OQL.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 /*
00026   il est inutile de passer par des OQLAtom: on peut utiliser directement
00027   les Value
00028 */
00029 
00030 #include "eyedb_p.h"
00031 #include "api_lib.h"
00032 #include <assert.h>
00033 #include "eyedblib/butils.h"
00034 
00035 namespace eyedbsm {
00036   extern Boolean backend;
00037 }
00038 
00039 namespace eyedb {
00040 
00041 #define CHKEXEC() \
00042 do { \
00043   Status _status_; \
00044   if (_status_ = execute()) return _status_; \
00045   if (_status_ = getResult()) return _status_; \
00046 } while(0)
00047 
00048 
00049   void
00050   clean(char *s)
00051   {
00052     int n;
00053 
00054     for (n = strlen(s)-1; n >= 0; n--)
00055       if (s[n] != ' ' && s[n] != '\t' && s[n] != '\n')
00056         break;
00057 
00058     if (s[n] != ';')
00059       s[++n] = ';';
00060 
00061     s[n+1] = 0;
00062   }
00063 
00064   OQL::OQL(Database *_db, const char *fmt, ...)
00065   {
00066     va_list ap, aq;
00067     va_start(ap, fmt);
00068     va_copy(aq, ap);
00069     char *s = eyedblib::getFBuffer(fmt, ap); 
00070     vsprintf(s, fmt, aq);
00071     clean(s);
00072     init(_db->getConnection(), _db, s);
00073     va_end(ap);
00074   }
00075 
00076   OQL::OQL(Connection *_conn, const char *fmt, ...)
00077   {
00078     va_list ap, aq;
00079     va_start(ap, fmt);
00080     va_copy(aq, ap);
00081 
00082     char *s = eyedblib::getFBuffer(fmt, ap); 
00083     vsprintf(s, fmt, aq);
00084     clean(s);
00085     init(_conn, 0, s);
00086     va_end(ap);
00087   }
00088 
00089   void OQL::init(Connection *_conn, Database *_db, const char *s)
00090   {
00091     oql_string = strdup(s);
00092     schema_info = 0;
00093     state = True;
00094     db = _db;
00095     conn = _conn;
00096     qid = 0;
00097     executed = False;
00098     value_read = False;
00099     oql_status = Success;
00100   }
00101 
00102   Status
00103   OQL::initDatabase(Database *db)
00104   {
00105     Status status;
00106     status = db->transactionBegin();
00107     if (status)
00108       return status;
00109     OQL oql(db, "import \"stdlib\";");
00110     status = oql.execute();
00111     db->transactionCommit();
00112     return status;
00113   }
00114 
00115   //
00116   // execute methods
00117   //
00118 
00119   Status OQL::execute()
00120   {
00121     if (executed) return oql_status;
00122 
00123     IDB_LOG(IDB_LOG_OQL_EXEC, ("before '%s'\n", oql_string));
00124 
00125     RPCStatus rpc_status =
00126       oqlCreate(conn->getConnHandle(), (db ? db->getDbHandle() : 0),
00127                 oql_string, &qid, &schema_info);
00128 
00129     if (!rpc_status)
00130       db->updateSchema(*schema_info);
00131 
00132     if (db->isLocal() || eyedbsm::backend)
00133       schema_info = 0;
00134 
00135     executed = True;
00136 
00137     if (rpc_status)
00138       oql_status = new Exception(*StatusMake(rpc_status));
00139 
00140     IDB_LOG(IDB_LOG_OQL_EXEC,
00141             ("'%s' done => %s\n",
00142              oql_string,
00143              oql_status ? oql_status->getDesc() : "successful"));
00144 
00145     return oql_status;
00146   }
00147 
00148   void
00149   OQL::log_result() const
00150   {
00151     FILE *fd = utlogFDGet();
00152     if (!fd)
00153       return;
00154 
00155     utlog_p("IDB_LOG_OQL_RESULT");
00156     utlog("result value of '%s': '", oql_string);
00157     result_value.print(fd);
00158     fprintf(fd, "'\n");
00159     fflush(fd);
00160   }
00161 
00162   Status
00163   OQL::getResult()
00164   {
00165     if (value_read)
00166       return Success;
00167 
00168     Status status = StatusMake(oqlGetResult
00169                                (conn->getConnHandle(), 
00170                                 (db ? db->getDbHandle() : 0),
00171                                 qid, &result_value));
00172 
00173     if (status) return status;
00174 
00175     if ((IDB_LOG_OQL_RESULT & eyedblib::log_mask) == IDB_LOG_OQL_RESULT)
00176       log_result();
00177 
00178     value_read = True;
00179     return Success;
00180   }
00181 
00182   Status
00183   OQL::getResult(Value &value)
00184   {
00185     return execute(value);
00186   }
00187 
00188   Status
00189   OQL::getResult(ValueArray &val_array)
00190   {
00191     return execute(val_array);
00192   }
00193 
00194   Status
00195   OQL::getResult(ObjectPtrVector &obj_vect, const RecMode *rcm)
00196   {
00197     return execute(obj_vect, rcm);
00198   }
00199 
00200   Status
00201   OQL::getResult(ObjectArray &obj_array, const RecMode *rcm)
00202   {
00203     return execute(obj_array, rcm);
00204   }
00205 
00206   Status
00207   OQL::getResult(OidArray &oid_array)
00208   {
00209     return execute(oid_array);
00210   }
00211 
00212   Status
00213   OQL::execute(ValueArray &val_array)
00214   {
00215     CHKEXEC();
00216     result_value.toArray(val_array);
00217     return Success;
00218   }
00219 
00220   Status
00221   OQL::execute(ObjectPtrVector &obj_vect, const RecMode *rcm)
00222   {
00223     CHKEXEC();
00224     result_value.toArray(db, obj_vect, rcm);
00225     return Success;
00226   }
00227 
00228   Status
00229   OQL::execute(ObjectArray &obj_array, const RecMode *rcm)
00230   {
00231     CHKEXEC();
00232     result_value.toArray(db, obj_array, rcm);
00233     return Success;
00234   }
00235 
00236   Status
00237   OQL::execute(OidArray &oid_array)
00238   {
00239     CHKEXEC();
00240     result_value.toArray(oid_array);
00241     return Success;
00242   }
00243 
00244   Status
00245   OQL::execute(Value &value)
00246   {
00247     CHKEXEC();
00248     value = result_value;
00249     return Success;
00250   }
00251 
00252   OQL::~OQL()
00253   {
00254     if (db && db->getDbHandle())
00255       oqlDelete(conn->getConnHandle(), (db ? db->getDbHandle() : 0), qid);
00256 
00257     free(oql_string);
00258     delete schema_info;
00259   }
00260 }

Generated on Mon Dec 22 18:16:01 2008 for eyedb by  doxygen 1.5.3