77a1a4c6ee6c882e187f1fc80b531c0e61f957cd chmalee Tue Nov 19 15:23:59 2024 -0800 Be more intelligent about producing default hub names, don't die when a hub exists already and we are adding another file to it diff --git src/hg/lib/userdata.c src/hg/lib/userdata.c index 5c68fc5..fdb9445 100644 --- src/hg/lib/userdata.c +++ src/hg/lib/userdata.c @@ -93,77 +93,94 @@ void addHubSpaceRowForFile(struct hubSpace *row) /* We created a file for a user, now add an entry to the hubSpace table for it */ { struct sqlConnection *conn = hConnectCentral(); // now write out row to hubSpace table if (!sqlTableExistsOnMain(conn, "hubSpace")) { errAbort("No hubSpace MySQL table is present. Please send an email to genome-www@soe.ucsc.edu describing the exact steps you took just before you got this error"); } hubSpaceSaveToDb(conn, row, "hubSpace", 0); hDisconnectCentral(&conn); } +static boolean checkHubSpaceRowExists(struct hubSpace *row) +/* Return TRUE if row already exists */ +{ +struct sqlConnection *conn = hConnectCentral(); +struct dyString *queryCheck = sqlDyStringCreate("select count(*) from hubSpace where userName='%s' and fileName='%s' and parentDir='%s'", row->userName, row->fileName, row->parentDir); +int ret = sqlQuickNum(conn, dyStringCannibalize(&queryCheck)); +hDisconnectCentral(&conn); +return ret > 0; +} + static void makeParentDirRows(char *userName, time_t lastModified, char *db, char *parentDirStr) /* For each '/' separated component of parentDirStr, create a row in hubSpace. Return the * final subdirectory component of parentDirStr */ { int i, slashCount = countChars(parentDirStr, '/'); char *components[256]; struct dyString *currLocation = dyStringNew(0); int foundSlashes = chopByChar(cloneString(parentDirStr), '/', components, slashCount); if (foundSlashes > 256) errAbort("parentDir setting '%s' too long", parentDirStr); for (i = 0; i < foundSlashes; i++) { char *subdir = components[i]; if (sameString(subdir, ".")) continue; fprintf(stderr, "making row for parent dir: '%s'\n", subdir); if (!subdir) errAbort("error: empty subdirectory components for parentDir string '%s'", parentDirStr); struct hubSpace *row = NULL; AllocVar(row); row->userName = userName; row->fileName = subdir; row->fileSize = 0; row->fileType = subdir; row->creationTime = NULL; row->lastModified = sqlUnixTimeToDate(&lastModified, TRUE); row->db = db; row->location = cloneString(dyStringContents(currLocation)); row->md5sum = ""; row->parentDir = i > 0 ? components[i-1] : ""; + // only insert a row for this parentDir if it's unique to the table + if (!checkHubSpaceRowExists(row)) addHubSpaceRowForFile(row); dyStringAppendC(currLocation, '/'); dyStringAppend(currLocation, components[i]); } } char *writeHubText(char *path, char *userName, char *hubName, char *db) /* Create a hub.txt file, optionally creating the directory holding it. For convenience, return * the file name of the created hub, which can be freed. */ { int oldUmask = 00; oldUmask = umask(0); makeDirsOnPath(path); // restore umask umask(oldUmask); // now make the hub.txt with some basic information -char *hubFile = catTwoStrings(path, "/hub.txt"); +char *hubFile = NULL; +struct dyString *hubFileDy = dyStringCreate("%s%shub.txt", path, endsWith(path, "/") ? "" : "/"); +hubFile = dyStringCannibalize(&hubFileDy); +if (fileExists(hubFile)) + return hubFile; + FILE *f = mustOpen(hubFile, "w"); //fprintf(stderr, "would write \"hub %s\nemail %s\nshortLabel %s\nlongLabel %s\nuseOneFile on\n\ngenome %s\n\n\" to %s", hubName, emailForUserName(userName), hubName, hubName, db, hubFile); fprintf(f, "hub %s\n" "email %s\n" "shortLabel %s\n" "longLabel %s\n" "useOneFile on\n" "\n" "genome %s\n" "\n", hubName, emailForUserName(userName), hubName, hubName, db); carefulClose(&f); return hubFile; } @@ -212,30 +229,31 @@ row->fileSize = fileSize(hubFileName); row->fileType = "hub"; row->creationTime = NULL; time_t lastModTime = fileModTime(hubFileName); row->lastModified = sqlUnixTimeToDate(&lastModTime, TRUE); row->db = db; row->location = path; row->md5sum = md5HexForFile(hubFileName); fprintf(stderr, "making parent dir rows\n"); fflush(stderr); makeParentDirRows(userName, lastModTime, db, parentDir); row->parentDir = hubName; struct dyString *parentsPath = dyStringCreate("%s%s", getDataDir(userName), parentDir); fprintf(stderr, "parentDir of hub.txt: '%s'\n", parentsPath->string); fflush(stderr); +if (!checkHubSpaceRowExists(row)) addHubSpaceRowForFile(row); } static void deleteHubSpaceRow(char *fname) /* Deletes a row from the hubspace table for a given fname */ { struct sqlConnection *conn = hConnectCentral(); struct dyString *deleteQuery = sqlDyStringCreate("delete from hubSpace where location='%s'", fname); sqlUpdate(conn, dyStringCannibalize(&deleteQuery)); } void removeFileForUser(char *fname, char *userName) /* Remove a file for this user if it exists */ { // The file to remove must be prefixed by the hg.conf userDataDir @@ -321,33 +339,66 @@ struct userFiles *hubFileList = listFilesForUserHub(userName, hub->hubName); hub->lastModified = getFileListLatestTime(hubFileList); hub->fileList = hubFileList; slAddHead(&userHubs, hub); } } return userHubs; } struct hubSpace *listFilesForUser(char *userName) /* Return the files the user has uploaded */ { struct sqlConnection *conn = hConnectCentral(); struct dyString *query = sqlDyStringCreate("select userName, fileName, fileSize, fileType, creationTime, DATE_FORMAT(lastModified, '%%c/%%d/%%Y, %%l:%%i:%%s %%p') as lastModified, db, location, md5sum, parentDir from hubSpace where userName='%s' order by creationTime, fileName", userName); struct hubSpace *fileList = hubSpaceLoadByQuery(conn, dyStringCannibalize(&query)); +hDisconnectCentral(&conn); return fileList; } +#define defaultHubName "defaultHub" +char *defaultHubNameForUser(char *userName) +/* Return a name to use as a default for a hub, starts with defaultHub, then defaultHub2, ... */ +{ +if (!userName) + return defaultHubName; +struct dyString *query = sqlDyStringCreate("select distinct(fileName) from hubSpace where parentDir='' and fileName like '%s%%' and userName='%s'", defaultHubName, userName); +struct sqlConnection *conn = hConnectCentral(); +struct slName *hubNames = sqlQuickList(conn, dyStringCannibalize(&query));; +hDisconnectCentral(&conn); +if (hubNames == NULL) + // user has no hubs created + return defaultHubName; +slSort(&hubNames,slNameCmpStringsWithEmbeddedNumbers); +slReverse(&hubNames); +// now the first element of the list has the most recent integer to use (or no integer) +char *currHubName = cloneString(hubNames->name); +int currHubStrLen = strlen(currHubName); +int defaultLen = strlen(defaultHubName); +if (currHubStrLen == defaultLen) + // probably a common case + return "defaultHub2"; +else + { + currHubName[defaultLen-1] = 0; + currHubName += strlen(defaultHubName); + int hubNum = sqlUnsigned(currHubName) + 1; + struct dyString *hubName = dyStringCreate("%s%d", defaultHubName, hubNum); + return dyStringCannibalize(&hubName); + } +} + long long getMaxUserQuota(char *userName) /* Return how much space is allocated for this user or the default */ { return HUB_SPACE_DEFAULT_QUOTA; } long long checkUserQuota(char *userName) /* Return the amount of space a user is currently using */ { long long quota = 0; struct hubSpace *hubSpace, *hubSpaceList = listFilesForUser(userName); for (hubSpace = hubSpaceList; hubSpace != NULL; hubSpace = hubSpace->next) { quota += hubSpace->fileSize; }