/* OpenDBRead * VOpenDBRead * open a database for read * * "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 KDBManagerVOpenDBReadInt ( const KDBManager *self, const KDatabase **dbp, const KDirectory *wd, const char *path, va_list args ) { /* generate absolute path to db */ char dbpath [ 4096 ]; rc_t rc = KDirectoryVResolvePath ( wd, true, dbpath, sizeof dbpath, path, args ); if ( rc == 0 ) { KDatabase *db; const KDirectory *dir; /* open the directory if its a database */ rc = KDBOpenPathTypeRead ( wd, dbpath, &dir, kptDatabase, NULL ); if ( rc == 0 ) { /* allocate a new guy */ rc = KDatabaseMake ( & db, dir, dbpath ); if ( rc == 0 ) { db -> mgr = KDBManagerAttach ( self ); * dbp = db; return 0; } KDirectoryRelease ( dir ); } } return rc; }
/* OpenColumnRead * VOpenColumnRead * open a column for read * * "col" [ OUT ] - return parameter for newly opened column * * "path" [ IN ] - NUL terminated string in UTF-8 giving path to col * where "." acts as a structure name separator, i.e. struct.member */ static rc_t KDBManagerVOpenColumnReadInt ( const KDBManager *self, const KColumn **colp, const KDirectory *wd, bool try_srapath, const char *path, va_list args ) { char colpath [ 4096 ]; rc_t rc; size_t z; /* rc = KDirectoryVResolvePath ( wd, 1, colpath, sizeof colpath, path, args ); */ rc = string_vprintf( colpath, sizeof colpath, &z, path, args ); if ( rc == 0 ) { KColumn *col; const KDirectory *dir; /* open table directory */ rc = KDBOpenPathTypeRead ( self, wd, colpath, &dir, kptColumn, NULL, try_srapath ); if ( rc == 0 ) { rc = KColumnMakeRead ( & col, dir, colpath ); if ( rc == 0 ) { col -> mgr = KDBManagerAttach ( self ); * colp = col; return 0; } KDirectoryRelease ( dir ); } } return rc; }
/* OpenTableRead * VOpenTableRead * open a table for read * * "tbl" [ OUT ] - return parameter for newly opened table * * "path" [ IN ] - NUL terminated string in * wd-native character set giving path to table */ static rc_t KDBManagerVOpenTableReadInt ( const KDBManager *self, const KTable **tblp, const KDirectory *wd, bool try_srapath, const char *path, va_list args ) { rc_t rc; char tblpath [ 4096 ]; int z = ( args == NULL ) ? snprintf ( tblpath, sizeof tblpath, "%s", path ): vsnprintf ( tblpath, sizeof tblpath, path, args ); if ( z < 0 || ( size_t ) z >= sizeof tblpath ) rc = RC ( rcDB, rcMgr, rcOpening, rcPath, rcExcessive ); else { KTable *tbl; const KDirectory *dir; bool prerelease = false; rc = KDBOpenPathTypeRead ( self, wd, tblpath, &dir, kptTable, NULL, try_srapath ); if ( rc != 0 ) { prerelease = true; rc = KDBOpenPathTypeRead ( self, wd, tblpath, &dir, kptPrereleaseTbl, NULL, try_srapath ); } if ( rc == 0 ) { rc = KTableMake ( & tbl, dir, tblpath ); if ( rc == 0 ) { tbl -> mgr = KDBManagerAttach ( self ); tbl -> prerelease = prerelease; * tblp = tbl; return 0; } KDirectoryRelease ( dir ); } } 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; }
/* OpenDBRead * VOpenDBRead * open a database for read * * "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 KDBManagerVOpenDBReadInt ( const KDBManager *cself, const KDatabase **dbp, KDirectory *wd, const char *path, va_list args, bool *cached, bool try_srapath ) { rc_t rc; char dbpath [4096]; size_t z; rc = string_vprintf (dbpath, sizeof dbpath, &z, path, args); if ( rc == 0 ) { KSymbol *sym; /* if already open */ sym = KDBManagerOpenObjectFind (cself, dbpath); if (sym != NULL) { const KDatabase *cdb; rc_t obj; if ( cached != NULL ) * cached = true; switch (sym->type) { case kptDatabase: cdb = (KDatabase*)sym->u.obj; /* if open for update, refuse */ if ( cdb -> read_only ) { /* attach a new reference and we're gone */ rc = KDatabaseAddRef ( cdb ); if ( rc == 0 ) * dbp = cdb; return rc; } obj = rcDatabase; break; default: obj = rcPath; break; case kptTable: obj = rcTable; break; case kptColumn: obj = rcColumn; break; case kptIndex: obj = rcIndex; break; case kptMetadata: obj = rcMetadata; break; } rc = RC (rcDB, rcMgr, rcOpening, obj, rcBusy); } else { const KDirectory *dir; if ( cached != NULL ) * cached = false; /* open the directory if its a database */ rc = KDBOpenPathTypeRead ( cself, wd, dbpath, &dir, kptDatabase, NULL, try_srapath ); if ( rc == 0 ) { KDatabase *db; rc = KDatabaseMake ( &db, dir, dbpath, NULL, true ); if ( rc == 0 ) { KDBManager *self = ( KDBManager* ) cself; rc = KDBManagerInsertDatabase ( self, db ); if ( rc == 0 ) { * dbp = db; return 0; } free (db); } KDirectoryRelease (dir); } } } 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; }
static bool CC KDatabaseListFilter ( const KDirectory *dir, const char *name, void *data_ ) { struct FilterData * data = data_; return ( KDBOpenPathTypeRead ( data->mgr, dir, name, NULL, data->type, NULL, false ) == 0 ); }
/* List * create database listings */ static bool KDatabaseListFilter ( const KDirectory *dir, const char *name, void *data ) { return ( KDBOpenPathTypeRead ( dir, name, NULL, (( long int ) data ), NULL ) == 0 ); }