DBM_Database.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021    Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 
00025 //#define FRONT_END
00026 #include "DBM_Database.h"
00027 #include "db_p.h"
00028 #include "eyedbsm/transaction.h"
00029 #define LOCKID
00030 
00031 namespace eyedb {
00032 
00033 const char DBM_Database::defaultDBMDB[] = "default";
00034 
00035 LinkedList *DBM_Database::dbmdb_list;
00036 
00037 static const char dbentry_s[]       = "database_entry";
00038 static const char user_s[]          = "user_entry";
00039 static const char dbuseraccess_s[]  = "database_user_access";
00040 static const char sysuseraccess_s[] = "system_user_access";
00041 
00042 /* static members */
00043 void DBM_Database::init()
00044 {
00045   dbmdb_list = new LinkedList();
00046   DBM::init();
00047 }
00048 
00049 Status
00050 DBM_Database::updateSchema(Database *db)
00051 {
00052   //  return dbmSchemaUpdate(db);
00053   return DBM::updateSchema(db);
00054 }
00055 
00056 const char *DBM_Database::getDbName()
00057 {
00058   return "EYEDBDBM";
00059 }
00060 
00061 int DBM_Database::getDbid()
00062 {
00063   return 1;
00064 }
00065 
00066 DBM_Database *
00067 DBM_Database::setDBM_Database(const char *dbmfile, Database *db)
00068 {
00069   DBM_Database *dbm;
00070 
00071   if (dbm = getDBM_Database(dbmfile))
00072     dbmdb_list->deleteObject(dbm);
00073 
00074   if (!db)
00075     return 0;
00076 
00077   dbm = new DBM_Database(dbmfile, db);
00078   dbmdb_list->insertObject(dbm);
00079 
00080   return dbm;
00081 }
00082 
00083 void DBM_Database::_dble_underscore_release()
00084 {
00085   _release();
00086   //  dbmRelease();
00087   DBM::release();
00088 }
00089 
00090 void DBM_Database::_release()
00091 {
00092   if (!dbmdb_list)
00093     return;
00094 
00095   LinkedListCursor *c = dbmdb_list->startScan();
00096 
00097   DBM_Database *dbm;
00098 
00099   while (dbmdb_list->getNextObject(c, (void *&)dbm))
00100     {
00101       dbm->close();
00102       dbm->release();
00103     }
00104 
00105   dbmdb_list->endScan(c);
00106 
00107   dbmdb_list->empty();
00108 
00109   delete dbmdb_list;
00110   dbmdb_list = NULL;
00111 }
00112 
00113 DBM_Database *DBM_Database::getDBM_Database(const char *dbmfile)
00114 {
00115   LinkedListCursor *c = dbmdb_list->startScan();
00116 
00117   DBM_Database *dbm;
00118 
00119   while (dbmdb_list->getNextObject(c, (void *&)dbm))
00120     {
00121       if (!strcmp(dbm->dbmdb_str, dbmfile))
00122         {
00123           dbmdb_list->endScan(c);
00124           return dbm;
00125         }
00126     }
00127 
00128   dbmdb_list->endScan(c);
00129   return 0;
00130 }
00131 
00132 /* non static members */
00133 DBM_Database::DBM_Database(const char *dbmfile) :
00134 Database(DBM_Database::getDbName(), dbmfile)
00135 {
00136 }
00137 
00138 DBM_Database::DBM_Database(const char *dbmfile, Database *_dbmdb)
00139 : Database(*_dbmdb)
00140 {
00141   --open_refcnt;
00142 }
00143 
00144 Status
00145 DBM_Database::getDbFile(const char **dbname, int *_dbid, const char *&dbfile)
00146 {
00147   OQL *q;
00148   Status s;
00149 
00150   dbfile = 0;
00151   s = transactionBegin();
00152   if (s) return s;
00153 
00154   // TO IMPROVE this query, should use index directly!
00155   //eyedblib::display_time("DBM_Database::getDbFile #1");
00156   if ((*dbname)[0])
00157     q = new OQL(this, "select %s.dbname = \"%s\"", dbentry_s, *dbname);
00158   else
00159     q = new OQL(this, "select %s.dbid = %d", dbentry_s, *_dbid);
00160 
00161   ObjectArray obj_arr;
00162   // the #1 query takes about 400ms because of initialisation which
00163   // must complete part of the schema and because of other 
00164   // Schema::manageClassDeferred calls!
00165   s = q->execute(obj_arr);
00166   //eyedblib::display_time("DBM_Database::getDbFile #2");
00167   if (s)
00168     {
00169       transactionCommit();
00170       delete q;
00171       return s;
00172     }
00173 
00174   if (obj_arr.getCount())
00175     {
00176       DBEntry *dbmentry = (DBEntry *)obj_arr[0];
00177       
00178       if (!(*dbname)[0])
00179         *dbname = strdup(dbmentry->dbname().c_str());
00180       else if (_dbid)
00181         *_dbid = dbmentry->dbid();
00182 
00183       dbfile = strdup(dbmentry->dbfile().c_str());
00184     }
00185 
00186   delete q;
00187   return transactionCommit();
00188 }
00189 
00190 Status
00191 DBM_Database::getDatabases(LinkedList *list)
00192 {
00193   Status s;
00194 
00195   s = transactionBegin();
00196   if (s) return s;
00197   OQL q(this, (std::string("select ") + dbentry_s).c_str());
00198 
00199   ObjectArray obj_arr;
00200   s = q.execute(obj_arr);
00201 
00202   if (s)
00203     {
00204       transactionAbort();
00205       return s;
00206     }
00207 
00208   for (int i = 0; i < obj_arr.getCount(); i++)
00209     {
00210       DBEntry *dbmentry = (DBEntry *)obj_arr[i];
00211       Database *_db = new Database(dbmentry->dbname().c_str(),
00212                                    dbmentry->dbid());
00213       list->insertObjectLast(_db);
00214     }
00215 
00216   return transactionCommit();
00217 }
00218 
00219 Status
00220 DBM_Database::createEntry(int _dbid, const char *_dbname, const char *_dbfile)
00221 {
00222   Status s;
00223   s = transactionBegin();
00224   DBEntry *entry = new DBEntry(this);
00225 
00226   entry->dbid(_dbid);
00227   entry->dbname(_dbname);
00228   entry->dbfile(_dbfile);
00229   entry->default_access(NoDBAccessMode);
00230 
00231   if (s) return s;
00232   s = entry->realize();
00233   transactionCommit();
00234 
00235   entry->release();
00236   return s;
00237 }
00238 
00239 Status
00240 DBM_Database::updateEntry(int _dbid, const char *_dbname, 
00241                             const char *_newdbname, const char *_dbfile)
00242 {
00243   Status s;
00244   DBEntry *entry;
00245 
00246   s = getDBEntry(_dbname, entry);
00247   if (s) return s;
00248 
00249   if (!entry)
00250     return Exception::make(IDB_DATABASE_RENAME_ERROR,
00251                          "database entry '%s' does not exist", _dbname);
00252 
00253   transactionBegin();
00254   entry->dbname(_newdbname);
00255   entry->dbfile(_dbfile);
00256   s = entry->realize();
00257   transactionCommit();
00258 
00259   entry->release();
00260   return s;
00261 }
00262 
00263 Status DBM_Database::getNewDbid(int &newid)
00264 {
00265   return getNewID(dbentry_s, "dbid", 2, newid, True);
00266 }
00267 
00268 Status DBM_Database::getNewUid(int &newid)
00269 {
00270   return getNewID(user_s, "uid", 1, newid, False);
00271 }
00272 
00273 static int
00274 cmp(const void *xi1, const void *xi2)
00275 {
00276   return *(const int *)xi1 - *(const int *)xi2;
00277 }
00278 
00279 static const char keyid[] = "eyedb::id";
00280 
00281 std::string
00282 DBM_Database::makeTempName(int dbid)
00283 {
00284   return std::string("--eyedb--temporary--#") + str_convert(dbid);
00285 }
00286 
00287 Status
00288 DBM_Database::lockId(Oid &objoid)
00289 {
00290   Status s;
00291   eyedbsm::Status se;
00292   if (!isInTransaction())
00293     return Exception::make(IDB_ERROR, "transaction expected in lockId");
00294 
00295   eyedbsm::DbHandle *se_dbh = get_eyedbsm_DbHandle((DbHandle *)dbh->u.dbh);
00296 
00297   Bool setRootEntry;
00298   if (!eyedbsm::rootEntryGet(se_dbh, keyid, objoid.getOid(), sizeof(eyedbsm::Oid)))
00299     {
00300       Class *xcls = 0;
00301       // check oid
00302       if (s = getObjectClass(objoid, xcls))
00303         setRootEntry = True;
00304       else
00305         setRootEntry = False;
00306     }
00307   else
00308     setRootEntry = True;
00309 
00310   if (setRootEntry)
00311     {
00312       Object *lockobj = sch->getClass("char")->newObj(this);
00313       s = lockobj->store();
00314       if (s) return s;
00315       objoid = lockobj->getOid();
00316       se = eyedbsm::rootEntrySet(se_dbh, keyid, objoid.getOid(), sizeof(eyedbsm::Oid),
00317                                  eyedbsm::False);
00318       lockobj->release();
00319       if (se)
00320         return Exception::make(IDB_ERROR, eyedbsm::statusGet(se));
00321     }
00322 
00323   /* warning; was se_OWRITE|se_LOCKX */
00324   se = eyedbsm::objectLock(se_dbh, objoid.getOid(), eyedbsm::LockX, 0);
00325   if (se)
00326     return Exception::make(IDB_ERROR, eyedbsm::statusGet(se));
00327 
00328   return Success;
00329 }
00330 
00331 Status
00332 DBM_Database::unlockId(const Oid &objoid)
00333 {
00334   eyedbsm::DbHandle *se_dbh = get_eyedbsm_DbHandle((DbHandle *)dbh->u.dbh);
00335   eyedbsm::Status se = eyedbsm::objectDownLock(se_dbh, objoid.getOid());
00336   if (se)
00337     return Exception::make(IDB_ERROR, eyedbsm::statusGet(se));
00338   return Success;
00339 }
00340 
00341 Status
00342 DBM_Database::getNewID(const char *classname, const char *attrname,
00343                          int start_val, int &_dbid, Bool create_entry)
00344 {
00345   Status s;
00346   _dbid = -1;
00347 
00348   s = transactionBegin();
00349   if (s) return s;
00350   Oid lockoid;
00351   s = lockId(lockoid);
00352   if (s) return s;
00353 
00354   OQL q(this, "select %s.%s", classname, attrname);
00355   int maxdbid = 0;
00356 
00357   ValueArray val_arr;
00358   s = q.execute(val_arr);
00359   if (s)
00360     {
00361       transactionAbort();
00362       //unlockId(lockoid);
00363       return s;
00364     }
00365 
00366   int cnt = val_arr.getCount();
00367   if (cnt > 0)
00368     {
00369       int *values = new int[cnt];
00370       for (int i = 0; i < cnt; i++)
00371         values[i] = val_arr[i].l;
00372 
00373       qsort(values, cnt, sizeof(int), cmp);
00374       
00375       for (int j = 0; j < cnt; j++)
00376         if (j > 0 && values[j] - values[j-1] > 1)
00377           {
00378             _dbid = values[j-1]+1;
00379             break;
00380           }
00381       
00382       if (_dbid < 0)
00383         _dbid = values[cnt-1] + 1;
00384       
00385       delete [] values;
00386     }
00387   else
00388     _dbid = start_val;
00389 
00390   if (create_entry)
00391     s = createEntry(_dbid, makeTempName(_dbid).c_str(), "");
00392 
00393   if (s)
00394     transactionAbort();
00395   else
00396     transactionCommit();
00397   //unlockId(lockoid);
00398   return s;
00399 }
00400 
00401 Status
00402 DBM_Database::removeEntry(const char *dbname)
00403 {
00404   Status s;
00405   s = transactionBegin();
00406   if (s) return s;
00407 
00408   OQL q(this,
00409            "for (y in (select %s->dbentry->dbname = \"%s\")) delete y",
00410            dbuseraccess_s, dbname);
00411 
00412   s = q.execute();
00413   if (s)
00414     {
00415       transactionAbort();
00416       return s;
00417     }
00418 
00419   OQL q1(this, "select %s.dbname = \"%s\"", dbentry_s, dbname);
00420 
00421   OidArray oid_arr;
00422   s = q1.execute(oid_arr);
00423   if (s)
00424     {
00425       transactionAbort();
00426       return s;
00427     }
00428 
00429   if (oid_arr.getCount())
00430     s = removeObject(oid_arr[0]);
00431   else
00432     s = Exception::make(IDB_DBM_ERROR,
00433                            "fatal error: entry '%s' not found", dbname);
00434 
00435   transactionCommit();
00436   return s;
00437 }
00438 
00439 Status
00440 DBM_Database::getUser(const char *username, UserEntry *&user)
00441 {
00442   Status s;
00443   user = 0;;
00444 
00445   s = transactionBegin();
00446   if (s) return s;
00447 
00448   OQL q(this, "select %s->name = \"%s\"", user_s, username);
00449 
00450   ObjectArray obj_arr;
00451   s = q.execute(obj_arr);
00452   if (s)
00453     {
00454       transactionAbort();
00455       return s;
00456     }
00457 
00458   if (obj_arr.getCount())
00459     user = (UserEntry *)obj_arr[0];
00460     
00461   return transactionCommit();
00462 }
00463 
00464 Status
00465 DBM_Database::setSchema(const char *dbname, const Oid &sch_oid)
00466 {
00467   DBEntry *dbentry;
00468   Status s;
00469   s = getDBEntry(dbname, dbentry);
00470   if (s) return s;
00471 
00472   if (dbentry)
00473     {
00474       transactionBegin();
00475 
00476       /* cannot use : dbentry->sch_oid(sch_oid), because this method
00477          call item->setOid(dbentry, &sch_oid, 1, 0, True), which means
00478          a check of the type of sch_oid, so a database opening.
00479          But as we are creating this database, it is not yet ready, so : */
00480 
00481       const Attribute *item =
00482         dbentry->getClass()->getAttribute("sch");
00483       if (item)
00484         {
00485           s = item->setOid(dbentry, &sch_oid, 1, 0, False);
00486           if (!s)
00487             s = dbentry->realize();
00488         }
00489 
00490       transactionCommit();
00491       dbentry->release();
00492       return s;
00493     }
00494 
00495   return Exception::make(IDB_DATABASE_OPEN_ERROR,
00496                        "database entry '%s' not found", dbname);
00497 }
00498 
00499 Status
00500 DBM_Database::getDBEntries(const char *dbname, DBEntry **&dbentries,
00501                              int &cnt, const char *op)
00502 {
00503   Status s;
00504   dbentries = 0;;
00505   cnt = 0;
00506 
00507   s = transactionBegin();
00508   if (s) return s;
00509 
00510   OQL q(this, "select %s->dbname %s \"%s\"", dbentry_s, op, dbname);
00511 
00512   ObjectArray obj_arr;
00513   s = q.execute(obj_arr);
00514   if (s)
00515     {
00516       transactionAbort();
00517       return s;
00518     }
00519 
00520   cnt = obj_arr.getCount();
00521   if (!cnt)
00522     {
00523       dbentries = 0;
00524       return Success;
00525     }
00526 
00527   dbentries = new DBEntry *[cnt];
00528   for (int i = 0; i < cnt; i++)
00529     dbentries[i] = (DBEntry *)obj_arr[i];
00530     
00531   return transactionCommit();
00532 }
00533 
00534 Status
00535 DBM_Database::getDBEntry(const char *dbname, DBEntry *&dbentry)
00536 
00537 {
00538   Status s;
00539   dbentry = 0;;
00540 
00541   s = transactionBegin();
00542   if (s) return s;
00543 
00544   OQL q(this, "select %s->dbname = \"%s\"", dbentry_s, dbname);
00545 
00546   ObjectArray obj_arr;
00547   s = q.execute(obj_arr);
00548   if (s)
00549     {
00550       transactionAbort();
00551       return s;
00552     }
00553 
00554   if (obj_arr.getCount())
00555     dbentry = (DBEntry *)obj_arr[0];
00556     
00557   return transactionCommit();
00558 }
00559 
00560 Status
00561 DBM_Database::get_sys_user_access(const char *username,
00562                                     SysUserAccess **psysaccess,
00563                                     Bool justCheck,
00564                                     const char *msg)
00565 {
00566   UserEntry *user;
00567   Status s;
00568 
00569   s = getUser(username, user);
00570   if (s) return s;
00571 
00572   if (!user)
00573     return Exception::make(IDB_AUTHENTICATION_FAILED,
00574                          "user entry '%s' not found", username);
00575 
00576   user->release();
00577 
00578   s = transactionBegin();
00579   if (s) return s;
00580 
00581   OQL q(this, "select %s->user->name = \"%s\"", sysuseraccess_s, username);
00582 
00583   ObjectArray obj_arr;
00584   s = q.execute(obj_arr);
00585   if (s)
00586     {
00587       transactionCommit();
00588       return s;
00589     }
00590 
00591   if (!obj_arr.getCount())
00592     {
00593       *psysaccess = (SysUserAccess *)0;
00594       if (justCheck)
00595         s = Success;
00596       else
00597         s = Exception::make(IDB_INSUFFICIENT_PRIVILEGES,
00598                                "user entry '%s': %s", username, msg);
00599     }
00600   else
00601     {
00602       *psysaccess = (SysUserAccess *)obj_arr[0];
00603       s = Success;
00604     }
00605 
00606   transactionCommit();
00607   return s;
00608 }
00609 
00610 Status DBM_Database::get_db_user_access(const char *dbname,
00611                                              const char *username,
00612                                              UserEntry **puser,
00613                                              DBUserAccess **pdbaccess,
00614                                              DBAccessMode *defaccess)
00615 {
00616   Status s;
00617 
00618   s = getUser(username, *puser);
00619   if (s) return s;
00620 
00621   if (!*puser)
00622     return Exception::make(IDB_AUTHENTICATION_FAILED,
00623                               "user entry '%s' not found", username);
00624 
00625   DBEntry *dbentry;
00626   s = getDBEntry(dbname, dbentry);
00627   if (s)
00628     {
00629       (*puser)->release();
00630       return s;
00631     }
00632 
00633   if (!dbentry)
00634     {
00635       (*puser)->release();
00636       return Exception::make(IDB_DATABASE_OPEN_ERROR,
00637                                 "database entry '%s' not found", dbname);
00638     }
00639 
00640   s = transactionBegin();
00641   if (s)
00642     {
00643       (*puser)->release();
00644       dbentry->release();
00645       return s;
00646     }
00647     
00648   OQL q(this, "select x from %s x where x->user->name = \"%s\" && "
00649            "x->dbentry->dbname = \"%s\"",
00650            dbuseraccess_s, username, dbname);
00651 
00652   ObjectArray obj_arr;
00653   s = q.execute(obj_arr);
00654   if (s)
00655     {
00656       (*puser)->release();
00657       dbentry->release();
00658       transactionCommit();
00659       return s;
00660     }
00661 
00662   if (obj_arr.getCount())
00663     *pdbaccess = (DBUserAccess *)obj_arr[0];
00664   else
00665     *pdbaccess = (DBUserAccess *)0;
00666 
00667   *defaccess = dbentry->default_access();
00668 
00669   dbentry->release();
00670   return transactionCommit();
00671 }
00672 
00673 Status DBM_Database::add_user(const char *username, const char *passwd,
00674                                    UserType user_type)
00675 {
00676   UserEntry *user;
00677   Status s;
00678 
00679   s = getUser(username, user);
00680   if (s) return s;
00681 
00682   if (user)
00683     {
00684       user->release();
00685       return Exception::make(IDB_ADD_USER_ERROR,
00686                                 "user entry '%s' already exists", username);
00687     }
00688 
00689   user = new UserEntry(this);
00690   user->name(username);
00691   if (passwd)
00692     user->passwd(passwd);
00693 
00694   int newid;
00695   s = getNewUid(newid);
00696   if (s)
00697     {
00698       transactionCommit();
00699       user->release();
00700     }
00701 
00702   user->uid(newid);
00703   user->type(user_type);
00704 
00705   s = transactionBegin();
00706   if (!s)
00707     s = user->realize();
00708 
00709   transactionCommit();
00710   user->release();
00711 
00712   if (s)
00713     return Exception::make(IDB_ADD_USER_ERROR,
00714                               "user entry '%s' : %s", username, s->getDesc());
00715 
00716   return Success;
00717 }
00718 
00719 Status DBM_Database::delete_user(const char *username)
00720 {
00721   UserEntry *user;
00722   Status s;
00723 
00724   s = getUser(username, user);
00725   if (s) return s;
00726 
00727   if (!user)
00728     return Exception::make(IDB_DELETE_USER_ERROR,
00729                          "user entry '%s' does not exist", username);
00730 
00731   const Oid xoid = user->getOid();
00732 
00733   user->release();
00734 
00735   s = transactionBegin();
00736   if (s) return s;
00737 
00738   OQL q(this, "for (y in (select %s.user = %s)) delete y",
00739            dbuseraccess_s, xoid.getString());
00740 
00741   s = q.execute();
00742   if (s)
00743     {
00744       transactionAbort();
00745       return s;
00746     }
00747 
00748   s = removeObject(&xoid);
00749   transactionCommit();
00750 
00751   return s;
00752 }
00753 
00754 Status DBM_Database::user_passwd_set(const char *username,
00755                                           const char *passwd)
00756 {
00757   UserEntry *user;
00758   Status s;
00759 
00760   s = getUser(username, user);
00761   if (s) return s;
00762 
00763   if (!user)
00764     return Exception::make(IDB_SET_USER_PASSWD_ERROR,
00765                          "user entry '%s' not found", username);
00766 
00767   if (passwd)
00768     user->passwd(passwd);
00769 
00770   s = transactionBegin();
00771   if (!s)
00772     s = user->realize();
00773   transactionCommit();
00774 
00775   user->release();
00776 
00777   return s;
00778 }
00779 
00780 Status DBM_Database::user_db_access_set(const char *dbname,
00781                                              const char *username,
00782                                              DBAccessMode dbmode)
00783 {
00784   UserEntry *user;
00785   Status s;
00786 
00787   s = getUser(username, user);
00788   if (s) return s;
00789 
00790   if (!user)
00791     return Exception::make(IDB_SET_USER_DBACCESS_ERROR,
00792                          "user entry '%s' not found", username);
00793 
00794   DBEntry *dbentry;
00795 
00796   s = getDBEntry(dbname, dbentry);
00797   if (s)
00798     {
00799       user->release();
00800       return s;
00801     }
00802 
00803   if (!dbentry)
00804     return Exception::make(IDB_SET_USER_DBACCESS_ERROR,
00805                          "database entry '%s' not found", dbname);
00806 
00807 
00808   DBUserAccess *dbaccess;
00809   Status status;
00810 
00811   s = transactionBegin();
00812   if (s) return s;
00813   dbaccess = new DBUserAccess(this);
00814 
00815   dbaccess->user(user);
00816   dbaccess->dbentry(dbentry);
00817   dbaccess->mode(dbmode);
00818 
00819   OQL q(this,
00820            "for (y in (select x from %s x where x->user->name = \"%s\" "
00821            "&& x->dbentry->dbname = \"%s\")) delete y",
00822            dbuseraccess_s, username, dbname);
00823 
00824   s = q.execute();
00825   if (s)
00826     {
00827       transactionAbort();
00828       return s;
00829     }
00830 
00831   s = dbaccess->realize();
00832   transactionCommit();
00833 
00834   user->release();
00835   dbentry->release();
00836   dbaccess->release();
00837 
00838   if (s)
00839     return Exception::make(IDB_SET_USER_DBACCESS_ERROR,
00840                          "database entry '%s', user entry '%s' : %s",
00841                          dbname, username, s->getString());
00842 
00843   return Success;
00844 }
00845 
00846 Status DBM_Database::default_db_access_set(const char *dbname,
00847                                                 DBAccessMode dbmode)
00848 {
00849   DBEntry *dbentry;
00850   Status s;
00851 
00852   s = getDBEntry(dbname, dbentry);
00853   if (s) return s;
00854 
00855   if (!dbentry)
00856     return Exception::make(IDB_SET_DEFAULT_DBACCESS_ERROR,
00857                          "database entry '%s' not found", dbname);
00858 
00859   DBUserAccess *dbaccess;
00860 
00861   dbentry->default_access(dbmode);
00862 
00863   s = transactionBegin();
00864   if (s)
00865     {
00866       dbentry->release();
00867       return s;
00868     }
00869 
00870   s = dbentry->realize();
00871   transactionCommit();
00872 
00873   dbentry->release();
00874 
00875   if (s)
00876     return Exception::make(IDB_SET_DEFAULT_DBACCESS_ERROR,
00877                          "database entry '%s' : %s", dbname, s->getString());
00878 
00879   return Success;
00880 }
00881 
00882 Status DBM_Database::user_sys_access_set(const char *username,
00883                                               SysAccessMode sysmode)
00884 {
00885   UserEntry *user;
00886   Status s;
00887 
00888   s = getUser(username, user);
00889   if (s) return s;
00890 
00891   if (!user)
00892     return Exception::make(IDB_SET_USER_SYSACCESS_ERROR,
00893                          "user entry '%s' not found", username);
00894 
00895   SysUserAccess *sysaccess;
00896 
00897   sysaccess = new SysUserAccess(this);
00898 
00899   sysaccess->user(user);
00900   sysaccess->mode(sysmode);
00901 
00902   transactionBegin();
00903   OQL q(this, "for (y in (select %s->user->name = \"%s\")) delete y",
00904            sysuseraccess_s, username);
00905 
00906   s = q.execute();
00907   if (s)
00908     {
00909       transactionAbort();
00910       return s;
00911     }
00912   s = sysaccess->realize();
00913 
00914   transactionCommit();
00915 
00916   sysaccess->release();
00917   user->release();
00918 
00919   if (s)
00920     return Exception::make(IDB_SET_USER_SYSACCESS_ERROR,
00921                          "user entry '%s' : %s",
00922                          username, s->getString());
00923   return Success;
00924 }
00925 
00926 Status DBM_Database::addUser(Connection *ch,
00927                                   const char *username, const char *passwd,
00928                                   UserType user_type,
00929                                   const char *userauth, const char *passwdauth)
00930 {
00931   if (!dbmdb_str)
00932     return invalidDbmdb(IDB_ADD_USER_ERROR);
00933 
00934   conn = ch;
00935   check_auth(userauth, passwdauth, "adding user");
00936 
00937   RPCStatus rpc_status;
00938   rpc_status = userAdd(ConnectionPeer::getConnH(conn),
00939                            dbmdb_str, userauth, passwdauth,
00940                            username, passwd, user_type);
00941   return StatusMake(rpc_status);
00942 }
00943 
00944 Status DBM_Database::deleteUser(Connection *ch,
00945                                      const char *username,
00946                                      const char *userauth,
00947                                      const char *passwdauth)
00948 {
00949   if (!dbmdb_str)
00950     return invalidDbmdb(IDB_DELETE_USER_ERROR);
00951 
00952   conn = ch;
00953   check_auth(userauth, passwdauth, "deleting user");
00954 
00955   RPCStatus rpc_status;
00956   rpc_status = userDelete(ConnectionPeer::getConnH(conn),
00957                               dbmdb_str, userauth, passwdauth,
00958                               username);
00959   return StatusMake(rpc_status);
00960 }
00961 
00962 Status DBM_Database::setUserPasswd(Connection *ch,
00963                                         const char *username,
00964                                         const char *passwd,
00965                                         const char *userauth,
00966                                         const char *passwdauth)
00967 {
00968   if (!dbmdb_str)
00969     return invalidDbmdb(IDB_SET_USER_PASSWD_ERROR);
00970 
00971   conn = ch;
00972   check_auth(userauth, passwdauth, "seting user passwd");
00973 
00974   RPCStatus rpc_status;
00975   rpc_status = userPasswdSet(ConnectionPeer::getConnH(conn),
00976                                  dbmdb_str, userauth, passwdauth,
00977                                  username, passwd);
00978   return StatusMake(rpc_status);
00979 }
00980 
00981 Status DBM_Database::setPasswd(Connection *ch,
00982                                     const char *username, const char *passwd,
00983                                     const char *newpasswd)
00984                      
00985 {
00986   if (!dbmdb_str)
00987     return invalidDbmdb(IDB_SET_PASSWD_ERROR);
00988 
00989   conn = ch;
00990   RPCStatus rpc_status;
00991   rpc_status = passwdSet(ConnectionPeer::getConnH(conn),
00992                                  dbmdb_str, username, passwd, newpasswd);
00993   return StatusMake(rpc_status);
00994 }
00995 
00996 #define check_sysaccess(s, mode)  \
00997 if ((mode) != NoSysAccessMode && \
00998     (mode) != DBCreateSysAccessMode && \
00999     (mode) != AddUserSysAccessMode && \
01000     (mode) != DeleteUserSysAccessMode && \
01001     (mode) != SetUserPasswdSysAccessMode && \
01002     (mode) != AdminSysAccessMode && \
01003     (mode) != SuperUserSysAccessMode) \
01004      return Exception::make(s, "invalid database access mode 0x%x", (mode))
01005 
01006 Status DBM_Database::setUserSysAccess(Connection *ch,
01007                                            const char *username,
01008                                            SysAccessMode mode,
01009                                            const char *userauth,
01010                                            const char *passwdauth)
01011 {
01012   if (!dbmdb_str)
01013     return invalidDbmdb(IDB_SET_USER_SYSACCESS_ERROR);
01014 
01015   conn = ch;
01016   check_auth(userauth, passwdauth, "setting user sys access");
01017 
01018   check_sysaccess(IDB_SET_USER_SYSACCESS_ERROR, mode);
01019 
01020   RPCStatus rpc_status;
01021   rpc_status = userSysAccessSet(ConnectionPeer::getConnH(conn),
01022                                     dbmdb_str, userauth, passwdauth,
01023                                     username, mode);
01024   return StatusMake(rpc_status);
01025 }
01026 
01027 #define dbmupdate_str "*I*D*B*D*B*M*"
01028 
01029 Status DBM_Database::create(Connection *ch, const char *passwdauth,
01030                             const char *username, const char *passwd,
01031                             DbCreateDescription *pdbdesc)
01032 {
01033   RPCStatus rpc_status;
01034   DbCreateDescription dbdesc;
01035 
01036   if (!dbmdb_str)
01037     return invalidDbmdb(IDB_DATABASE_CREATE_ERROR);
01038 
01039   if (!passwdauth)
01040     passwdauth = Connection::getDefaultUser();
01041 
01042   if (!passwdauth)
01043     return Exception::make(IDB_AUTHENTICATION_NOT_SET, "creating DBM database %s",
01044                          dbmdb_str);
01045 
01046   create_prologue(dbdesc, &pdbdesc);
01047 
01048   rpc_status = dbmCreate(ConnectionPeer::getConnH(ch), dbmdb_str,
01049                          passwdauth, pdbdesc);
01050 
01051   if (rpc_status == RPCSuccess)
01052     {
01053       conn = ch;
01054 
01055       delete _user;
01056       _user = strdup(dbmupdate_str);
01057       delete _passwd;
01058       _passwd = strdup(passwd);
01059 
01060       Status status;
01061       status = init_db(ch);
01062       if (status)
01063         return status;
01064 
01065       delete _user;
01066       _user = strdup(username);
01067 
01068       rpc_status = dbmUpdate(ConnectionPeer::getConnH(ch), dbmdb_str,
01069                              username, passwd);
01070       
01071       return StatusMake(rpc_status);
01072     }
01073 
01074   return StatusMake(rpc_status);
01075 }
01076 
01077 Status DBM_Database::create()
01078 {
01079   return Exception::make(IDB_NOT_YET_IMPLEMENTED, "DBM_Database::create");
01080 }
01081 
01082 Status DBM_Database::update()
01083 {
01084   return Exception::make(IDB_NOT_YET_IMPLEMENTED, "DBM_Database::update");
01085 }
01086 
01087 Status DBM_Database::realize(const RecMode*)
01088 {
01089   return Exception::make(IDB_NOT_YET_IMPLEMENTED, "DBM_Database::realize");
01090 }
01091 
01092 Status DBM_Database::remove(const RecMode*)
01093 {
01094   return Exception::make(IDB_NOT_YET_IMPLEMENTED, "DBM_Database::remove");
01095 }
01096 
01097 DBM_Database::~DBM_Database()
01098 {
01099 }
01100 
01101 }

Generated on Mon Dec 22 18:15:54 2008 for eyedb by  doxygen 1.5.3