TnFXSQLDB_ipc.h

Go to the documentation of this file.
00001 /********************************************************************************
00002 *                                                                               *
00003 *                            Via-IPC Database Support                           *
00004 *                                                                               *
00005 *********************************************************************************
00006 *       Copyright (C) 2005-2006 by Niall Douglas.   All Rights Reserved.        *
00007 *       NOTE THAT I DO NOT PERMIT ANY OF MY CODE TO BE PROMOTED TO THE GPL      *
00008 *********************************************************************************
00009 * This code is free software; you can redistribute it and/or modify it under    *
00010 * the terms of the GNU Library General Public License v2.1 as published by the  *
00011 * Free Software Foundation EXCEPT that clause 3 does not apply ie; you may not  *
00012 * "upgrade" this code to the GPL without my prior written permission.           *
00013 * Please consult the file "License_Addendum2.txt" accompanying this file.       *
00014 *                                                                               *
00015 * This code is distributed in the hope that it will be useful,                  *
00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                          *
00018 *********************************************************************************
00019 * $Id:                                                                          *
00020 ********************************************************************************/
00021 #if FX_SQLMODULE
00022 
00023 #ifndef TNFXSQLDB_IPC_H
00024 #define TNFXSQLDB_IPC_H
00025 
00026 #include "TnFXSQLDB.h"
00027 #include "FXIPC.h"
00028 #include "QSSLDevice.h"
00029 #include <qptrvector.h>
00030 
00031 // Stop CopyCursor macro from WinUser.h mucking up the code
00032 #undef CopyCursor
00033 
00034 namespace FX {
00035 
00040 #if !defined(__GCCXML__)
00041 namespace TnFXSQLDBIPCMsgsI
00042 {   /* We have a slight problem in that the chunk code which is normally static
00043     is user-definable here. Unfortunately this means we must take a chunk parameter
00044     in every constructor :( */
00045     struct ColType
00046     {
00047         TnFXSQLDB::SQLDataType datatype;
00048         FXint size;
00049         ColType(TnFXSQLDB::SQLDataType _datatype=TnFXSQLDB::Null, FXint _size=0) : datatype(_datatype), size(_size) { }
00050         friend FXStream &operator<<(FXStream &s, const ColType &i)
00051         {
00052             s << (FXuchar) i.datatype << i.size;
00053             return s;
00054         }
00055         friend FXStream &operator>>(FXStream &s, ColType &i)
00056         {
00057             FXuchar v;
00058             s >> v >> i.size;
00059             i.datatype=(TnFXSQLDB::SQLDataType) v;
00060             return s;
00061         }
00062     };
00063     struct DataContainer
00064     {   // Holds a parameter being bound or a column being fetched
00065         FXuchar type;       // A TnFXSQLDB::SQLDataType
00066         struct Data
00067         {
00068             FXuint length;
00069             union
00070             {
00071                 FXchar *text;
00072                 FXchar tinyint;
00073                 FXshort smallint;
00074                 FXint integer;
00075                 FXlong bigint;
00076                 FXfloat real;
00077                 FXdouble double_;
00078                 char timestamp[sizeof(FXTime)];
00079                 void *blob;
00080             };
00081         } data;
00082         bool mydata;
00083         DataContainer(TnFXSQLDB::SQLDataType datatype=TnFXSQLDB::Null) : type((FXuchar) datatype), mydata(false) { }
00084         void copy(const DataContainer &o)
00085         {
00086             type=o.type;
00087             data=o.data;
00088             if(TnFXSQLDB::BLOB==type || (type>=TnFXSQLDB::VarChar && type<=TnFXSQLDB::WChar))
00089             {
00090                 data.blob=malloc(data.length);
00091                 mydata=true;
00092                 memcpy(data.blob, o.data.blob, data.length);
00093             }
00094         }
00095 #ifndef HAVE_CPP0XRVALUEREFS
00096 #ifdef HAVE_CONSTTEMPORARIES
00097         DataContainer(const DataContainer &_o) : type(_o.type), mydata(_o.mydata)
00098         {
00099             DataContainer &o=const_cast<DataContainer &>(_o);
00100 #else
00101         DataContainer(DataContainer &o) : type(o.type), mydata(o.mydata)
00102         {
00103 #endif
00104 #else
00105 private:
00106         DataContainer(const DataContainer &);   // disable copy constructor
00107 public:
00108         DataContainer(DataContainer &&o) : type(std::move(o.type)), mydata(std::move(o.mydata))
00109         {
00110 #endif
00111             data=o.data;
00112             o.data.blob=0;
00113         }
00114 #ifndef HAVE_CPP0XRVALUEREFS
00115         DataContainer &operator=(const DataContainer &_o)
00116 #else
00117 private:
00118         DataContainer &operator=(const DataContainer &_o);
00119 public:
00120         DataContainer &&operator=(const DataContainer &&_o)
00121 #endif
00122         {   // Moves
00123             DataContainer &o=const_cast<DataContainer &>(_o);
00124             type=o.type;
00125             data=o.data;
00126             o.data.blob=0;
00127             return *this;
00128         }
00129         ~DataContainer()
00130         {
00131             if(mydata && data.blob)
00132             {
00133                 free(data.blob);
00134                 data.blob=0;
00135             }
00136         }
00137         friend FXStream &operator<<(FXStream &s, const DataContainer &i)
00138         {
00139             s << i.type << i.data.length;
00140             switch(i.type)
00141             {
00142             case TnFXSQLDB::Null:
00143                 break;
00144             case TnFXSQLDB::VarChar:
00145             case TnFXSQLDB::Char:
00146             case TnFXSQLDB::WVarChar:
00147             case TnFXSQLDB::WChar:
00148                 s.writeRawBytes(i.data.text, i.data.length+1);
00149                 break;
00150 
00151             case TnFXSQLDB::TinyInt:
00152                 s << i.data.tinyint;
00153                 break;
00154             case TnFXSQLDB::SmallInt:
00155                 s << i.data.smallint;
00156                 break;
00157             case TnFXSQLDB::Integer:
00158                 s << i.data.integer;
00159                 break;
00160             case TnFXSQLDB::BigInt:
00161             case TnFXSQLDB::Decimal:
00162             case TnFXSQLDB::Numeric:
00163                 s << i.data.bigint;
00164                 break;
00165 
00166             case TnFXSQLDB::Real:
00167                 s << i.data.real;
00168                 break;
00169             case TnFXSQLDB::Double:
00170             case TnFXSQLDB::Float:
00171                 s << i.data.double_;
00172                 break;
00173 
00174             case TnFXSQLDB::Timestamp:
00175             case TnFXSQLDB::Date:
00176             case TnFXSQLDB::Time:
00177                 s << *(FXTime *)(void *) i.data.timestamp;
00178                 break;
00179 
00180             case TnFXSQLDB::BLOB:
00181                 {
00182                     s.writeRawBytes((const char *) i.data.blob, i.data.length);
00183                     break;
00184                 }
00185             }
00186             return s;
00187         }
00188         friend FXStream &operator>>(FXStream &s, DataContainer &i)
00189         {
00190             s >> i.type >> i.data.length;
00191             switch(i.type)
00192             {
00193             case TnFXSQLDB::Null:
00194                 break;
00195             case TnFXSQLDB::VarChar:
00196             case TnFXSQLDB::Char:
00197             case TnFXSQLDB::WVarChar:
00198             case TnFXSQLDB::WChar:
00199                 {
00200                     FXERRHM(i.data.text=(FXchar *) malloc(i.data.length+1));
00201                     i.mydata=true;
00202                     s.readRawBytes(i.data.text, i.data.length+1);
00203                     break;
00204                 }
00205             case TnFXSQLDB::TinyInt:
00206                 s >> i.data.tinyint;
00207                 break;
00208             case TnFXSQLDB::SmallInt:
00209                 s >> i.data.smallint;
00210                 break;
00211             case TnFXSQLDB::Integer:
00212                 s >> i.data.integer;
00213                 break;
00214             case TnFXSQLDB::BigInt:
00215             case TnFXSQLDB::Decimal:
00216             case TnFXSQLDB::Numeric:
00217                 s >> i.data.bigint;
00218                 break;
00219 
00220             case TnFXSQLDB::Real:
00221                 s >> i.data.real;
00222                 break;
00223             case TnFXSQLDB::Double:
00224             case TnFXSQLDB::Float:
00225                 s >> i.data.double_;
00226                 break;
00227 
00228             case TnFXSQLDB::Timestamp:
00229             case TnFXSQLDB::Date:
00230             case TnFXSQLDB::Time:
00231                 s >> *(FXTime *)(void *) i.data.timestamp;
00232                 break;
00233 
00234             case TnFXSQLDB::BLOB:
00235                 {
00236                     FXERRHM(i.data.blob=malloc(i.data.length));
00237                     i.mydata=true;
00238                     s.readRawBytes((char *) i.data.blob, i.data.length);
00239                     break;
00240                 }
00241             }
00242             return s;
00243         }
00244     };
00245     struct ColumnData
00246     {   // Holds a column's worth of data
00247         FXuint flags;
00248         DataContainer data;
00249         ColumnData(FXuint _flags=0, TnFXSQLDB::SQLDataType datatype=TnFXSQLDB::Null)
00250             : flags(_flags), data(std::move(datatype)) { }
00251 #ifdef HAVE_CPP0XRVALUEREFS
00252 private:
00253         ColumnData(const ColumnData &); // disable copy constructor
00254         ColumnData &operator=(const ColumnData &);
00255 public:
00256         ColumnData(ColumnData &&o) : flags(std::move(o.flags)), data(std::move(o.data)) { }
00257 #endif
00258         void copy(const ColumnData &o)
00259         {
00260             flags=o.flags;
00261             data.copy(o.data);
00262         }
00263         friend FXStream &operator<<(FXStream &s, const ColumnData &i)
00264         {
00265             s << i.flags << i.data;
00266             return s;
00267         }
00268         friend FXStream &operator>>(FXStream &s, ColumnData &i)
00269         {
00270             s >> i.flags >> i.data;
00271             return s;
00272         }
00273     };
00274     // Requests a public encryption key
00275     struct RequestKey : public FXIPCMsg
00276     {
00277         typedef FXIPCMsgChunkCodeAlloc<0, true> id;
00278         typedef FXIPCMsgRegister<id, RequestKey> regtype;
00279         RequestKey()
00280             : FXIPCMsg(id::code) { }
00281         void   endianise(FXStream &s) const { }
00282         void deendianise(FXStream &s)       { }
00283     };
00284     struct RequestKeyAck : public FXIPCMsg
00285     {
00286         typedef FXIPCMsgChunkCodeAlloc<0, false> id;
00287         typedef FXIPCMsgRegister<id, RequestKeyAck> regtype;
00288         FXSSLPKey pkey;
00289         RequestKeyAck() : FXIPCMsg(0) { }
00290         RequestKeyAck(FXuint _id, const FXSSLPKey &_pkey)
00291             : FXIPCMsg(id::code, _id), pkey(_pkey) { }
00292         void   endianise(FXStream &s) const { s << pkey; }
00293         void deendianise(FXStream &s)       { s >> pkey; }
00294     };
00295     // Opens a database
00296     struct Open : public FXIPCMsg
00297     {
00298         typedef FXIPCMsgChunkCodeAlloc<RequestKey::id::nextcode, true> id;
00299         typedef FXIPCMsgRegister<id, Open> regtype;
00300         FXString driver;        // Name of the remote driver
00301         FXString dbname;
00302         FXString user;
00303         QBuffer password;
00304         QHostAddress host;
00305         FXushort port;
00306         Open() : FXIPCMsg(0) { }
00307         Open(const FXString &_driver, const FXString &_dbname, const FXString &_user, const QHostAddress &_host, FXushort _port)
00308             : FXIPCMsg(id::code), driver(_driver), dbname(_dbname), user(_user), host(_host), port(_port) { }
00309         void   endianise(FXStream &s) const { s << driver << dbname << user << !password.isNull(); if(!password.isNull()) { s << (FXuint)password.buffer().size(); s.writeRawBytes(password.buffer().data(), password.buffer().size()); } s << host << port; }
00310         void deendianise(FXStream &s)       { s >> driver >> dbname >> user; bool hasp; s >> hasp; if(hasp) { FXuint l; s >> l; password.buffer().resize(l); s.readRawBytes(password.buffer().data(), l); } s >> host >> port; }
00311     };
00312     struct OpenAck : public FXIPCMsg
00313     {
00314         typedef FXIPCMsgChunkCodeAlloc<RequestKey::id::nextcode, false> id;
00315         typedef FXIPCMsgRegister<id, OpenAck> regtype;
00316         FXuint connh;
00317         OpenAck() : FXIPCMsg(0) { }
00318         OpenAck(FXuint _id, FXuint _connh)
00319             : FXIPCMsg(id::code, _id), connh(_connh) { }
00320         void   endianise(FXStream &s) const { s << connh; }
00321         void deendianise(FXStream &s)       { s >> connh; }
00322     };
00323     // Closes a database
00324     struct Close : public FXIPCMsg
00325     {
00326         typedef FXIPCMsgChunkCodeAlloc<Open::id::nextcode, true> id;
00327         typedef FXIPCMsgRegister<id, Close> regtype;
00328         FXuint connh;
00329         Close(FXuint _connh=0) : FXIPCMsg(id::code), connh(_connh) { }
00330         void   endianise(FXStream &ds) const { ds << connh; }
00331         void deendianise(FXStream &ds)       { ds >> connh; }
00332     };
00333     struct CloseAck : public FXIPCMsg
00334     {
00335         typedef FXIPCMsgChunkCodeAlloc<Open::id::nextcode, false> id;
00336         typedef FXIPCMsgRegister<id, CloseAck> regtype;
00337         CloseAck(FXuint _id=0) : FXIPCMsg(id::code, _id) { }
00338         void   endianise(FXStream &ds) const { }
00339         void deendianise(FXStream &ds)       { }
00340     };
00341     // Prepares a statement
00342     struct PrepareStatement : public FXIPCMsg
00343     {
00344         typedef FXIPCMsgChunkCodeAlloc<Close::id::nextcode, true> id;
00345         typedef FXIPCMsgRegister<id, PrepareStatement> regtype;
00346         FXuint connh;           // Connection handle
00347         FXString statement;
00348         FXuint request;         // >0 for execute immediately
00349         FXuint cursflags;       // ==0 for no results
00350         PrepareStatement() : FXIPCMsg(0), request(0), cursflags(0) { }
00351         PrepareStatement(FXuint _connh, const FXString &_statement, FXuint _request=0, FXuint _cursflags=0)
00352             : FXIPCMsg(id::code), connh(_connh), statement(_statement), request(_request), cursflags(_cursflags) { }
00353         void   endianise(FXStream &s) const { s << connh << statement << request << cursflags; }
00354         void deendianise(FXStream &s)       { s >> connh >> statement >> request >> cursflags; }
00355     };
00356     struct PrepareStatementAck : public FXIPCMsg
00357     {
00358         typedef FXIPCMsgChunkCodeAlloc<Close::id::nextcode, false> id;
00359         typedef FXIPCMsgRegister<id, PrepareStatementAck> regtype;
00360         FXuint stmth;
00361         QMemArray<FXString> parNames;
00362 
00363         FXuint cursh;           // If it was immediate
00364         FXuint flags;
00365         FXuint columns;
00366         FXint rows;                     // Can be -1 if unknown
00367         QPtrVector<ColumnData> *data;
00368         FXint rowsToGo;                 // Rows to go after this batch of columns (can be -1)
00369         PrepareStatementAck() : FXIPCMsg(0), stmth(0), cursh(0), flags(0), columns(0), rows(0), data(0), rowsToGo(0) { }
00370         PrepareStatementAck(FXuint _id, FXuint _stmth, FXuint _cursh=0, FXuint _flags=0, FXuint _columns=0, FXint _rows=0)
00371             : FXIPCMsg(id::code, _id), stmth(_stmth), cursh(_cursh), flags(_flags), columns(_columns), rows(_rows), data(0), rowsToGo(-1) { }
00372         ~PrepareStatementAck() { FXDELETE(data); }
00373         void   endianise(FXStream &s) const { s << stmth << parNames << cursh; if(cursh) s << flags << columns << rows << *data << rowsToGo; }
00374         void deendianise(FXStream &s)       { s >> stmth >> parNames >> cursh; if(cursh) { FXERRHM(data=new QPtrVector<ColumnData>(true)); s >> flags >> columns >> rows >> *data >> rowsToGo; } }
00375     };
00376     // Unprepares a statement
00377     struct UnprepareStatement : public FXIPCMsg
00378     {
00379         typedef FXIPCMsgChunkCodeAlloc<PrepareStatement::id::nextcode, false> id;
00380         typedef FXIPCMsgRegister<id, UnprepareStatement> regtype;
00381         FXuint stmth;
00382         UnprepareStatement() : FXIPCMsg(0), stmth(0) { }
00383         UnprepareStatement(FXuint _stmth) : FXIPCMsg(id::code), stmth(_stmth) { }
00384         void   endianise(FXStream &s) const { s << stmth; }
00385         void deendianise(FXStream &s)       { s >> stmth; }
00386     };
00387     // Binds a parameter
00388     struct BindParameter : public FXIPCMsg
00389     {
00390         typedef FXIPCMsgChunkCodeAlloc<UnprepareStatement::id::nextcode, true> id;
00391         typedef FXIPCMsgRegister<id, BindParameter> regtype;
00392         FXuint stmth;
00393         FXint paridx;
00394         DataContainer par;
00395         BindParameter() : FXIPCMsg(0), stmth(0), paridx(0) { }
00396         BindParameter(FXuint _stmth, FXint _paridx, TnFXSQLDB::SQLDataType datatype)
00397             : FXIPCMsg(id::code), stmth(_stmth), paridx(_paridx), par(datatype) { }
00398         void   endianise(FXStream &s) const { s << stmth << paridx << par; }
00399         void deendianise(FXStream &s)       { s >> stmth >> paridx >> par; }
00400     };
00401     struct BindParameterAck : public FXIPCMsg
00402     {
00403         typedef FXIPCMsgChunkCodeAlloc<UnprepareStatement::id::nextcode, false> id;
00404         typedef FXIPCMsgRegister<id, BindParameterAck> regtype;
00405         BindParameterAck(FXuint _id=0) : FXIPCMsg(id::code, _id) { }
00406         void   endianise(FXStream &s) const { }
00407         void deendianise(FXStream &s)       { }
00408     };
00409     // Executes a prepared statement
00410     struct Execute : public FXIPCMsg
00411     {
00412         typedef FXIPCMsgChunkCodeAlloc<BindParameter::id::nextcode, true> id;
00413         typedef FXIPCMsgRegister<id, Execute> regtype;
00414         FXuint stmth;
00415         FXuint request;     // How many of the results to return immediately
00416         FXuint cursflags;
00417         Execute() : FXIPCMsg(0), stmth(0), request(0), cursflags(0) { }
00418         Execute(FXuint _stmth, FXuint _request, FXuint _cursflags)
00419             : FXIPCMsg(id::code), stmth(_stmth), request(_request), cursflags(_cursflags) { }
00420         void   endianise(FXStream &s) const { s << stmth << request << cursflags; }
00421         void deendianise(FXStream &s)       { s >> stmth >> request >> cursflags; }
00422     };
00423     struct ExecuteAck : public FXIPCMsg
00424     {
00425         typedef FXIPCMsgChunkCodeAlloc<BindParameter::id::nextcode, false> id;
00426         typedef FXIPCMsgRegister<id, ExecuteAck> regtype;
00427         FXuint cursh;                   // Handle to the returned cursor
00428         FXuint flags;
00429         FXuint columns;
00430         FXint rows;                     // Can be -1 if unknown
00431         QPtrVector<ColumnData> *data;
00432         FXint rowsToGo;                 // Rows to go after this batch of columns (can be -1)
00433         ExecuteAck(FXuint _id=0, FXuint _cursh=0, FXuint _flags=0, FXuint _columns=0, FXint _rows=0, FXint _rowsToGo=0)
00434             : FXIPCMsg(id::code, _id), cursh(_cursh), flags(_flags), columns(_columns), rows(_rows), data(0), rowsToGo(_rowsToGo) { }
00435         ~ExecuteAck() { FXDELETE(data); }
00436         void   endianise(FXStream &s) const { s << cursh; if(cursh) s << flags << columns << rows << *data << rowsToGo; }
00437         void deendianise(FXStream &s)       { s >> cursh; if(cursh) { FXERRHM(data=new QPtrVector<ColumnData>(true)); s >> flags >> columns >> rows >> *data >> rowsToGo; } }
00438     };
00439     // Closes a cursor
00440     struct CloseCursor : public FXIPCMsg
00441     {
00442         typedef FXIPCMsgChunkCodeAlloc<Execute::id::nextcode, false> id;
00443         typedef FXIPCMsgRegister<id, CloseCursor> regtype;
00444         FXuint cursh;
00445         CloseCursor() : FXIPCMsg(0), cursh(0) { }
00446         CloseCursor(FXuint _cursh)
00447             : FXIPCMsg(id::code), cursh(_cursh) { }
00448         void   endianise(FXStream &s) const { s << cursh; }
00449         void deendianise(FXStream &s)       { s >> cursh; }
00450     };
00451     // Request rows of results
00452     struct RequestRows : public FXIPCMsg
00453     {
00454         typedef FXIPCMsgChunkCodeAlloc<CloseCursor::id::nextcode, true> id;
00455         typedef FXIPCMsgRegister<id, RequestRows> regtype;
00456         FXuint cursh;
00457         FXuint where;
00458         FXuint request;
00459         RequestRows() : FXIPCMsg(0), cursh(0), request(0) { }
00460         RequestRows(FXuint _cursh, FXuint _where, FXuint _request)
00461             : FXIPCMsg(id::code), cursh(_cursh), where(_where), request(_request) { }
00462         void   endianise(FXStream &s) const { s << cursh << where << request; }
00463         void deendianise(FXStream &s)       { s >> cursh >> where >> request; }
00464     };
00465     struct RequestRowsAck : public FXIPCMsg
00466     {
00467         typedef FXIPCMsgChunkCodeAlloc<CloseCursor::id::nextcode, false> id;
00468         typedef FXIPCMsgRegister<id, RequestRowsAck> regtype;
00469         QPtrVector<ColumnData> *data;
00470         FXint rowsToGo;                 // Rows to go after this batch of columns (can be -1)
00471         RequestRowsAck(FXuint _id=0, FXint _rowsToGo=0)
00472             : FXIPCMsg(id::code, _id), data(0), rowsToGo(_rowsToGo) { }
00473         ~RequestRowsAck() { FXDELETE(data); }
00474         void   endianise(FXStream &s) const { s << *data << rowsToGo; }
00475         void deendianise(FXStream &s)       { FXERRHM(data=new QPtrVector<ColumnData>(true)); s >> *data >> rowsToGo; }
00476     };
00477     // Request the types of the results
00478     struct RequestColTypes : public FXIPCMsg
00479     {
00480         typedef FXIPCMsgChunkCodeAlloc<RequestRows::id::nextcode, true> id;
00481         typedef FXIPCMsgRegister<id, RequestColTypes> regtype;
00482         FXuint cursh;
00483         RequestColTypes() : FXIPCMsg(0), cursh(0) { }
00484         RequestColTypes(FXuint _cursh)
00485             : FXIPCMsg(id::code), cursh(_cursh) { }
00486         void   endianise(FXStream &s) const { s << cursh; }
00487         void deendianise(FXStream &s)       { s >> cursh; }
00488     };
00489     struct RequestColTypesAck : public FXIPCMsg
00490     {
00491         typedef FXIPCMsgChunkCodeAlloc<RequestRows::id::nextcode, false> id;
00492         typedef FXIPCMsgRegister<id, RequestColTypesAck> regtype;
00493         QMemArray<ColType> *data;
00494         RequestColTypesAck(FXuint _id=0)
00495             : FXIPCMsg(id::code, _id), data(0) { }
00496         ~RequestColTypesAck() { FXDELETE(data); }
00497         void   endianise(FXStream &s) const { s << *data; }
00498         void deendianise(FXStream &s)       { FXERRHM(data=new QMemArray<ColType>); s >> *data; }
00499     };
00500     // Request the headers of the results
00501     struct RequestColHeaders : public FXIPCMsg
00502     {
00503         typedef FXIPCMsgChunkCodeAlloc<RequestColTypes::id::nextcode, true> id;
00504         typedef FXIPCMsgRegister<id, RequestColHeaders> regtype;
00505         FXuint cursh;
00506         RequestColHeaders() : FXIPCMsg(0), cursh(0) { }
00507         RequestColHeaders(FXuint _cursh)
00508             : FXIPCMsg(id::code), cursh(_cursh) { }
00509         void   endianise(FXStream &s) const { s << cursh; }
00510         void deendianise(FXStream &s)       { s >> cursh; }
00511     };
00512     struct RequestColHeadersAck : public FXIPCMsg
00513     {
00514         typedef FXIPCMsgChunkCodeAlloc<RequestColTypes::id::nextcode, false> id;
00515         typedef FXIPCMsgRegister<id, RequestColHeadersAck> regtype;
00516         QPtrVector<ColumnData> *data;
00517         RequestColHeadersAck(FXuint _id=0)
00518             : FXIPCMsg(id::code, _id), data(0) { }
00519         ~RequestColHeadersAck() { FXDELETE(data); }
00520         void   endianise(FXStream &s) const { s << *data; }
00521         void deendianise(FXStream &s)       { FXERRHM(data=new QPtrVector<ColumnData>(true)); s >> *data; }
00522     };
00523     // Copies a cursor
00524     struct CopyCursor : public FXIPCMsg
00525     {
00526         typedef FXIPCMsgChunkCodeAlloc<RequestColHeaders::id::nextcode, true> id;
00527         typedef FXIPCMsgRegister<id, CopyCursor> regtype;
00528         FXuint cursh;
00529         CopyCursor() : FXIPCMsg(0), cursh(0) { }
00530         CopyCursor(FXuint _cursh)
00531             : FXIPCMsg(id::code), cursh(_cursh) { }
00532         void   endianise(FXStream &s) const { s << cursh; }
00533         void deendianise(FXStream &s)       { s >> cursh; }
00534     };
00535     struct CopyCursorAck : public FXIPCMsg
00536     {
00537         typedef FXIPCMsgChunkCodeAlloc<RequestColHeaders::id::nextcode, false> id;
00538         typedef FXIPCMsgRegister<id, CopyCursorAck> regtype;
00539         FXuint cursh;
00540         CopyCursorAck(FXuint _id=0, FXuint _cursh=0)
00541             : FXIPCMsg(id::code, _id), cursh(_cursh) { }
00542         void   endianise(FXStream &s) const { s << cursh; }
00543         void deendianise(FXStream &s)       { s >> cursh; }
00544     };
00545 }
00546 
00557 template<unsigned int chunkno> struct TnFXSQLDBIPCMsgs
00558 {
00559     typedef FXIPCMsgChunkCodeAlloc<chunkno, true> ChunkBegin;
00560 
00561     struct RequestKey : public TnFXSQLDBIPCMsgsI::RequestKey
00562     {
00563         typedef FXIPCMsgChunkCodeAlloc<ChunkBegin::code, true> id;
00564         typedef FXIPCMsgRegister<id, RequestKey> regtype;
00565     };
00566     struct RequestKeyAck : public TnFXSQLDBIPCMsgsI::RequestKeyAck
00567     {
00568         typedef FXIPCMsgChunkCodeAlloc<ChunkBegin::code, false> id;
00569         typedef FXIPCMsgRegister<id, RequestKeyAck> regtype;
00570     };
00571     struct Open : public TnFXSQLDBIPCMsgsI::Open
00572     {
00573         typedef FXIPCMsgChunkCodeAlloc<RequestKey::id::nextcode, true> id;
00574         typedef FXIPCMsgRegister<id, Open> regtype;
00575     };
00576     struct OpenAck : public TnFXSQLDBIPCMsgsI::OpenAck
00577     {
00578         typedef FXIPCMsgChunkCodeAlloc<RequestKey::id::nextcode, false> id;
00579         typedef FXIPCMsgRegister<id, OpenAck> regtype;
00580     };
00581     struct Close : public TnFXSQLDBIPCMsgsI::Close
00582     {
00583         typedef FXIPCMsgChunkCodeAlloc<Open::id::nextcode, true> id;
00584         typedef FXIPCMsgRegister<id, Close> regtype;
00585     };
00586     struct CloseAck : public TnFXSQLDBIPCMsgsI::CloseAck
00587     {
00588         typedef FXIPCMsgChunkCodeAlloc<Open::id::nextcode, false> id;
00589         typedef FXIPCMsgRegister<id, CloseAck> regtype;
00590     };
00591     struct PrepareStatement : public TnFXSQLDBIPCMsgsI::PrepareStatement
00592     {
00593         typedef FXIPCMsgChunkCodeAlloc<Close::id::nextcode, true> id;
00594         typedef FXIPCMsgRegister<id, PrepareStatement> regtype;
00595     };
00596     struct PrepareStatementAck : public TnFXSQLDBIPCMsgsI::PrepareStatementAck
00597     {
00598         typedef FXIPCMsgChunkCodeAlloc<Close::id::nextcode, false> id;
00599         typedef FXIPCMsgRegister<id, PrepareStatementAck> regtype;
00600     };
00601     struct UnprepareStatement : public TnFXSQLDBIPCMsgsI::UnprepareStatement
00602     {
00603         typedef FXIPCMsgChunkCodeAlloc<PrepareStatement::id::nextcode, false> id;
00604         typedef FXIPCMsgRegister<id, UnprepareStatement> regtype;
00605     };
00606     struct BindParameter : public TnFXSQLDBIPCMsgsI::BindParameter
00607     {
00608         typedef FXIPCMsgChunkCodeAlloc<UnprepareStatement::id::nextcode, true> id;
00609         typedef FXIPCMsgRegister<id, BindParameter> regtype;
00610     };
00611     struct BindParameterAck : public TnFXSQLDBIPCMsgsI::BindParameterAck
00612     {
00613         typedef FXIPCMsgChunkCodeAlloc<UnprepareStatement::id::nextcode, false> id;
00614         typedef FXIPCMsgRegister<id, BindParameterAck> regtype;
00615     };
00616     struct Execute : public TnFXSQLDBIPCMsgsI::Execute
00617     {
00618         typedef FXIPCMsgChunkCodeAlloc<BindParameter::id::nextcode, true> id;
00619         typedef FXIPCMsgRegister<id, Execute> regtype;
00620     };
00621     struct ExecuteAck : public TnFXSQLDBIPCMsgsI::ExecuteAck
00622     {
00623         typedef FXIPCMsgChunkCodeAlloc<BindParameter::id::nextcode, false> id;
00624         typedef FXIPCMsgRegister<id, ExecuteAck> regtype;
00625     };
00626     struct CloseCursor : public TnFXSQLDBIPCMsgsI::CloseCursor
00627     {
00628         typedef FXIPCMsgChunkCodeAlloc<Execute::id::nextcode, false> id;
00629         typedef FXIPCMsgRegister<id, CloseCursor> regtype;
00630     };
00631     struct RequestRows : public TnFXSQLDBIPCMsgsI::RequestRows
00632     {
00633         typedef FXIPCMsgChunkCodeAlloc<CloseCursor::id::nextcode, true> id;
00634         typedef FXIPCMsgRegister<id, RequestRows> regtype;
00635     };
00636     struct RequestRowsAck : public TnFXSQLDBIPCMsgsI::RequestRowsAck
00637     {
00638         typedef FXIPCMsgChunkCodeAlloc<CloseCursor::id::nextcode, false> id;
00639         typedef FXIPCMsgRegister<id, RequestRowsAck> regtype;
00640     };
00641     struct RequestColTypes : public TnFXSQLDBIPCMsgsI::RequestColTypes
00642     {
00643         typedef FXIPCMsgChunkCodeAlloc<RequestRows::id::nextcode, true> id;
00644         typedef FXIPCMsgRegister<id, RequestColTypes> regtype;
00645     };
00646     struct RequestColTypesAck : public TnFXSQLDBIPCMsgsI::RequestColTypesAck
00647     {
00648         typedef FXIPCMsgChunkCodeAlloc<RequestRows::id::nextcode, false> id;
00649         typedef FXIPCMsgRegister<id, RequestColTypesAck> regtype;
00650     };
00651     struct RequestColHeaders : public TnFXSQLDBIPCMsgsI::RequestColHeaders
00652     {
00653         typedef FXIPCMsgChunkCodeAlloc<RequestColTypes::id::nextcode, true> id;
00654         typedef FXIPCMsgRegister<id, RequestColHeaders> regtype;
00655     };
00656     struct RequestColHeadersAck : public TnFXSQLDBIPCMsgsI::RequestColHeadersAck
00657     {
00658         typedef FXIPCMsgChunkCodeAlloc<RequestColTypes::id::nextcode, false> id;
00659         typedef FXIPCMsgRegister<id, RequestColHeadersAck> regtype;
00660     };
00661     struct CopyCursor : public TnFXSQLDBIPCMsgsI::CopyCursor
00662     {
00663         typedef FXIPCMsgChunkCodeAlloc<RequestColHeaders::id::nextcode, true> id;
00664         typedef FXIPCMsgRegister<id, CopyCursor> regtype;
00665     };
00666     struct CopyCursorAck : public TnFXSQLDBIPCMsgsI::CopyCursorAck
00667     {
00668         typedef FXIPCMsgChunkCodeAlloc<RequestColHeaders::id::nextcode, false> id;
00669         typedef FXIPCMsgRegister<id, CopyCursorAck> regtype;
00670     };
00671     typedef FXIPCMsgChunk<typename Generic::TL::append<typename Generic::TL::create<
00672             typename RequestKey::regtype,
00673             typename RequestKeyAck::regtype,
00674             typename Open::regtype,
00675             typename OpenAck::regtype,
00676             typename Close::regtype,
00677             typename CloseAck::regtype,
00678             typename PrepareStatement::regtype,
00679             typename PrepareStatementAck::regtype,
00680             typename UnprepareStatement::regtype,
00681             typename BindParameter::regtype,
00682             typename BindParameterAck::regtype,
00683             typename Execute::regtype,
00684             typename ExecuteAck::regtype,
00685             typename CloseCursor::regtype>::value, typename Generic::TL::create<
00686             typename RequestRows::regtype,
00687             typename RequestRowsAck::regtype,
00688             typename RequestColTypes::regtype,
00689             typename RequestColTypesAck::regtype,
00690             typename RequestColHeaders::regtype,
00691             typename RequestColHeadersAck::regtype,
00692             typename CopyCursor::regtype,
00693             typename CopyCursorAck::regtype
00694         >::value>::value> Chunk;
00695 
00696     typedef typename Generic::TL::create<Chunk>::value ChunkTypeList;
00697 };
00698 #endif // !defined(__GCCXML__)
00699 
00700 #ifdef _MSC_VER
00701 #pragma warning(push)
00702 #pragma warning(disable : 4275) // non dll interface use as base
00703 #endif
00704 
00761 struct TnFXSQLDB_ipcPrivate;
00762 class FXSQLMODULEAPI TnFXSQLDB_ipc : public TnFXSQLDB, public FXIPCChannelIndirector
00763 {
00764     friend struct TnFXSQLDB_ipcPrivate;
00765     TnFXSQLDB_ipcPrivate *p;
00766     TnFXSQLDB_ipc(const TnFXSQLDB_ipc &);
00767     TnFXSQLDB_ipc &operator=(const TnFXSQLDB_ipc &);
00768     typedef Generic::Functor<Generic::TL::create<bool, FXIPCMsg *FXRESTRICT, FXIPCMsg *FXRESTRICT>::value> AckHandler;
00769     typedef void (*delMsgSpec)(FXIPCMsg *m);
00770     inline void FXDLLLOCAL addAsyncMsg(FXIPCMsg *FXRESTRICT ia, FXIPCMsg *FXRESTRICT i, void *ref, void (*refdel)(void *), AckHandler handler, delMsgSpec iadel, delMsgSpec idel);
00771     template<class reftype> static void delRef(void *ptr) { delete static_cast<reftype *>(ptr); }
00772     template<class msgacktype, class msgtype, class reprtype> inline void sendAsyncMsg(msgtype *i, reprtype *dest, AckHandler handler)
00773     {   // Avoid including FXRollback.h
00774         FXAutoPtr<msgacktype> ia;
00775         FXAutoPtr<FXRefingObject<reprtype> > destref;
00776         FXERRHM(ia=new msgacktype);
00777         if(dest) { FXERRHM(destref=new FXRefingObject<reprtype>(dest)); }
00778         sendMsg(PtrPtr(ia), i, 0);
00779         addAsyncMsg(PtrPtr(ia), i, PtrPtr(destref), &delRef<FXRefingObject<reprtype> >, std::move(handler), msgacktype::regtype::delMsg, msgtype::regtype::delMsg);
00780         PtrRelease(ia);
00781         PtrRelease(destref);
00782     }
00783     inline bool FXDLLLOCAL pollAcks(bool waitIfNoneReady=false);
00784     struct Column;
00785     struct Cursor;      friend struct Cursor;
00786     struct Statement;   friend struct Statement;
00787 public:
00788     static const FXString MyName;
00790     TnFXSQLDB_ipc(const FXString &dbspec, const FXString &user=FXString::nullStr(), const QHostAddress &host=QHOSTADDRESS_LOCALHOST, FXushort port=0);
00791     ~TnFXSQLDB_ipc();
00792 
00793     using FXIPCChannelIndirector::channel;
00794     using FXIPCChannelIndirector::msgChunk;
00795     using FXIPCChannelIndirector::msgRouting;
00796     using FXIPCChannelIndirector::setIPCChannel;
00797 
00799     bool isAsynchronous() const throw();
00801     TnFXSQLDB_ipc &setIsAsynchronous(bool v=true) throw();
00803     void prefetching(FXuint &no, FXuint &askForMore) const throw();
00805     TnFXSQLDB_ipc &setPrefetching(FXuint no, FXuint askForMore) throw();
00806 
00807     virtual const FXString &versionInfo() const;
00808 
00809     virtual void open(const FXString &password=FXString::nullStr());
00810     virtual void close();
00811     virtual TnFXSQLDBStatementRef prepare(const FXString &text);
00812 
00813     virtual TnFXSQLDBCursorRef execute(const FXString &text, FXuint flags=TnFXSQLDBCursor::IsDynamic|TnFXSQLDBCursor::ForwardOnly, QWaitCondition *latch=0);
00814     virtual void immediate(const FXString &text);
00815 
00816     virtual void synchronise();
00817 };
00818 
00830 struct TnFXSQLDBServerPrivate;
00831 class FXSQLMODULEAPI TnFXSQLDBServer : public FXIPCChannelIndirector
00832 {
00833     TnFXSQLDBServerPrivate *p;
00834     TnFXSQLDBServer(const TnFXSQLDBServer &);
00835     TnFXSQLDBServer &operator=(const TnFXSQLDBServer &);
00836 public:
00838     TnFXSQLDBServer();
00839     ~TnFXSQLDBServer();
00840 
00841     using FXIPCChannelIndirector::channel;
00842     using FXIPCChannelIndirector::msgChunk;
00843     using FXIPCChannelIndirector::msgRouting;
00844     using FXIPCChannelIndirector::setIPCChannel;
00845 
00849     TnFXSQLDBServer &addDatabase(const FXString &driverName, const FXString &dbname, const FXString &user="*", const QHostAddress &host=QHostAddress(), FXushort port=0);
00851     bool removeDatabase(const FXString &driverName, const FXString &dbname, const FXString &user="*", const QHostAddress &host=QHostAddress(), FXushort port=0);
00852 
00853     /* The message handler which looks for messages addressed to this server
00854     and processes them. You must call this in the message handler of that
00855     which serves the database */
00856     FXIPCChannel::HandledCode handleMsg(FXIPCMsg *msg);
00857 };
00858 
00859 #ifdef _MSC_VER
00860 #pragma warning(pop)
00861 #endif
00862 
00863 }
00864 
00865 #endif
00866 #endif

(C) 2002-2009 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Nov 20 18:31:26 2009 for TnFOX by doxygen v1.4.7