22 #include <tqfileinfo.h> 23 #include <tqdatastream.h> 25 #include <krandomsequence.h> 34 #include USE_DB_H_PATH 39 struct _Catalog_Private
44 TQMap<TQCString, DB*> indexList;
49 : dbp( 0 ), enabled( true )
53 bool hasIndex(
const TQCString& name )
const 55 return indexList.contains( name );
58 DB* index(
const TQCString& name )
60 return indexList[ name ];
63 bool addItem( DB* dbp,
const TQCString&
id,
const Tag& tag )
70 std::memset( &key, 0,
sizeof(key) );
71 std::memset( &data, 0,
sizeof(data) );
75 TQDataStream stream( a1, IO_WriteOnly );
83 TQDataStream stream( a2, IO_WriteOnly );
85 data.data = a2.data();
86 data.size = a2.size();
89 ret = dbp->put( dbp, 0, &key, &data, 0 );
94 bool addItem( DB* dbp,
const TQVariant&
id,
const TQCString& v )
101 std::memset( &key, 0,
sizeof(key) );
102 std::memset( &data, 0,
sizeof(data) );
106 TQDataStream stream( a1, IO_WriteOnly );
108 key.data = a1.data();
109 key.size = a1.size();
114 TQDataStream stream( a2, IO_WriteOnly );
116 data.data = a2.data();
117 data.size = a2.size();
120 ret = dbp->put( dbp, 0, &key, &data, 0 );
132 : d( new _Catalog_Private() )
149 TQValueList<TQCString> Catalog::indexList()
const 151 TQValueList<TQCString> l;
152 TQMap<TQCString, DB*>::Iterator it = d->indexList.begin();
153 while( it != d->indexList.end() ){
161 bool Catalog::enabled()
const 166 void Catalog::setEnabled(
bool isEnabled )
168 d->enabled = isEnabled;
177 Q_ASSERT( d->dbp != 0 );
179 TQMap<TQCString, DB*>::Iterator it = d->indexList.find( name );
180 if( it == d->indexList.end() ){
185 if ((ret = db_create(&dbp, 0, 0)) != 0) {
186 kdDebug() <<
"db_create: " << db_strerror(ret) << endl;
190 if ((ret = dbp->set_flags(dbp, DB_DUP | DB_DUPSORT)) != 0) {
191 dbp->err(dbp, ret,
"set_flags: DB_DUP | DB_DUPSORT");
192 dbp->close( dbp, 0 );
196 TQFileInfo fileInfo( d->dbName );
197 TQString indexName = fileInfo.dirPath(
true) +
"/" + fileInfo.baseName(
true) +
"." + TQString(name) +
".idx";
199 if( (ret = dbp->set_cachesize( dbp, 0, 2 * 1024 * 1024, 0 )) != 0 ){
200 kdDebug() <<
"set_cachesize: " << db_strerror(ret) << endl;
203 if ((ret = dbp->open(
204 dbp, NULL, TQFile::encodeName( indexName ).data(), 0, DB_BTREE, DB_CREATE, 0664)) != 0) {
205 kdDebug() <<
"db_open: " << db_strerror(ret) << endl;
206 dbp->close( dbp, 0 );
210 d->indexList[ name ] = dbp;
218 void Catalog::close()
220 d->dbName = TQString();
222 TQMap<TQCString, DB*>::Iterator it = d->indexList.begin();
223 while( it != d->indexList.end() ){
225 it.data()->close( it.data(), 0 );
229 d->indexList.clear();
232 d->dbp->close( d->dbp, 0 );
241 void Catalog::open(
const TQString& dbName )
243 Q_ASSERT( d->dbp == 0 );
249 if ((ret = db_create(&d->dbp, 0, 0)) != 0) {
250 kdDebug() <<
"db_create: " << db_strerror(ret) << endl;
254 if ((ret = d->dbp->set_flags(d->dbp, DB_RECNUM)) != 0) {
255 d->dbp->err(d->dbp, ret,
"set_flags: DB_RECNUM");
260 if( (ret = d->dbp->set_cachesize( d->dbp, 0, 2 * 1024 * 1024, 0 )) != 0 ){
261 kdDebug() <<
"set_cachesize: " << db_strerror(ret) << endl;
264 if ((ret = d->dbp->open(
265 d->dbp, NULL, d->dbName.local8Bit(), 0, DB_BTREE, DB_CREATE, 0664)) != 0) {
266 kdDebug() <<
"db_open: " << db_strerror(ret) << endl;
276 TQString Catalog::dbName()
const 285 bool Catalog::isValid()
const 294 void Catalog::addItem( Tag& tag )
296 if( tag.name().isEmpty() )
299 TQCString
id = generateId();
302 if( d->addItem(d->dbp,
id, tag) ){
303 TQMap<TQCString, DB*>::Iterator it = d->indexList.begin();
304 while( it != d->indexList.end() ){
305 if( tag.hasAttribute(it.key()) )
306 d->addItem( it.data(), tag.attribute(it.key()),
id );
316 Tag Catalog::getItemById(
const TQCString&
id )
318 Q_ASSERT( d->dbp != 0 );
321 std::memset( &key, 0,
sizeof(key) );
322 std::memset( &data, 0,
sizeof(data) );
326 TQDataStream stream( a1, IO_WriteOnly );
328 key.data = a1.data();
329 key.size = a1.size();
332 int ret = d->dbp->get( d->dbp, 0, &key, &data, 0 );
333 Q_ASSERT( ret == 0 );
339 a.setRawData( (
const char*) data.data, data.size );
340 TQDataStream stream( a, IO_ReadOnly );
342 a.resetRawData( (
const char*) data.data, data.size );
354 Q_ASSERT( d->dbp != 0 );
355 d->dbp->sync( d->dbp, 0 );
357 TQMap<TQCString, DB*>::Iterator it = d->indexList.begin();
358 while( it != d->indexList.end() ){
359 it.data()->sync( it.data(), 0 );
368 TQValueList<Tag> Catalog::query(
const TQValueList<QueryArgument>& args )
370 TQValueList<Tag> tags;
374 DBC** cursors =
new DBC* [ args.size() + 1 ];
376 TQValueList< TQPair<TQCString,TQVariant> >::ConstIterator it = args.begin();
378 while( it != args.end() ){
379 TQCString indexName = (*it).first;
380 TQVariant value = (*it).second;
382 if( d->hasIndex(indexName) ) {
383 DB* dbp = d->index( indexName );
384 Q_ASSERT( dbp != 0 );
386 std::memset( &key, 0,
sizeof(key) );
387 std::memset( &data, 0,
sizeof(data) );
391 TQDataStream stream( a1, IO_WriteOnly );
393 key.data = a1.data();
394 key.size = a1.size();
398 int rtn = dbp->cursor( dbp, 0, &cursor, 0 );
402 rtn = cursor->c_get( cursor, &key, &data, DB_SET );
405 cursors[ current++ ] = cursor;
407 else if ( rtn != DB_NOTFOUND) {
408 kdDebug() <<
"fetching cursor failed: " << db_strerror(rtn) << endl;
409 cursor->c_close(cursor);
413 kdDebug() <<
"creating cursor failed: " << db_strerror(rtn) << endl;
419 cursors[ current ] = 0;
421 if( current == args.size() ) {
424 int rtn = d->dbp->join( d->dbp, cursors, &join_curs, 0 );
428 std::memset( &key, 0,
sizeof(key) );
429 std::memset( &data, 0,
sizeof(data) );
431 while( join_curs->c_get(join_curs, &key, &data, 0) == 0 ) {
434 a2.setRawData( (
const char*) data.data, data.size );
435 TQDataStream s( a2, IO_ReadOnly );
438 a2.resetRawData( (
const char*) data.data, data.size );
442 join_curs->c_close( join_curs );
445 kdDebug() <<
"joining results failed: " << db_strerror(rtn) << endl;
459 TQCString Catalog::generateId()
463 asStr.sprintf(
"%05d", n++ );
void addIndex(const TQCString &name)
Catalog database - the persistent symbol store database.