LIB_EXPORT rc_t CC KDatabaseVWritable ( const KDatabase *self, uint32_t type, const char *name, va_list args ) { rc_t rc; char path [ 256 ]; rc = KDatabaseLockInt (self, path, sizeof path, type, name, args); if (rc == 0) rc = KDBWritable (self->dir, path); return rc; }
/* Locked * returns non-zero if locked */ LIB_EXPORT bool CC KDatabaseLocked ( const KDatabase *self ) { rc_t rc; if ( self == NULL ) return false; rc = KDBWritable ( self -> dir, "." ); return GetRCState ( rc ) == rcLocked; }
/* Locked * returns non-zero if locked */ LIB_EXPORT bool CC KColumnLocked ( const KColumn *self ) { rc_t rc; if ( self == NULL ) return false; rc = KDBWritable ( self -> dir, "" ); return GetRCState ( rc ) == rcLocked; }
/* Writable * returns 0 if object is writable * or a reason why if not * * "path" [ IN ] - NUL terminated path * * TBD: Better reasons for non local paths */ static rc_t KDBManagerWritableInt ( const KDirectory * dir, const char * path ) { rc_t rc; int type = KDBPathType ( /*NULL,*/ dir, NULL, path ) & ~ kptAlias; switch ( type ) { case kptDatabase: case kptTable: case kptPrereleaseTbl: case kptColumn: rc = KDBWritable ( dir, path ); break; case kptIndex: case kptMetadata: /* a wrong database type */ rc = RC ( rcDB, rcMgr, rcAccessing, rcPath, rcIncorrect ); break; #if 0 /*TBD - eventually we need to check for an archive here */ case kptFile: /* check if this is an archive .tar or .sra and return rcReadonly if it is */ #endif case kptNotFound: rc = RC ( rcDB, rcMgr, rcAccessing, rcPath, rcNotFound ); break; case kptBadPath: rc = RC ( rcDB, rcMgr, rcAccessing, rcPath, rcInvalid ); break; default: rc = RC ( rcDB, rcMgr, rcAccessing, rcPath, rcIncorrect ); } return rc; }
/* OpenDBUpdate * VOpenDBUpdate * open a database for read/write * * "db" [ OUT ] - return parameter for newly opened database * * "path" [ IN ] - NUL terminated string in * wd-native character set giving path to database */ static rc_t KDBManagerVOpenDBUpdateInt ( KDBManager *self, KDatabase **db, KDirectory *wd, const char *path, va_list args ) { char dbpath [ 4096 ]; rc_t rc = KDirectoryVResolvePath ( wd, true, dbpath, sizeof dbpath, path, args ); if ( rc == 0 ) { KSymbol * sym; KFile *f; KMD5SumFmt * md5 = NULL; /* if already open, refuse */ sym = KDBManagerOpenObjectFind (self, dbpath); if (sym != NULL) { rc_t obj; switch (sym->type) { default: obj = rcPath; break; case kptDatabase: obj = rcDatabase; break; case kptTable: obj = rcTable; break; case kptColumn: obj = rcColumn; break; case kptIndex: obj = rcIndex; break; case kptMetadata: obj = rcMetadata; break; } return RC ( rcDB, rcMgr, rcOpening, obj, rcBusy ); } /* only open existing dbs */ switch (KDBPathType ( /*self,*/ wd, NULL, dbpath ) ) { case kptNotFound: return RC ( rcDB, rcMgr, rcOpening, rcDatabase, rcNotFound ); case kptBadPath: return RC ( rcDB, rcMgr, rcOpening, rcPath, rcInvalid ); case kptFile: case kptFile | kptAlias: /* if we find a file, vary the failure if it is an archive that is a database * or a non related file */ if ( KDBOpenPathTypeRead ( self, wd, dbpath, NULL, kptDatabase, NULL, false ) == 0 ) return RC ( rcDB, rcMgr, rcOpening, rcDirectory, rcUnauthorized ); /* fall through */ default: return RC ( rcDB, rcMgr, rcOpening, rcPath, rcIncorrect ); case kptDatabase: case kptDatabase | kptAlias: break; } /* test now for locked directory */ rc = KDBWritable (wd, dbpath); switch (GetRCState (rc)) { default: #if 0 return RC ( rcDB, rcMgr, rcOpening, rcDatabase, rcNoPerm ); /* TBD: better state? */ #endif case rcLocked: return RC ( rcDB, rcMgr, rcOpening, rcDatabase, rcLocked ); case rcReadonly: return RC ( rcDB, rcMgr, rcOpening, rcDatabase, rcReadonly ); case 0: rc = 0; break; } rc = KDirectoryOpenFileWrite ( wd, &f, true, "%s/md5", dbpath ); if ( rc == 0 ) { rc = KMD5SumFmtMakeUpdate ( & md5, f ); if ( rc != 0 ) KFileRelease ( f ); } else if ( GetRCState ( rc ) == rcNotFound ) rc = 0; if ( rc == 0 ) rc = KDBManagerMakeDBUpdate ( self, db, wd, dbpath, md5 ); KMD5SumFmtRelease ( md5 ); } return rc; }
/* CreateDB * VCreateDB * create a new or open an existing database * * "db" [ OUT ] - return parameter for newly opened database * * "cmode" [ IN ] - creation mode * * "path" [ IN ] - NUL terminated string in * wd-native character set giving path to database */ static rc_t KDBManagerVCreateDBInt ( KDBManager *self, KDatabase **db, KDirectory *wd, KCreateMode cmode, const char *path, va_list args ) { char dbpath [ 4096 ]; rc_t rc = KDirectoryVResolvePath ( wd, true, dbpath, sizeof dbpath, path, args ); if ( rc == 0 ) { /* we won't try accession resolution here */ int type = KDBPathType ( /*NULL,*/ wd, NULL, dbpath ); switch ( type ) { case kptNotFound: /* first good path */ break; case kptBadPath: return RC ( rcDB, rcMgr, rcCreating, rcPath, rcInvalid ); case kptDatabase: case kptDatabase | kptAlias: /* found so is not good if we want to create new and not * clear/init or open old */ if ((cmode & kcmValueMask) == kcmCreate) return RC ( rcDB, rcMgr, rcCreating, rcDatabase, rcExists ); if (KDBManagerOpenObjectBusy (self, dbpath)) return RC ( rcDB, rcMgr, rcCreating, rcDatabase, rcBusy ); /* test now for locked directory */ rc = KDBWritable ( wd, dbpath ); if (rc) { switch (GetRCState(rc)) { default: return rc; case rcLocked: return RC ( rcDB, rcMgr, rcCreating, rcDatabase, rcLocked ); case rcReadonly: return RC ( rcDB, rcMgr, rcCreating, rcDatabase, rcReadonly ); case rcNotFound: /* not found is good but probably unreachable */ break; case 0: rc = 0; break; } } /* second good path */ break; case kptTable: case kptTable | kptAlias: return RC (rcDB, rcMgr, rcCreating, rcTable, rcExists); case kptColumn: case kptColumn | kptAlias: return RC (rcDB, rcMgr, rcCreating, rcColumn, rcExists); case kptIndex: case kptIndex | kptAlias: return RC (rcDB, rcMgr, rcCreating, rcIndex, rcExists); case kptMetadata: case kptMetadata | kptAlias: return RC (rcDB, rcMgr, rcCreating, rcMetadata, rcExists); case kptFile: case kptFile | kptAlias: /* if we find a file, vary the failure if it is an archive that is a database * or a non related file */ if ( KDBOpenPathTypeRead ( self, wd, dbpath, NULL, kptDatabase, NULL, false ) == 0 ) return RC ( rcDB, rcMgr, rcCreating, rcDirectory, rcUnauthorized ); /* fall through */ default: return RC ( rcDB, rcMgr, rcCreating, rcPath, rcIncorrect ); } /* [re]create directory */ rc = KDirectoryCreateDir ( wd, 0775, cmode, "%s", dbpath ); if (rc == 0) /* create tbl subdirectory as required for db */ rc = KDirectoryCreateDir ( wd, 0775, kcmOpen, "%s/tbl", dbpath ); if ( rc == 0 ) { KMD5SumFmt *md5 = NULL; if ( ( cmode & kcmMD5 ) != 0 ) { KFile * f; /* if needed create the md5 digest file */ rc = KDirectoryCreateFile ( wd, &f, true, 0664, kcmOpen, "%s/md5", dbpath ); if ( rc == 0 ) { /* create a formatter around file formatter will own "f" afterward */ rc = KMD5SumFmtMakeUpdate ( & md5, f ); /* if failed to create formatter, release "f" */ if ( rc != 0 ) KFileRelease ( f ); } } if ( rc == 0 ) rc = KDBManagerMakeDBUpdate ( self, db, wd, dbpath, md5 ); KMD5SumFmtRelease ( md5 ); } } return rc; }
bool KDBIsLocked ( const KDirectory *dir, const char *path ) { return ( KDBWritable (dir, path) != 0 ); }