00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GCATALOG_H
00021 #define GCATALOG_H
00022
00023 #include <qvaluelist.h>
00024 #include <qpair.h>
00025 #include <qvariant.h>
00026
00027 #include <krandomsequence.h>
00028 #include <kdebug.h>
00029
00030 #include <cstring>
00031 #include <cstdlib>
00032 #include <db.h>
00033
00034 template<class Tp>
00035 struct _GCatalog_Private
00036 {
00037 QString dbName;
00038
00039 DB* dbp;
00040 QMap<QCString, DB*> indexList;
00041 KRandomSequence rnd;
00042 bool enabled;
00043
00044 _GCatalog_Private()
00045 : dbp( 0 ), enabled( true )
00046 {
00047 }
00048
00049 bool hasIndex( const QCString& name ) const
00050 {
00051 return indexList.contains( name );
00052 }
00053
00054 DB* index( const QCString& name )
00055 {
00056 return indexList[ name ];
00057 }
00058
00059 QValueList<Tp> getAllItems( DB* dbp )
00060 {
00061 Q_ASSERT( dbp != 0 );
00062
00063 DBC* cursor;
00064
00065 int ret = dbp->cursor( dbp, 0, &cursor, 0 );
00066 Q_ASSERT( cursor != 0 );
00067
00068 DBT key, data;
00069 std::memset( &key, 0, sizeof(key) );
00070 std::memset( &data, 0, sizeof(data) );
00071
00072 QValueList<Tp> tags;
00073 QByteArray a2;
00074 while( (ret = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0 ){
00075
00076 a2.setRawData( (const char*) data.data, data.size );
00077 QDataStream s( a2, IO_ReadOnly );
00078
00079 Tp tag;
00080 tag.load( s );
00081
00082 a2.resetRawData( (const char*) data.data, data.size );
00083
00084 tags << tag;
00085 }
00086
00087 cursor->c_close( cursor );
00088
00089 return tags;
00090 }
00091
00092
00093 bool addItem( DB* dbp, const QCString& id, const Tp& tag )
00094 {
00095 Q_ASSERT( dbp != 0 );
00096
00097 DBT key, data;
00098 int ret;
00099
00100 std::memset( &key, 0, sizeof(key) );
00101 std::memset( &data, 0, sizeof(data) );
00102
00103 QByteArray a1;
00104 {
00105 QDataStream stream( a1, IO_WriteOnly );
00106 stream << id;
00107 key.data = a1.data();
00108 key.size = a1.size();
00109 }
00110
00111 QByteArray a2;
00112 {
00113 QDataStream stream( a2, IO_WriteOnly );
00114 tag.store( stream );
00115 data.data = a2.data();
00116 data.size = a2.size();
00117 }
00118
00119 ret = dbp->put( dbp, 0, &key, &data, 0 );
00120
00121 return ret == 0;
00122 }
00123
00124 bool addItem( DB* dbp, const QVariant& id, const QCString& v )
00125 {
00126 Q_ASSERT( dbp != 0 );
00127
00128 DBT key, data;
00129 int ret;
00130
00131 std::memset( &key, 0, sizeof(key) );
00132 std::memset( &data, 0, sizeof(data) );
00133
00134 QByteArray a1;
00135 {
00136 QDataStream stream( a1, IO_WriteOnly );
00137 stream << id;
00138 key.data = a1.data();
00139 key.size = a1.size();
00140 }
00141
00142 QByteArray a2;
00143 {
00144 QDataStream stream( a2, IO_WriteOnly );
00145 stream << v;
00146 data.data = a2.data();
00147 data.size = a2.size();
00148 }
00149
00150 ret = dbp->put( dbp, 0, &key, &data, 0 );
00151
00152 return ret == 0;
00153 }
00154
00155 bool removeItem( DB* dbp, const QCString& id )
00156 {
00157 Q_ASSERT( dbp != 0 );
00158
00159 DBT key, data;
00160 std::memset( &key, 0, sizeof(key) );
00161 std::memset( &data, 0, sizeof(data) );
00162
00163 QByteArray a1;
00164 {
00165 QDataStream stream( a1, IO_WriteOnly );
00166 stream << id;
00167 key.data = a1.data();
00168 key.size = a1.size();
00169 }
00170
00171 int ret = 0;
00172 ret = dbp->del( dbp, 0, &key, 0 );
00173 Q_ASSERT( ret == 0 );
00174
00175 return ret == 0;
00176 }
00177
00178 bool removeItem( DB* dbp, const QVariant& id, const QCString& v )
00179 {
00180 Q_ASSERT( dbp != 0 );
00181
00182 DBT key, data;
00183 int ret;
00184
00185 std::memset( &key, 0, sizeof(key) );
00186 std::memset( &data, 0, sizeof(data) );
00187
00188 QByteArray a1;
00189 {
00190 QDataStream stream( a1, IO_WriteOnly );
00191 stream << id;
00192 key.data = a1.data();
00193 key.size = a1.size();
00194 }
00195
00196 QByteArray a2;
00197 {
00198 QDataStream stream( a2, IO_WriteOnly );
00199 stream << v;
00200 data.data = a2.data();
00201 data.size = a2.size();
00202 }
00203
00204 DBC* dbc = 0;
00205
00206 ret = dbp->cursor( dbp, 0, &dbc, 0 );
00207 Q_ASSERT( ret == 0 );
00208 if( ret != 0 )
00209 kdDebug() << "dbp->cursor: " << db_strerror(ret) << endl;
00210
00211 ret = dbc->c_get( dbc, &key, &data, DB_GET_BOTH );
00212 Q_ASSERT( ret == 0 );
00213 if( ret != 0 )
00214 kdDebug() << "dbc->c_get: " << db_strerror(ret) << endl;
00215
00216 ret = dbc->c_del( dbc, 0 );
00217 Q_ASSERT( ret == 0 );
00218
00219 dbc->c_close( dbc );
00220
00221 return ret == 0;
00222 }
00223 };
00224
00225 template <class Tp>
00226 class GCatalog
00227 {
00228 public:
00229 typedef Tp Tag;
00230 typedef QPair<QCString, QVariant> QueryArgument;
00231
00232 public:
00233 GCatalog();
00234 virtual ~GCatalog();
00235
00236 bool isValid() const;
00237 QString dbName() const;
00238
00239 bool enabled() const;
00240 void setEnabled( bool enabled );
00241
00242 virtual void open( const QString& dbName );
00243 virtual void close();
00244 virtual void sync();
00245
00246 QValueList<QCString> indexList() const;
00247 bool hasIndex( const QCString& name ) const;
00248 void addIndex( const QCString& name );
00249 void removeIndex( const QCString& name );
00250
00251 void addItem( Tag& tag );
00252 bool removeItem( const Tag& id );
00253 bool removeItemById( const QCString& id );
00254 void removeItems( const QValueList<QueryArgument>& args );
00255
00256 Tag getItemById( const QCString& id );
00257 bool hasItem( const QCString& id );
00258 QValueList<Tag> getAllItems();
00259 QValueList<Tag> query( const QValueList<QueryArgument>& args );
00260
00261 QCString generateId();
00262
00263 private:
00264 _GCatalog_Private<Tp>* d;
00265
00266 private:
00267 GCatalog( const GCatalog& source );
00268 void operator = ( const GCatalog& source );
00269 };
00270
00271 #include "gcatalog.tcc"
00272
00273 #endif