(file) Return to SQLiteStore.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Repository

   1 martin 1.8 //%LICENSE////////////////////////////////////////////////////////////////
   2 martin 1.9 //
   3 martin 1.8 // Licensed to The Open Group (TOG) under one or more contributor license
   4            // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
   5            // this work for additional information regarding copyright ownership.
   6            // Each contributor licenses this file to you under the OpenPegasus Open
   7            // Source License; you may not use this file except in compliance with the
   8            // License.
   9 martin 1.9 //
  10 martin 1.8 // Permission is hereby granted, free of charge, to any person obtaining a
  11            // copy of this software and associated documentation files (the "Software"),
  12            // to deal in the Software without restriction, including without limitation
  13            // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  14            // and/or sell copies of the Software, and to permit persons to whom the
  15            // Software is furnished to do so, subject to the following conditions:
  16 martin 1.9 //
  17 martin 1.8 // The above copyright notice and this permission notice shall be included
  18            // in all copies or substantial portions of the Software.
  19 martin 1.9 //
  20 martin 1.8 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  21 martin 1.9 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22 martin 1.8 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  23            // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  24            // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  25            // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  26            // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27 martin 1.9 //
  28 martin 1.8 //////////////////////////////////////////////////////////////////////////
  29 kumpf  1.1 //
  30            //%/////////////////////////////////////////////////////////////////////////////
  31            
  32            #include <Pegasus/Common/Config.h>
  33 kumpf  1.6 #include <Pegasus/Common/CIMNameCast.h>
  34 kumpf  1.1 #include <cctype>
  35            #include <cstdio>
  36            
  37            #include <Pegasus/Common/InternalException.h>
  38            #include <Pegasus/Common/DeclContext.h>
  39            #include <Pegasus/Common/Resolver.h>
  40            #include <Pegasus/Common/System.h>
  41            #include <Pegasus/Common/Tracer.h>
  42            #include <Pegasus/Common/MessageLoader.h>
  43            #include <Pegasus/Common/FileSystem.h>
  44 kumpf  1.7 #include <Pegasus/Common/CIMNameCast.h>
  45 kumpf  1.1 #include "SQLiteStore.h"
  46            
  47 kumpf  1.7 // No build option to disable the association class cache is currently provided.
  48            #define USE_ASSOC_CLASS_CACHE
  49            
  50 kumpf  1.1 PEGASUS_NAMESPACE_BEGIN
  51            
  52            struct CloseSQLiteDb
  53            {
  54                void operator()(sqlite3* db)
  55                {
  56                    // This operator may be invoked automatically when an exception is
  57                    // thrown, so it should not throw an exception itself.
  58            
  59                    int rc = sqlite3_close(db);
  60            
  61                    // It is expected that all prepared statements are finalized before
  62                    // this operator is invoked.
  63                    PEGASUS_ASSERT(rc == SQLITE_OK);
  64                }
  65            };
  66            
  67            struct FinalizeSQLiteStatement
  68            {
  69                void operator()(sqlite3_stmt* stmt)
  70                {
  71 kumpf  1.1         if (stmt)
  72                    {
  73                        sqlite3_finalize(stmt);
  74                    }
  75                }
  76            };
  77            
  78 kumpf  1.2 
  79            ///////////////////////////////////////////////////////////////////////////////
  80            //
  81            // DbConnectionManager
  82            //
  83            ///////////////////////////////////////////////////////////////////////////////
  84            
  85            static const Uint32 MAX_CONNECTION_CACHE_SIZE = 4;
  86            
  87            DbConnectionManager::~DbConnectionManager()
  88            {
  89                for (Uint32 i = 0; i < _cache.size(); i++)
  90                {
  91                    sqlite3_close(_cache[i].db);
  92                }
  93            }
  94            
  95            sqlite3* DbConnectionManager::getDbConnection(const CIMNamespaceName& nameSpace)
  96            {
  97                AutoMutex lock(_cacheLock);
  98            
  99 kumpf  1.2     // Get the database connection handle from the cache, if available
 100            
 101                for (Uint32 i = 0; i < _cache.size(); i++)
 102                {
 103                    if (_cache[i].nameSpace == nameSpace)
 104                    {
 105                        sqlite3* db = _cache[i].db;
 106                        _cache.remove(i);
 107                        return db;
 108                    }
 109                }
 110            
 111                // Create a database connection handle for this namespace
 112            
 113                return openDb(getDbPath(nameSpace).getCString());
 114            }
 115            
 116            void DbConnectionManager::cacheDbConnection(
 117                const CIMNamespaceName& nameSpace,
 118                sqlite3* db)
 119            {
 120 kumpf  1.2     AutoMutex lock(_cacheLock);
 121            
 122                // Make room in the cache
 123            
 124                if (_cache.size() == MAX_CONNECTION_CACHE_SIZE)
 125                {
 126                    int rc = sqlite3_close(_cache[0].db);
 127            
 128                    // It is expected that all prepared statements are finalized.
 129                    PEGASUS_ASSERT(rc == SQLITE_OK);
 130            
 131                    _cache.remove(0);
 132                }
 133            
 134                _cache.append(CacheEntry(nameSpace, db));
 135            }
 136            
 137            String DbConnectionManager::getDbPath(const CIMNamespaceName& nameSpace)
 138            {
 139                String dbFileName = nameSpace.getString();
 140                dbFileName.toLower();
 141 kumpf  1.2 
 142                for (Uint32 i = 0; i < dbFileName.size(); i++)
 143                {
 144                    if (dbFileName[i] == '/')
 145                    {
 146                        dbFileName[i] = '#';
 147                    }
 148                }
 149            
 150                return _repositoryRoot + "/" + escapeStringEncoder(dbFileName) + ".db";
 151            }
 152            
 153            sqlite3* DbConnectionManager::openDb(const char* fileName)
 154            {
 155                sqlite3* db;
 156            
 157                int rc = sqlite3_open(fileName, &db);
 158                if (rc != SQLITE_OK)
 159                {
 160                    sqlite3_close(db);
 161                    throw Exception(MessageLoaderParms(
 162 kumpf  1.2             "Repository.SQLiteStore.DB_OPEN_ERROR",
 163                        "Failed to open SQLite repository database file \"$0\".",
 164                        fileName));
 165                }
 166            
 167                return db;
 168            }
 169            
 170            
 171            ///////////////////////////////////////////////////////////////////////////////
 172            //
 173            // DbConnection
 174            //
 175            ///////////////////////////////////////////////////////////////////////////////
 176            
 177            /**
 178                The DbConnection class provides scope-based management of database
 179                connection handles.  It provides a simple mechanism for closing a database
 180                connection and when an error occurs and caching it for reuse otherwise.
 181                The release() method must be called before the object is destructed to
 182                allow the connection to be reused.
 183 kumpf  1.2 */
 184            class DbConnection
 185            {
 186            public:
 187                DbConnection(DbConnectionManager& dbcm, const CIMNamespaceName& nameSpace)
 188                    : _dbcm(dbcm),
 189                      _nameSpace(nameSpace)
 190                {
 191                    _db = _dbcm.getDbConnection(nameSpace);
 192                }
 193            
 194                ~DbConnection()
 195                {
 196                    if (_db)
 197                    {
 198                        int rc = sqlite3_close(_db);
 199            
 200                        // It is expected that all prepared statements are finalized.
 201                        PEGASUS_ASSERT(rc == SQLITE_OK);
 202                    }
 203                }
 204 kumpf  1.2 
 205                sqlite3* get()
 206                {
 207                    return _db;
 208                }
 209            
 210                void release()
 211                {
 212                    _dbcm.cacheDbConnection(_nameSpace, _db);
 213                    _db = 0;
 214                }
 215            
 216            private:
 217                DbConnectionManager& _dbcm;
 218                CIMNamespaceName _nameSpace;
 219                sqlite3* _db;
 220            };
 221            
 222            
 223            ///////////////////////////////////////////////////////////////////////////////
 224            //
 225 kumpf  1.2 // SQLiteStore
 226            //
 227            ///////////////////////////////////////////////////////////////////////////////
 228            
 229 kumpf  1.1 // Size optimization:  Keep the exception throwing logic in a function so it
 230            // does not get replicated with each error check.
 231            static void _throwSQLiteOperationException(sqlite3* db)
 232            {
 233                throw Exception(MessageLoaderParms(
 234                    "Repository.SQLiteStore.DB_OP_ERROR",
 235                    "Repository SQLite database operation failed with error $0: $1",
 236                    sqlite3_errcode(db),
 237                    String((const Char16*)sqlite3_errmsg16(db))));
 238            }
 239            
 240            inline void CHECK_RC_OK(int rc, sqlite3* db)
 241            {
 242                if (rc != SQLITE_OK)
 243                {
 244                    _throwSQLiteOperationException(db);
 245                }
 246            }
 247            
 248            inline void CHECK_RC_DONE(int rc, sqlite3* db)
 249            {
 250 kumpf  1.1     if (rc != SQLITE_DONE)
 251                {
 252                    _throwSQLiteOperationException(db);
 253                }
 254            }
 255            
 256            Boolean SQLiteStore::isExistingRepository(const String& repositoryRoot)
 257            {
 258                return FileSystem::exists(repositoryRoot + "/root.db");
 259            }
 260            
 261            SQLiteStore::SQLiteStore(
 262                const String& repositoryRoot,
 263                ObjectStreamer* streamer)
 264 kumpf  1.2     : _dbcm(repositoryRoot)
 265 kumpf  1.1 {
 266                PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::SQLiteStore");
 267            
 268                // Create the repository directory if it does not already exist.
 269            
 270                if (!FileSystem::isDirectory(repositoryRoot))
 271                {
 272                    if (!FileSystem::makeDirectory(repositoryRoot))
 273                    {
 274                        PEG_METHOD_EXIT();
 275                        throw CannotCreateDirectory(repositoryRoot);
 276                    }
 277                }
 278            
 279                _repositoryRoot = repositoryRoot;
 280                _streamer = streamer;
 281            
 282                PEG_METHOD_EXIT();
 283            }
 284            
 285            SQLiteStore::~SQLiteStore()
 286 kumpf  1.1 {
 287            }
 288            
 289            void SQLiteStore::_execDbStatement(
 290                sqlite3* db,
 291                const char* sqlStatement)
 292            {
 293                PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::_execDbStatement");
 294            
 295                PEG_TRACE((TRC_REPOSITORY, Tracer::LEVEL4,
 296                    "Executing SQLite operation \"%s\"", sqlStatement));
 297            
 298                char* zErrMsg = 0;
 299                int rc = sqlite3_exec(db, sqlStatement, 0, 0, &zErrMsg);
 300                if (rc)
 301                {
 302                    PEG_TRACE((TRC_REPOSITORY, Tracer::LEVEL1,
 303                        "SQLite operation \"%s\" failed with error code %d: %s",
 304                        sqlStatement,
 305                        rc,
 306                        zErrMsg));
 307 kumpf  1.1         MessageLoaderParms parms(
 308                        "Repository.SQLiteStore.DB_OP_ERROR",
 309                        "Repository SQLite database operation failed with error $0: $1",
 310                        rc,
 311                        zErrMsg);
 312                    sqlite3_free(zErrMsg);
 313                    PEG_METHOD_EXIT();
 314                    throw Exception(parms);
 315                }
 316            
 317                PEG_METHOD_EXIT();
 318            }
 319            
 320            void SQLiteStore::_initSchema(sqlite3* db)
 321            {
 322                PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::_initSchema");
 323            
 324                // The NamespaceTable contains a single row describing the namespace
 325                // corresponding to the database file.
 326                _execDbStatement(
 327                    db,
 328 kumpf  1.1         "CREATE TABLE NamespaceTable("
 329                        "nsname TEXT PRIMARY KEY NOT NULL,"
 330                        "shareable INTEGER NOT NULL,"
 331                        "updatesallowed INTEGER NOT NULL,"
 332                        "parentnsname TEXT NOT NULL,"
 333                        "remoteinfo TEXT NOT NULL);");
 334            
 335                _execDbStatement(
 336                    db,
 337                    "CREATE TABLE QualifierTable("
 338                        "qualname TEXT NOT NULL,"
 339                        "normqualname TEXT PRIMARY KEY NOT NULL,"
 340                        "rep BLOB NOT NULL);");
 341            
 342                _execDbStatement(
 343                    db,
 344                    "CREATE TABLE ClassTable("
 345                        "classname TEXT NOT NULL,"
 346                        "normclassname TEXT PRIMARY KEY NOT NULL,"
 347                        "superclassname TEXT NOT NULL,"
 348                        "rep BLOB NOT NULL);");
 349 kumpf  1.1 
 350                _execDbStatement(
 351                    db,
 352                    "CREATE TABLE ClassAssocTable("
 353                        "assocclassname TEXT NOT NULL,"
 354                        "normassocclassname TEXT NOT NULL,"
 355                        "normfromclassname TEXT NOT NULL,"
 356                        "normfrompropname TEXT NOT NULL,"
 357                        "toclassname TEXT NOT NULL,"
 358                        "normtoclassname TEXT NOT NULL,"
 359                        "normtopropname TEXT NOT NULL,"
 360                        "PRIMARY KEY("
 361                            "normassocclassname, normfrompropname, normtopropname));");
 362            
 363                _execDbStatement(
 364                    db,
 365                    "CREATE TABLE InstanceTable("
 366                        "normclassname TEXT NOT NULL,"
 367                        "instname TEXT NOT NULL,"
 368                        "norminstname TEXT PRIMARY KEY NOT NULL,"
 369                        "rep BLOB NOT NULL);");
 370 kumpf  1.1 
 371                _execDbStatement(
 372                    db,
 373                    "CREATE TABLE InstanceAssocTable("
 374                        "associnstname TEXT NOT NULL,"
 375                        "normassocinstname TEXT NOT NULL,"
 376                        "normassocclassname TEXT NOT NULL,"
 377                        "normfrominstname TEXT NOT NULL,"
 378                        "normfrompropname TEXT NOT NULL,"
 379                        "toinstname TEXT NOT NULL,"
 380                        "normtoclassname TEXT NOT NULL,"
 381                        "normtopropname TEXT NOT NULL,"
 382                        "PRIMARY KEY("
 383                            "normassocinstname, normfrompropname, normtopropname));");
 384            
 385                PEG_METHOD_EXIT();
 386            }
 387            
 388            void SQLiteStore::_beginTransaction(sqlite3* db)
 389            {
 390                _execDbStatement(db, "BEGIN;");
 391 kumpf  1.1 }
 392            
 393            void SQLiteStore::_commitTransaction(sqlite3* db)
 394            {
 395                _execDbStatement(db, "COMMIT;");
 396            }
 397            
 398            Array<NamespaceDefinition> SQLiteStore::enumerateNameSpaces()
 399            {
 400                PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::enumerateNameSpaces");
 401            
 402                Array<NamespaceDefinition> nameSpaces;
 403            
 404                Array<String> dbFileNames;
 405                if (!FileSystem::glob(_repositoryRoot, "*.db", dbFileNames))
 406                {
 407                    throw CannotOpenDirectory(_repositoryRoot);
 408                }
 409            
 410                const char* sqlStatement = "SELECT nsname, shareable, updatesallowed, "
 411                    "parentnsname, remoteinfo FROM NamespaceTable;";
 412 kumpf  1.1 
 413                for (Uint32 i = 0; i < dbFileNames.size(); i++)
 414                {
 415 kumpf  1.2         AutoPtr<sqlite3, CloseSQLiteDb> db(DbConnectionManager::openDb(
 416                        (_repositoryRoot + "/" + dbFileNames[i]).getCString()));
 417 kumpf  1.1 
 418                    sqlite3_stmt* stmt = 0;
 419                    CHECK_RC_OK(
 420                        sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 421                        db.get());
 422                    AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 423            
 424                    int rc = sqlite3_step(stmt);
 425            
 426                    if (rc == SQLITE_ROW)
 427                    {
 428                        NamespaceDefinition nsdef(String(
 429                            (const Char16*) sqlite3_column_text16(stmt, 0),
 430                            (Uint32) sqlite3_column_bytes16(stmt, 0) / 2));
 431                        nsdef.shareable = (Boolean) sqlite3_column_int(stmt, 1);
 432                        nsdef.updatesAllowed = (Boolean) sqlite3_column_int(stmt, 2);
 433                        String parentNameSpace = String(
 434                            (const Char16*) sqlite3_column_text16(stmt, 3),
 435                            (Uint32) sqlite3_column_bytes16(stmt, 3) / 2);
 436                        if (parentNameSpace.size())
 437                        {
 438 kumpf  1.1                 nsdef.parentNameSpace = parentNameSpace;
 439                        }
 440                        nsdef.remoteInfo = String(
 441                            (const Char16*) sqlite3_column_text16(stmt, 4),
 442                            (Uint32) sqlite3_column_bytes16(stmt, 4) / 2);
 443                        nameSpaces.append(nsdef);
 444                    }
 445                    else
 446                    {
 447                        // There should always be one entry in the table.  This namespace
 448                        // must be corrupt.  Skip it.
 449                        PEG_TRACE((TRC_REPOSITORY, Tracer::LEVEL1,
 450                            "Corrupt namespace database %s",
 451                            (const char*) dbFileNames[i].getCString()));
 452                    }
 453                }
 454            
 455                PEG_METHOD_EXIT();
 456                return nameSpaces;
 457            }
 458            
 459 kumpf  1.1 void SQLiteStore::createNameSpace(
 460                const CIMNamespaceName& nameSpace,
 461                Boolean shareable,
 462                Boolean updatesAllowed,
 463 venkat.puvvada 1.4     const String& parentNameSpace,
 464                        const String& remoteInfo)
 465 kumpf          1.1 {
 466                        PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::createNameSpace");
 467                    
 468 kumpf          1.2     String dbPath = _dbcm.getDbPath(nameSpace);
 469 kumpf          1.1 
 470                        if (FileSystem::exists(dbPath))
 471                        {
 472                            throw Exception(MessageLoaderParms(
 473                                "Repository.SQLiteStore.DB_FILE_ALREADY_EXISTS",
 474                                "Cannot create namespace $0: SQLite database file \"$1\" already "
 475                                    "exists in the repository."));
 476                        }
 477                    
 478                        try
 479                        {
 480 kumpf          1.2         AutoPtr<sqlite3, CloseSQLiteDb> db(
 481                                DbConnectionManager::openDb(dbPath.getCString()));
 482 kumpf          1.1 
 483                            _initSchema(db.get());
 484                    
 485                            const char* sqlStatement =
 486                                "INSERT INTO NamespaceTable VALUES(?,?,?,?,?);";
 487                    
 488                            sqlite3_stmt* stmt = 0;
 489                            CHECK_RC_OK(
 490                                sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 491                                db.get());
 492                            AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 493                    
 494                            String ns = nameSpace.getString();
 495                    
 496                            CHECK_RC_OK(
 497                                sqlite3_bind_text16(
 498                                    stmt, 1, ns.getChar16Data(), ns.size() * 2, SQLITE_STATIC),
 499                                db.get());
 500                            CHECK_RC_OK(
 501                                sqlite3_bind_int(stmt, 2, shareable? 1 : 0), db.get());
 502                            CHECK_RC_OK(
 503 kumpf          1.1             sqlite3_bind_int(stmt, 3, updatesAllowed? 1 : 0), db.get());
 504                            CHECK_RC_OK(
 505                                sqlite3_bind_text16(
 506                                    stmt,
 507                                    4,
 508                                    parentNameSpace.getChar16Data(),
 509                                    parentNameSpace.size() * 2,
 510                                    SQLITE_STATIC),
 511                                db.get());
 512 venkat.puvvada 1.4 
 513                           String remoteId;
 514                    #ifdef PEGASUS_ENABLE_REMOTE_CMPI
 515                           if (remoteInfo.size())
 516                           {
 517                               remoteId.append("r10");
 518                               remoteId.append(remoteInfo);
 519                           }
 520                    #endif
 521 kumpf          1.1         CHECK_RC_OK(
 522                                sqlite3_bind_text16(
 523                                    stmt,
 524                                    5,
 525 venkat.puvvada 1.4                 remoteId.getChar16Data(),
 526                                    remoteId.size() * 2,
 527 kumpf          1.1                 SQLITE_STATIC),
 528                                db.get());
 529                    
 530                            CHECK_RC_DONE(sqlite3_step(stmt), db.get());
 531                        }
 532                        catch (...)
 533                        {
 534                            // Do not leave a partially created database file
 535                            FileSystem::removeFile(dbPath);
 536                            PEG_METHOD_EXIT();
 537                            throw;
 538                        }
 539                    
 540                        PEG_METHOD_EXIT();
 541                    }
 542                    
 543                    void SQLiteStore::modifyNameSpace(
 544                        const CIMNamespaceName& nameSpace,
 545                        Boolean shareable,
 546                        Boolean updatesAllowed)
 547                    {
 548 kumpf          1.1     PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::modifyNameSpace");
 549                    
 550 kumpf          1.2     DbConnection db(_dbcm, nameSpace);
 551 kumpf          1.1 
 552                        // The NamespaceTable contains only a single row, so no WHERE clause is
 553                        // needed.
 554                        const char* sqlStatement = "UPDATE NamespaceTable SET shareable=?, "
 555                            "updatesallowed=?;";
 556                    
 557                        sqlite3_stmt* stmt = 0;
 558                        CHECK_RC_OK(
 559                            sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 560                            db.get());
 561                        AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 562                    
 563                        CHECK_RC_OK(sqlite3_bind_int(stmt, 1, shareable? 1 : 0), db.get());
 564                        CHECK_RC_OK(sqlite3_bind_int(stmt, 2, updatesAllowed? 1 : 0), db.get());
 565                    
 566                        CHECK_RC_DONE(sqlite3_step(stmt), db.get());
 567                    
 568 kumpf          1.3     stmtDestroyer.reset();
 569 kumpf          1.2     db.release();
 570                    
 571 kumpf          1.1     PEG_METHOD_EXIT();
 572                    }
 573                    
 574 rohini.deshpande 1.12 void SQLiteStore::modifyNameSpaceName(
 575                           const CIMNamespaceName& nameSpace,
 576                           const CIMNamespaceName& newNameSpaceName)
 577                       {
 578                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::modifyNameSpaceName");
 579                           
 580                           String dbPath = _dbcm.getDbPath(nameSpace);
 581                           String dbPathnew = _dbcm.getDbPath(newNameSpaceName);
 582                          
 583                           DbConnection db(_dbcm, nameSpace);
 584                       
 585                           String ns = newNameSpaceName.getString();
 586                           sqlite3_stmt* stmt = 0;
 587                       
 588                           // The NamespaceTable contains only a single row, so no WHERE clause is
 589                           // needed.
 590                           const char* sqlStatement = "UPDATE NamespaceTable SET nsname=?;";
 591                       
 592                           CHECK_RC_OK(
 593                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 594                               db.get());
 595 rohini.deshpande 1.12     AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 596                       
 597                           CHECK_RC_OK(
 598                                   sqlite3_bind_text16(
 599                                       stmt, 1, ns.getChar16Data(), ns.size() * 2, SQLITE_STATIC),
 600                                   db.get());
 601                           CHECK_RC_DONE(sqlite3_step(stmt), db.get());
 602                       
 603                           stmtDestroyer.reset();
 604                           db.release();
 605                           FileSystem::renameFile(dbPath, dbPathnew);
 606                       
 607                           PEG_METHOD_EXIT();
 608                       }
 609 kumpf            1.1  void SQLiteStore::deleteNameSpace(const CIMNamespaceName& nameSpace)
 610                       {
 611                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::deleteNameSpace");
 612                       
 613 kumpf            1.2      String dbPath = _dbcm.getDbPath(nameSpace);
 614 kumpf            1.1  
 615                           if (!FileSystem::removeFile(dbPath))
 616                           {
 617                               throw CannotRemoveFile(dbPath);
 618                           }
 619                       
 620                           PEG_METHOD_EXIT();
 621                       }
 622                       
 623                       Boolean SQLiteStore::isNameSpaceEmpty(const CIMNamespaceName& nameSpace)
 624                       {
 625                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::isNameSpaceEmpty");
 626                       
 627                           Boolean isEmpty =
 628                               ((enumerateQualifiers(nameSpace).size() == 0) &&
 629                                (enumerateClassNames(nameSpace).size() == 0));
 630                       
 631                           PEG_METHOD_EXIT();
 632                           return isEmpty;
 633                       }
 634                       
 635 kumpf            1.1  Array<CIMQualifierDecl> SQLiteStore::enumerateQualifiers(
 636                           const CIMNamespaceName& nameSpace)
 637                       {
 638                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::enumerateQualifiers");
 639                       
 640                           Array<CIMQualifierDecl> qualifiers;
 641 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
 642 kumpf            1.1  
 643                           const char* sqlStatement = "SELECT rep FROM QualifierTable;";
 644                       
 645                           sqlite3_stmt* stmt = 0;
 646                           CHECK_RC_OK(
 647                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 648                               db.get());
 649                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 650                       
 651                           int rc;
 652                           while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
 653                           {
 654                               Buffer data(
 655                                   (const char*)sqlite3_column_blob(stmt, 0),
 656                                   (Uint32)sqlite3_column_bytes(stmt, 0));
 657                               CIMQualifierDecl qualifier;
 658                               _streamer->decode(data, 0, qualifier);
 659                               qualifiers.append(qualifier);
 660                           }
 661                       
 662                           CHECK_RC_DONE(rc, db.get());
 663 kumpf            1.1  
 664 kumpf            1.3      stmtDestroyer.reset();
 665 kumpf            1.2      db.release();
 666                       
 667 kumpf            1.1      PEG_METHOD_EXIT();
 668                           return qualifiers;
 669                       }
 670                       
 671                       CIMQualifierDecl SQLiteStore::getQualifier(
 672                           const CIMNamespaceName& nameSpace,
 673                           const CIMName& qualifierName)
 674                       {
 675                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::getQualifier");
 676                       
 677                           CIMQualifierDecl qualifier;
 678                       
 679 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
 680 kumpf            1.1  
 681                           const char* sqlStatement = "SELECT rep FROM QualifierTable "
 682                               "WHERE normqualname=?;";
 683                       
 684                           sqlite3_stmt* stmt = 0;
 685                           CHECK_RC_OK(
 686                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 687                               db.get());
 688                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 689                       
 690                           String qualname = _getNormalizedName(qualifierName);
 691                       
 692                           CHECK_RC_OK(
 693                               sqlite3_bind_text16(
 694                                   stmt,
 695                                   1,
 696                                   qualname.getChar16Data(),
 697                                   qualname.size() * 2,
 698                                   SQLITE_STATIC),
 699                               db.get());
 700                       
 701 kumpf            1.1      int rc;
 702                           rc = sqlite3_step(stmt);
 703                       
 704                           if (rc == SQLITE_ROW)
 705                           {
 706                               Buffer data(
 707                                   (const char*)sqlite3_column_blob(stmt, 0),
 708                                   (Uint32)sqlite3_column_bytes(stmt, 0));
 709                               _streamer->decode(data, 0, qualifier);
 710                           }
 711                           else
 712                           {
 713 kumpf            1.2          // SQLITE_DONE here means the qualifier is not found
 714 kumpf            1.1          CHECK_RC_DONE(rc, db.get());
 715 kumpf            1.2      }
 716 kumpf            1.1  
 717 kumpf            1.3      stmtDestroyer.reset();
 718 kumpf            1.2      db.release();
 719 kumpf            1.1  
 720                           PEG_METHOD_EXIT();
 721                           return qualifier;
 722                       }
 723                       
 724                       void SQLiteStore::setQualifier(
 725                           const CIMNamespaceName& nameSpace,
 726                           const CIMQualifierDecl& qualifierDecl)
 727                       {
 728                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::setQualifier");
 729                       
 730                           // Note: This is a relatively inefficient way to determine the existence
 731                           // of a qualifier, but setting a qualifier is expected to be an infrequent
 732                           // operation.
 733 kumpf            1.10     if (!getQualifier(nameSpace, qualifierDecl.getName()).isUninitialized())
 734                           {
 735                               PEG_METHOD_EXIT();
 736                               throw PEGASUS_CIM_EXCEPTION(
 737                                   CIM_ERR_NOT_SUPPORTED, qualifierDecl.getName().getString());
 738                           }
 739 kumpf            1.2  
 740                           DbConnection db(_dbcm, nameSpace);
 741                       
 742 kumpf            1.10     // Qualifier does not exist yet; create it
 743                           const char* sqlStatement =
 744                               "INSERT INTO QualifierTable VALUES(?,?,?);";
 745 kumpf            1.1  
 746 kumpf            1.10     sqlite3_stmt* stmt = 0;
 747                           CHECK_RC_OK(
 748                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 749                               db.get());
 750                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 751 kumpf            1.1  
 752 kumpf            1.10     String qualname = qualifierDecl.getName().getString();
 753                           String normqualname = _getNormalizedName(qualifierDecl.getName());
 754                           Buffer data;
 755                           _streamer->encode(data, qualifierDecl);
 756 kumpf            1.1  
 757 kumpf            1.10     CHECK_RC_OK(
 758                               sqlite3_bind_text16(
 759                                   stmt,
 760                                   1,
 761                                   qualname.getChar16Data(),
 762                                   qualname.size() * 2,
 763                                   SQLITE_STATIC),
 764                               db.get());
 765                           CHECK_RC_OK(
 766                               sqlite3_bind_text16(
 767                                   stmt,
 768                                   2,
 769                                   normqualname.getChar16Data(),
 770                                   normqualname.size() * 2,
 771                                   SQLITE_STATIC),
 772                               db.get());
 773                           CHECK_RC_OK(
 774                               sqlite3_bind_blob(
 775                                   stmt, 3, data.getData(), data.size(), SQLITE_STATIC),
 776                               db.get());
 777 kumpf            1.1  
 778 kumpf            1.10     CHECK_RC_DONE(sqlite3_step(stmt), db.get());
 779 kumpf            1.1  
 780 kumpf            1.2      db.release();
 781                       
 782 kumpf            1.1      PEG_METHOD_EXIT();
 783                       }
 784                       
 785                       void SQLiteStore::deleteQualifier(
 786                           const CIMNamespaceName& nameSpace,
 787                           const CIMName& qualifierName)
 788                       {
 789                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::deleteQualifier");
 790                       
 791                           // Note: This is a relatively inefficient way to verify the existence of a
 792                           // qualifier, but deleting a qualifier is expected to be an infrequent
 793                           // operation.
 794                           if (getQualifier(nameSpace, qualifierName).isUninitialized())
 795                           {
 796                               PEG_METHOD_EXIT();
 797                               throw PEGASUS_CIM_EXCEPTION(
 798                                   CIM_ERR_NOT_FOUND, qualifierName.getString());
 799                           }
 800                       
 801 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
 802 kumpf            1.1  
 803                           const char* sqlStatement = "DELETE FROM QualifierTable "
 804                               "WHERE normqualname=?;";
 805                       
 806                           sqlite3_stmt* stmt = 0;
 807                           CHECK_RC_OK(
 808                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 809                               db.get());
 810                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 811                       
 812                           String qualname = _getNormalizedName(qualifierName);
 813                       
 814                           CHECK_RC_OK(
 815                               sqlite3_bind_text16(
 816                                   stmt,
 817                                   1,
 818                                   qualname.getChar16Data(),
 819                                   qualname.size() * 2,
 820                                   SQLITE_STATIC),
 821                               db.get());
 822                       
 823 kumpf            1.1      CHECK_RC_DONE(sqlite3_step(stmt), db.get());
 824                       
 825 kumpf            1.3      stmtDestroyer.reset();
 826 kumpf            1.2      db.release();
 827                       
 828 kumpf            1.1      PEG_METHOD_EXIT();
 829                       }
 830                       
 831                       Array<Pair<String, String> > SQLiteStore::enumerateClassNames(
 832                           const CIMNamespaceName& nameSpace)
 833                       {
 834                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::enumerateClassNames");
 835                       
 836                           Array<Pair<String, String> > classList;
 837 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
 838 kumpf            1.1  
 839                           const char* sqlStatement = "SELECT classname, superclassname "
 840                               "FROM ClassTable;";
 841                       
 842                           sqlite3_stmt* stmt = 0;
 843                           CHECK_RC_OK(
 844                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 845                               db.get());
 846                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 847                       
 848                           int rc;
 849                           while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
 850                           {
 851                               classList.append(Pair<String, String>(
 852                                   String(
 853                                       (const Char16*)sqlite3_column_text16(stmt, 0),
 854                                       (Uint32)sqlite3_column_bytes16(stmt, 0) / 2),
 855                                   String(
 856                                       (const Char16*)sqlite3_column_text16(stmt, 1),
 857                                       (Uint32)sqlite3_column_bytes16(stmt, 1) / 2)));
 858                           }
 859 kumpf            1.1  
 860                           CHECK_RC_DONE(rc, db.get());
 861                       
 862 kumpf            1.3      stmtDestroyer.reset();
 863 kumpf            1.2      db.release();
 864                       
 865 kumpf            1.1      PEG_METHOD_EXIT();
 866                           return classList;
 867                       }
 868                       
 869                       CIMClass SQLiteStore::getClass(
 870                           const CIMNamespaceName& nameSpace,
 871                           const CIMName& className,
 872                           const CIMName& superClassName)
 873                       {
 874                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::getClass");
 875                       
 876                           CIMClass cimClass;
 877 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
 878 kumpf            1.1  
 879                           const char* sqlStatement = "SELECT rep FROM ClassTable "
 880                               "WHERE normclassname=?;";
 881                       
 882                           sqlite3_stmt* stmt = 0;
 883                           CHECK_RC_OK(
 884                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 885                               db.get());
 886                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 887                       
 888                           String classname = _getNormalizedName(className);
 889                       
 890                           CHECK_RC_OK(
 891                               sqlite3_bind_text16(
 892                                   stmt,
 893                                   1,
 894                                   classname.getChar16Data(),
 895                                   classname.size() * 2,
 896                                   SQLITE_STATIC),
 897                               db.get());
 898                       
 899 kumpf            1.1      int rc = sqlite3_step(stmt);
 900                       
 901 kumpf            1.3      if (rc != SQLITE_ROW)
 902 kumpf            1.1      {
 903                               CHECK_RC_DONE(rc, db.get());
 904                       
 905 kumpf            1.3          stmtDestroyer.reset();
 906 kumpf            1.2          db.release();
 907                       
 908 kumpf            1.1          PEG_METHOD_EXIT();
 909                               throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, className.getString());
 910                           }
 911                       
 912 kumpf            1.3      Buffer data(
 913                               (const char*)sqlite3_column_blob(stmt, 0),
 914                               (Uint32)sqlite3_column_bytes(stmt, 0));
 915                           _streamer->decode(data, 0, cimClass);
 916                       
 917                           PEGASUS_ASSERT(sqlite3_step(stmt) == SQLITE_DONE);
 918                       
 919                           stmtDestroyer.reset();
 920 kumpf            1.2      db.release();
 921                       
 922 kumpf            1.1      PEG_METHOD_EXIT();
 923                           return cimClass;
 924                       }
 925                       
 926                       void SQLiteStore::createClass(
 927                           const CIMNamespaceName& nameSpace,
 928                           const CIMClass& newClass,
 929                           const Array<ClassAssociation>& classAssocEntries)
 930                       {
 931                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::createClass");
 932                       
 933 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
 934 kumpf            1.1  
 935                           _beginTransaction(db.get());
 936                       
 937                           const char* sqlStatement = "INSERT INTO ClassTable VALUES(?,?,?,?);";
 938                       
 939                           sqlite3_stmt* stmt = 0;
 940                           CHECK_RC_OK(
 941                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
 942                               db.get());
 943                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
 944                       
 945                           String classname = newClass.getClassName().getString();
 946                           String normclassname = _getNormalizedName(newClass.getClassName());
 947                           String superclassname = newClass.getSuperClassName().getString();
 948                           Buffer data;
 949                           _streamer->encode(data, newClass);
 950                       
 951                           CHECK_RC_OK(
 952                               sqlite3_bind_text16(
 953                                   stmt,
 954                                   1,
 955 kumpf            1.1              classname.getChar16Data(),
 956                                   classname.size() * 2,
 957                                   SQLITE_STATIC),
 958                               db.get());
 959                           CHECK_RC_OK(
 960                               sqlite3_bind_text16(
 961                                   stmt,
 962                                   2,
 963                                   normclassname.getChar16Data(),
 964                                   normclassname.size() * 2,
 965                                   SQLITE_STATIC),
 966                               db.get());
 967                           CHECK_RC_OK(
 968                               sqlite3_bind_text16(
 969                                   stmt,
 970                                   3,
 971                                   superclassname.getChar16Data(),
 972                                   superclassname.size() * 2,
 973                                   SQLITE_STATIC),
 974                               db.get());
 975                           CHECK_RC_OK(
 976 kumpf            1.1          sqlite3_bind_blob(stmt, 4, data.getData(), data.size(), SQLITE_STATIC),
 977                               db.get());
 978                       
 979                           CHECK_RC_DONE(sqlite3_step(stmt), db.get());
 980                       
 981                           // Create the class association entries
 982                           if (classAssocEntries.size())
 983                           {
 984                               _addClassAssociationEntries(db.get(), nameSpace, classAssocEntries);
 985                           }
 986                       
 987                           _commitTransaction(db.get());
 988                       
 989 kumpf            1.3      stmtDestroyer.reset();
 990 kumpf            1.2      db.release();
 991                       
 992 kumpf            1.1      PEG_METHOD_EXIT();
 993                       }
 994                       
 995                       void SQLiteStore::modifyClass(
 996                           const CIMNamespaceName& nameSpace,
 997                           const CIMClass& modifiedClass,
 998                           const CIMName& oldSuperClassName,
 999                           Boolean isAssociation,
1000                           const Array<ClassAssociation>& classAssocEntries)
1001                       {
1002                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::modifyClass");
1003                       
1004 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1005 kumpf            1.1  
1006                           _beginTransaction(db.get());
1007                       
1008                           const char* sqlStatement = "UPDATE ClassTable SET rep=? "
1009                               "WHERE normclassname=?;";
1010                       
1011                           sqlite3_stmt* stmt = 0;
1012                           CHECK_RC_OK(
1013                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
1014                               db.get());
1015                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1016                       
1017                           Buffer data;
1018                           _streamer->encode(data, modifiedClass);
1019                           String normclassname = _getNormalizedName(modifiedClass.getClassName());
1020                       
1021                           CHECK_RC_OK(
1022                               sqlite3_bind_blob(stmt, 1, data.getData(), data.size(), SQLITE_STATIC),
1023                               db.get());
1024                           CHECK_RC_OK(
1025                               sqlite3_bind_text16(
1026 kumpf            1.1              stmt,
1027                                   2,
1028                                   normclassname.getChar16Data(),
1029                                   normclassname.size() * 2,
1030                                   SQLITE_STATIC),
1031                               db.get());
1032                       
1033                           CHECK_RC_DONE(sqlite3_step(stmt), db.get());
1034                       
1035                           //
1036                           // Update the association entries
1037                           //
1038                       
1039                           if (isAssociation)
1040                           {
1041                               _removeClassAssociationEntries(
1042                                   db.get(), nameSpace, modifiedClass.getClassName());
1043                               if (classAssocEntries.size())
1044                               {
1045                                   _addClassAssociationEntries(db.get(), nameSpace, classAssocEntries);
1046                               }
1047 kumpf            1.1      }
1048                       
1049                           _commitTransaction(db.get());
1050                       
1051 kumpf            1.3      stmtDestroyer.reset();
1052 kumpf            1.2      db.release();
1053                       
1054 kumpf            1.1      PEG_METHOD_EXIT();
1055                       }
1056                       
1057                       void SQLiteStore::deleteClass(
1058                           const CIMNamespaceName& nameSpace,
1059                           const CIMName& className,
1060                           const CIMName& superClassName,
1061                           Boolean isAssociation,
1062                           const Array<CIMNamespaceName>& dependentNameSpaceNames)
1063                       {
1064                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::deleteClass");
1065                       
1066                           // Note: This is a relatively inefficient way to verify the existence of a
1067                           // class, but deleting a class is expected to be an infrequent operation.
1068                           CIMClass dummy = getClass(nameSpace, className, superClassName);
1069                       
1070 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1071 kumpf            1.1  
1072                           _beginTransaction(db.get());
1073                       
1074                           const char* sqlStatement = "DELETE FROM ClassTable "
1075                               "WHERE normclassname=?;";
1076                       
1077                           sqlite3_stmt* stmt = 0;
1078                           CHECK_RC_OK(
1079                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
1080                               db.get());
1081                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1082                       
1083                           String normclassname = _getNormalizedName(className);
1084                       
1085                           CHECK_RC_OK(
1086                               sqlite3_bind_text16(
1087                                   stmt,
1088                                   1,
1089                                   normclassname.getChar16Data(),
1090                                   normclassname.size() * 2,
1091                                   SQLITE_STATIC),
1092 kumpf            1.1          db.get());
1093                       
1094                           CHECK_RC_DONE(sqlite3_step(stmt), db.get());
1095                       
1096                           //
1097                           // Remove association entries
1098                           //
1099                       
1100                           if (isAssociation)
1101                           {
1102                               _removeClassAssociationEntries(db.get(), nameSpace, className);
1103                           }
1104                       
1105                           _commitTransaction(db.get());
1106                       
1107 kumpf            1.3      stmtDestroyer.reset();
1108 kumpf            1.2      db.release();
1109                       
1110 kumpf            1.1      PEG_METHOD_EXIT();
1111                       }
1112                       
1113                       Array<CIMObjectPath> SQLiteStore::enumerateInstanceNamesForClass(
1114                           const CIMNamespaceName& nameSpace,
1115                           const CIMName& className)
1116                       {
1117                           PEG_METHOD_ENTER(TRC_REPOSITORY,
1118                               "SQLiteStore::enumerateInstanceNamesForClass");
1119                       
1120                           Array<CIMObjectPath> instanceNames;
1121 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1122 kumpf            1.1  
1123                           const char* sqlStatement = "SELECT instname FROM InstanceTable "
1124                               "WHERE normclassname=?;";
1125                       
1126                           sqlite3_stmt* stmt = 0;
1127                           CHECK_RC_OK(
1128                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
1129                               db.get());
1130                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1131                       
1132                           String classname = _getNormalizedName(className);
1133                       
1134                           CHECK_RC_OK(
1135                               sqlite3_bind_text16(
1136                                   stmt,
1137                                   1,
1138                                   classname.getChar16Data(),
1139                                   classname.size() * 2,
1140                                   SQLITE_STATIC),
1141                               db.get());
1142                       
1143 kumpf            1.1      int rc;
1144                           while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
1145                           {
1146                               instanceNames.append(CIMObjectPath(String(
1147                                   (const Char16*)sqlite3_column_text16(stmt, 0),
1148                                   (Uint32)sqlite3_column_bytes16(stmt, 0) / 2)));
1149                           }
1150                       
1151                           CHECK_RC_DONE(rc, db.get());
1152                       
1153 kumpf            1.3      stmtDestroyer.reset();
1154 kumpf            1.2      db.release();
1155                       
1156 kumpf            1.1      PEG_METHOD_EXIT();
1157                           return instanceNames;
1158                       }
1159                       
1160                       Array<CIMInstance> SQLiteStore::enumerateInstancesForClass(
1161                           const CIMNamespaceName& nameSpace,
1162                           const CIMName& className)
1163                       {
1164                           PEG_METHOD_ENTER(TRC_REPOSITORY,
1165                               "SQLiteStore::enumerateInstancesForClass");
1166                       
1167                           Array<CIMInstance> cimInstances;
1168                       
1169 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1170 kumpf            1.1  
1171                           const char* sqlStatement = "SELECT instname, rep FROM InstanceTable "
1172                               "WHERE normclassname=?;";
1173                       
1174                           sqlite3_stmt* stmt = 0;
1175                           CHECK_RC_OK(
1176                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
1177                               db.get());
1178                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1179                       
1180                           String classname = _getNormalizedName(className);
1181                       
1182                           CHECK_RC_OK(
1183                               sqlite3_bind_text16(
1184                                   stmt,
1185                                   1,
1186                                   classname.getChar16Data(),
1187                                   classname.size() * 2,
1188                                   SQLITE_STATIC),
1189                               db.get());
1190                       
1191 kumpf            1.1      int rc;
1192                           while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
1193                           {
1194                               CIMObjectPath instanceName = CIMObjectPath(String(
1195                                   (const Char16*)sqlite3_column_text16(stmt, 0),
1196                                   (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
1197                               Buffer data(
1198                                   (const char*)sqlite3_column_blob(stmt, 1),
1199                                   (Uint32)sqlite3_column_bytes(stmt, 1));
1200                       
1201                               CIMInstance cimInstance;
1202                               _streamer->decode(data, 0, cimInstance);
1203                               cimInstance.setPath(instanceName);
1204                               cimInstances.append(cimInstance);
1205                           }
1206                       
1207                           CHECK_RC_DONE(rc, db.get());
1208                       
1209 kumpf            1.3      stmtDestroyer.reset();
1210 kumpf            1.2      db.release();
1211                       
1212 kumpf            1.1      PEG_METHOD_EXIT();
1213                           return cimInstances;
1214                       }
1215                       
1216                       CIMInstance SQLiteStore::getInstance(
1217                           const CIMNamespaceName& nameSpace,
1218                           const CIMObjectPath& instanceName)
1219                       {
1220                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::getInstance");
1221                       
1222                           CIMInstance cimInstance;
1223                       
1224 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1225 kumpf            1.1  
1226                           const char* sqlStatement = "SELECT instname, rep FROM InstanceTable "
1227                               "WHERE norminstname=?;";
1228                       
1229                           sqlite3_stmt* stmt = 0;
1230                           CHECK_RC_OK(
1231                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
1232                               db.get());
1233                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1234                       
1235                           String norminstname = instanceName._toStringCanonical();
1236                       
1237                           CHECK_RC_OK(
1238                               sqlite3_bind_text16(
1239                                   stmt,
1240                                   1,
1241                                   norminstname.getChar16Data(),
1242                                   norminstname.size() * 2,
1243                                   SQLITE_STATIC),
1244                               db.get());
1245                       
1246 kumpf            1.1      int rc = sqlite3_step(stmt);
1247                       
1248 kumpf            1.3      if (rc != SQLITE_ROW)
1249 kumpf            1.1      {
1250                               CHECK_RC_DONE(rc, db.get());
1251                       
1252 kumpf            1.3          stmtDestroyer.reset();
1253 kumpf            1.2          db.release();
1254                       
1255 kumpf            1.1          PEG_METHOD_EXIT();
1256                               throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
1257                           }
1258                       
1259 kumpf            1.3      Buffer data(
1260                               (const char*)sqlite3_column_blob(stmt, 1),
1261                               (Uint32)sqlite3_column_bytes(stmt, 1));
1262                           _streamer->decode(data, 0, cimInstance);
1263                       
1264                           PEGASUS_ASSERT(sqlite3_step(stmt) == SQLITE_DONE);
1265                       
1266                           stmtDestroyer.reset();
1267 kumpf            1.2      db.release();
1268                       
1269 kumpf            1.1      PEG_METHOD_EXIT();
1270                           return cimInstance;
1271                       }
1272                       
1273                       void SQLiteStore::createInstance(
1274                           const CIMNamespaceName& nameSpace,
1275                           const CIMObjectPath& instanceName,
1276                           const CIMInstance& cimInstance,
1277                           const Array<InstanceAssociation>& instAssocEntries)
1278                       {
1279                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::createInstance");
1280                       
1281 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1282 kumpf            1.1  
1283                           _beginTransaction(db.get());
1284                       
1285                           const char* sqlStatement = "INSERT INTO InstanceTable VALUES(?,?,?,?);";
1286                       
1287                           sqlite3_stmt* stmt = 0;
1288                           CHECK_RC_OK(
1289                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
1290                               db.get());
1291                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1292                       
1293                           String classname = _getNormalizedName(cimInstance.getClassName());
1294                           String instname = instanceName.toString();
1295                           String norminstname = instanceName._toStringCanonical();
1296                           Buffer data;
1297                           _streamer->encode(data, cimInstance);
1298                       
1299                           CHECK_RC_OK(
1300                               sqlite3_bind_text16(
1301                                   stmt,
1302                                   1,
1303 kumpf            1.1              classname.getChar16Data(),
1304                                   classname.size() * 2,
1305                                   SQLITE_STATIC),
1306                               db.get());
1307                           CHECK_RC_OK(
1308                               sqlite3_bind_text16(
1309                                   stmt,
1310                                   2,
1311                                   instname.getChar16Data(),
1312                                   instname.size() * 2,
1313                                   SQLITE_STATIC),
1314                               db.get());
1315                           CHECK_RC_OK(
1316                               sqlite3_bind_text16(
1317                                   stmt,
1318                                   3,
1319                                   norminstname.getChar16Data(),
1320                                   norminstname.size() * 2,
1321                                   SQLITE_STATIC),
1322                               db.get());
1323                           CHECK_RC_OK(
1324 kumpf            1.1          sqlite3_bind_blob(stmt, 4, data.getData(), data.size(), SQLITE_STATIC),
1325                               db.get());
1326                       
1327                           CHECK_RC_DONE(sqlite3_step(stmt), db.get());
1328                       
1329                           //
1330                           // Create association entries if an association instance.
1331                           //
1332                       
1333                           if (instAssocEntries.size())
1334                           {
1335                               _addInstanceAssociationEntries(db.get(), nameSpace, instAssocEntries);
1336                           }
1337                       
1338                           _commitTransaction(db.get());
1339                       
1340 kumpf            1.3      stmtDestroyer.reset();
1341 kumpf            1.2      db.release();
1342                       
1343 kumpf            1.1      PEG_METHOD_EXIT();
1344                       }
1345                       
1346                       void SQLiteStore::modifyInstance(
1347                           const CIMNamespaceName& nameSpace,
1348                           const CIMObjectPath& instanceName,
1349                           const CIMInstance& cimInstance)
1350                       {
1351                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::modifyInstance");
1352                       
1353                           if (!instanceExists(nameSpace, instanceName))
1354                           {
1355                               PEG_METHOD_EXIT();
1356                               throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
1357                           }
1358                       
1359 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1360 kumpf            1.1  
1361                           const char* sqlStatement = "UPDATE InstanceTable SET rep=? "
1362                               "WHERE norminstname=?;";
1363                       
1364                           sqlite3_stmt* stmt = 0;
1365                           CHECK_RC_OK(
1366                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
1367                               db.get());
1368                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1369                       
1370                           Buffer data;
1371                           _streamer->encode(data, cimInstance);
1372                           String norminstname = instanceName._toStringCanonical();
1373                       
1374                           CHECK_RC_OK(
1375                               sqlite3_bind_blob(stmt, 1, data.getData(), data.size(), SQLITE_STATIC),
1376                               db.get());
1377                           CHECK_RC_OK(
1378                               sqlite3_bind_text16(
1379                                   stmt,
1380                                   2,
1381 kumpf            1.1              norminstname.getChar16Data(),
1382                                   norminstname.size() * 2,
1383                                   SQLITE_STATIC),
1384                               db.get());
1385                       
1386                           CHECK_RC_DONE(sqlite3_step(stmt), db.get());
1387                       
1388 kumpf            1.3      stmtDestroyer.reset();
1389 kumpf            1.2      db.release();
1390                       
1391 kumpf            1.1      PEG_METHOD_EXIT();
1392                       }
1393                       
1394                       void SQLiteStore::deleteInstance(
1395                           const CIMNamespaceName& nameSpace,
1396                           const CIMObjectPath& instanceName)
1397                       {
1398                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::deleteInstance");
1399                       
1400                           if (!instanceExists(nameSpace, instanceName))
1401                           {
1402                               throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
1403                           }
1404                       
1405 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1406 kumpf            1.1  
1407                           _beginTransaction(db.get());
1408                       
1409                           const char* sqlStatement = "DELETE FROM InstanceTable "
1410                               "WHERE norminstname=?;";
1411                       
1412                           sqlite3_stmt* stmt = 0;
1413                           CHECK_RC_OK(
1414                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
1415                               db.get());
1416                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1417                       
1418                           String norminstname = instanceName._toStringCanonical();
1419                       
1420                           CHECK_RC_OK(
1421                               sqlite3_bind_text16(
1422                                   stmt,
1423                                   1,
1424                                   norminstname.getChar16Data(),
1425                                   norminstname.size() * 2,
1426                                   SQLITE_STATIC),
1427 kumpf            1.1          db.get());
1428                       
1429                           CHECK_RC_DONE(sqlite3_step(stmt), db.get());
1430                       
1431                           //
1432                           // Delete from association table (if an assocation).
1433                           //
1434                       
1435                           _removeInstanceAssociationEntries(db.get(), nameSpace, instanceName);
1436                       
1437                           _commitTransaction(db.get());
1438                       
1439 kumpf            1.3      stmtDestroyer.reset();
1440 kumpf            1.2      db.release();
1441                       
1442 kumpf            1.1      PEG_METHOD_EXIT();
1443                       }
1444                       
1445                       Boolean SQLiteStore::instanceExists(
1446                           const CIMNamespaceName& nameSpace,
1447                           const CIMObjectPath& instanceName)
1448                       {
1449                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::instanceExists");
1450                       
1451 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1452 kumpf            1.1  
1453                           const char* sqlStatement = "SELECT instname FROM InstanceTable "
1454                               "WHERE norminstname=?;";
1455                       
1456                           sqlite3_stmt* stmt = 0;
1457                           CHECK_RC_OK(
1458                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
1459                               db.get());
1460                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1461                       
1462                           String norminstname = instanceName._toStringCanonical();
1463                       
1464                           CHECK_RC_OK(
1465                               sqlite3_bind_text16(
1466                                   stmt,
1467                                   1,
1468                                   norminstname.getChar16Data(),
1469                                   norminstname.size() * 2,
1470                                   SQLITE_STATIC),
1471                               db.get());
1472                       
1473 kumpf            1.1      int rc = sqlite3_step(stmt);
1474 kumpf            1.2      Boolean found = false;
1475 kumpf            1.1  
1476                           if (rc == SQLITE_ROW)
1477                           {
1478 kumpf            1.2          found = true;
1479                           }
1480                           else
1481                           {
1482                               CHECK_RC_DONE(rc, db.get());
1483 kumpf            1.1      }
1484                       
1485 kumpf            1.3      stmtDestroyer.reset();
1486 kumpf            1.2      db.release();
1487 kumpf            1.1  
1488                           PEG_METHOD_EXIT();
1489 kumpf            1.2      return found;
1490 kumpf            1.1  }
1491                       
1492 kumpf            1.7  void SQLiteStore::_initAssocClassCache(
1493                           const CIMNamespaceName& nameSpace,
1494                           AssocClassCache* cache)
1495                       {
1496                       #ifdef USE_ASSOC_CLASS_CACHE
1497                           PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::_initAssocClassCache");
1498                       
1499                           DbConnection db(_dbcm, nameSpace);
1500                       
1501                           const char* sqlStatement =
1502                               "SELECT assocclassname, normfromclassname, normfrompropname, "
1503                                   "toclassname, normtopropname FROM ClassAssocTable;";
1504                       
1505                           sqlite3_stmt* stmt = 0;
1506                           CHECK_RC_OK(
1507                               sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
1508                               db.get());
1509                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1510                       
1511                           int rc;
1512                           while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
1513 kumpf            1.7      {
1514                               ClassAssociation classAssociation;
1515                               classAssociation.assocClassName = CIMNameCast(String(
1516                                       (const Char16*)sqlite3_column_text16(stmt, 0),
1517                                       (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
1518                               classAssociation.fromClassName = CIMNameCast(String(
1519                                       (const Char16*)sqlite3_column_text16(stmt, 1),
1520                                       (Uint32)sqlite3_column_bytes16(stmt, 1) / 2));
1521                               classAssociation.fromPropertyName = CIMNameCast(String(
1522                                       (const Char16*)sqlite3_column_text16(stmt, 2),
1523                                       (Uint32)sqlite3_column_bytes16(stmt, 2) / 2));
1524                               classAssociation.toClassName = CIMNameCast(String(
1525                                       (const Char16*)sqlite3_column_text16(stmt, 3),
1526                                       (Uint32)sqlite3_column_bytes16(stmt, 3) / 2));
1527                               classAssociation.toPropertyName = CIMNameCast(String(
1528                                       (const Char16*)sqlite3_column_text16(stmt, 4),
1529                                       (Uint32)sqlite3_column_bytes16(stmt, 4) / 2));
1530                               cache->addRecord(classAssociation.fromClassName, classAssociation);
1531                           }
1532                       
1533                           CHECK_RC_DONE(rc, db.get());
1534 kumpf            1.7  
1535                           cache->setActive(true);
1536                       
1537                           stmtDestroyer.reset();
1538                           db.release();
1539                       
1540                           PEG_METHOD_EXIT();
1541                       #endif
1542                       }
1543                       
1544 kumpf            1.1  void SQLiteStore::_addClassAssociationEntries(
1545                           sqlite3* db,
1546                           const CIMNamespaceName& nameSpace,
1547                           const Array<ClassAssociation>& classAssocEntries)
1548                       {
1549                           PEG_METHOD_ENTER(TRC_REPOSITORY,
1550                               "SQLiteStore::_addClassAssociationEntries");
1551                       
1552                           const char* sqlStatement =
1553                               "INSERT INTO ClassAssocTable VALUES(?,?,?,?,?,?,?);";
1554                       
1555                           sqlite3_stmt* stmt = 0;
1556                           CHECK_RC_OK(
1557                               sqlite3_prepare_v2(db, sqlStatement, -1, &stmt, 0),
1558                               db);
1559                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1560                       
1561                           for (Uint32 i = 0; i < classAssocEntries.size(); i++)
1562                           {
1563                               String assocclassname =
1564                                   classAssocEntries[i].assocClassName.getString();
1565 kumpf            1.1          String normassocclassname = _getNormalizedName(
1566                                   classAssocEntries[i].assocClassName);
1567                               String normfromclassname = _getNormalizedName(
1568                                   classAssocEntries[i].fromClassName);
1569                               String normfrompropname = _getNormalizedName(
1570                                   classAssocEntries[i].fromPropertyName);
1571                               String toclassname =
1572                                   classAssocEntries[i].toClassName.getString();
1573                               String normtoclassname = _getNormalizedName(
1574                                   classAssocEntries[i].toClassName);
1575                               String normtopropname = _getNormalizedName(
1576                                   classAssocEntries[i].toPropertyName);
1577                       
1578                               CHECK_RC_OK(
1579                                   sqlite3_bind_text16(
1580                                       stmt,
1581                                       1,
1582                                       assocclassname.getChar16Data(),
1583                                       assocclassname.size() * 2,
1584                                       SQLITE_STATIC),
1585                                   db);
1586 kumpf            1.1          CHECK_RC_OK(
1587                                   sqlite3_bind_text16(
1588                                       stmt,
1589                                       2,
1590                                       normassocclassname.getChar16Data(),
1591                                       normassocclassname.size() * 2,
1592                                       SQLITE_STATIC),
1593                                   db);
1594                               CHECK_RC_OK(
1595                                   sqlite3_bind_text16(
1596                                       stmt,
1597                                       3,
1598                                       normfromclassname.getChar16Data(),
1599                                       normfromclassname.size() * 2,
1600                                       SQLITE_STATIC),
1601                                   db);
1602                               CHECK_RC_OK(
1603                                   sqlite3_bind_text16(
1604                                       stmt,
1605                                       4,
1606                                       normfrompropname.getChar16Data(),
1607 kumpf            1.1                  normfrompropname.size() * 2,
1608                                       SQLITE_STATIC),
1609                                   db);
1610                               CHECK_RC_OK(
1611                                   sqlite3_bind_text16(
1612                                       stmt,
1613                                       5,
1614                                       toclassname.getChar16Data(),
1615                                       toclassname.size() * 2,
1616                                       SQLITE_STATIC),
1617                                   db);
1618                               CHECK_RC_OK(
1619                                   sqlite3_bind_text16(
1620                                       stmt,
1621                                       6,
1622                                       normtoclassname.getChar16Data(),
1623                                       normtoclassname.size() * 2,
1624                                       SQLITE_STATIC),
1625                                   db);
1626                               CHECK_RC_OK(
1627                                   sqlite3_bind_text16(
1628 kumpf            1.1                  stmt,
1629                                       7,
1630                                       normtopropname.getChar16Data(),
1631                                       normtopropname.size() * 2,
1632                                       SQLITE_STATIC),
1633                                   db);
1634                       
1635                               CHECK_RC_DONE(sqlite3_step(stmt), db);
1636                       
1637                               CHECK_RC_OK(sqlite3_reset(stmt), db);
1638                       
1639                               CHECK_RC_OK(sqlite3_clear_bindings(stmt), db);
1640                           }
1641                       
1642 kumpf            1.7  #ifdef USE_ASSOC_CLASS_CACHE
1643                       
1644                           String assocClassCacheName = nameSpace.getString();
1645                           assocClassCacheName.toLower();
1646                           AssocClassCache* cache =
1647                               _assocClassCacheManager.getAssocClassCache(assocClassCacheName);
1648                       
1649                           if (cache->isActive())
1650                           {
1651                               for (Uint32 i = 0; i < classAssocEntries.size(); i++)
1652                               {
1653                                   cache->addRecord(
1654                                       classAssocEntries[i].fromClassName, classAssocEntries[i]);
1655                               }
1656                           }
1657                       
1658                       #endif
1659                       
1660 kumpf            1.1      PEG_METHOD_EXIT();
1661                       }
1662                       
1663                       void SQLiteStore::_removeClassAssociationEntries(
1664                           sqlite3* db,
1665                           const CIMNamespaceName& nameSpace,
1666                           const CIMName& assocClassName)
1667                       {
1668                           PEG_METHOD_ENTER(TRC_REPOSITORY,
1669                               "SQLiteStore::_removeClassAssociationEntries");
1670                       
1671                           const char* sqlStatement = "DELETE FROM ClassAssocTable "
1672                               "WHERE normassocclassname=?;";
1673                       
1674                           sqlite3_stmt* stmt = 0;
1675                           CHECK_RC_OK(
1676                               sqlite3_prepare_v2(db, sqlStatement, -1, &stmt, 0),
1677                               db);
1678                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1679                       
1680                           String normassocclassname = _getNormalizedName(assocClassName);
1681 kumpf            1.1  
1682                           CHECK_RC_OK(
1683                               sqlite3_bind_text16(
1684                                   stmt,
1685                                   1,
1686                                   normassocclassname.getChar16Data(),
1687                                   normassocclassname.size() * 2,
1688                                   SQLITE_STATIC),
1689                               db);
1690                       
1691                           CHECK_RC_DONE(sqlite3_step(stmt), db);
1692                       
1693 kumpf            1.7  #ifdef USE_ASSOC_CLASS_CACHE
1694                       
1695                           String assocClassCacheName = nameSpace.getString();
1696                           assocClassCacheName.toLower();
1697                           AssocClassCache* cache =
1698                               _assocClassCacheManager.getAssocClassCache(assocClassCacheName);
1699                       
1700                           if (cache->isActive())
1701                           {
1702                               cache->removeAssocClassRecords(assocClassName);
1703                           }
1704                       
1705                       #endif
1706                       
1707 kumpf            1.1      PEG_METHOD_EXIT();
1708                       }
1709                       
1710                       void SQLiteStore::getClassAssociatorNames(
1711                           const CIMNamespaceName& nameSpace,
1712                           const Array<CIMName>& classList,
1713                           const Array<CIMName>& assocClassList,
1714                           const Array<CIMName>& resultClassList,
1715                           const String& role,
1716                           const String& resultRole,
1717                           Array<String>& associatorNames)
1718                       {
1719                           PEG_METHOD_ENTER(TRC_REPOSITORY,
1720                               "SQLiteStore::getClassAssociatorNames");
1721                       
1722 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1723 kumpf            1.1  
1724                           String sqlStatement =
1725                               "SELECT DISTINCT toclassname FROM ClassAssocTable WHERE (";
1726                       
1727                           // Match "from" class name
1728                           for (Uint32 i = 0; i < classList.size(); i++)
1729                           {
1730                               if (i > 0)
1731                               {
1732                                   sqlStatement.append(" OR ");
1733                               }
1734                       
1735                               sqlStatement.append("normfromclassname=?");
1736                           }
1737                           sqlStatement.append(')');
1738                       
1739                           // Match role
1740                           if (role.size())
1741                           {
1742                               sqlStatement.append(" AND normfrompropname=?");
1743                           }
1744 kumpf            1.1  
1745                           // Match resultRole
1746                           if (resultRole.size())
1747                           {
1748                               sqlStatement.append(" AND normtopropname=?");
1749                           }
1750                       
1751                           // Match association class name
1752                           if (assocClassList.size())
1753                           {
1754                               sqlStatement.append(" AND (");
1755                       
1756                               for (Uint32 i = 0; i < assocClassList.size(); i++)
1757                               {
1758                                   if (i > 0)
1759                                   {
1760                                       sqlStatement.append(" OR ");
1761                                   }
1762                       
1763                                   sqlStatement.append("normassocclassname=?");
1764                               }
1765 kumpf            1.1  
1766                               sqlStatement.append(')');
1767                           }
1768                       
1769                           // Match result class name
1770                           if (resultClassList.size())
1771                           {
1772                               sqlStatement.append(" AND (");
1773                       
1774                               for (Uint32 i = 0; i < resultClassList.size(); i++)
1775                               {
1776                                   if (i > 0)
1777                                   {
1778                                       sqlStatement.append(" OR ");
1779                                   }
1780                       
1781                                   sqlStatement.append("normtoclassname=?");
1782                               }
1783                       
1784                               sqlStatement.append(')');
1785                           }
1786 kumpf            1.1  
1787                           sqlStatement.append(';');
1788                       
1789                           sqlite3_stmt* stmt = 0;
1790                           CHECK_RC_OK(
1791                               sqlite3_prepare_v2(db.get(), sqlStatement.getCString(), -1, &stmt, 0),
1792                               db.get());
1793                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1794                       
1795                           int bindIndex = 1;
1796                       
1797                           for (Uint32 i = 0; i < classList.size(); i++)
1798                           {
1799                               String normfromclassname = _getNormalizedName(classList[i]);
1800                               CHECK_RC_OK(
1801                                   sqlite3_bind_text16(
1802                                       stmt,
1803                                       bindIndex++,
1804                                       normfromclassname.getChar16Data(),
1805                                       normfromclassname.size() * 2,
1806                                       SQLITE_TRANSIENT),
1807 kumpf            1.1              db.get());
1808                           }
1809                       
1810                           if (role.size())
1811                           {
1812 mike             1.5          String normfrompropname = _getNormalizedName(CIMNameCast(role));
1813 kumpf            1.1          CHECK_RC_OK(
1814                                   sqlite3_bind_text16(
1815                                       stmt,
1816                                       bindIndex++,
1817                                       normfrompropname.getChar16Data(),
1818                                       normfrompropname.size() * 2,
1819                                       SQLITE_TRANSIENT),
1820                                   db.get());
1821                           }
1822                       
1823                           if (resultRole.size())
1824                           {
1825                               String normtopropname =
1826 mike             1.5              _getNormalizedName(CIMNameCast(resultRole));
1827 kumpf            1.1          CHECK_RC_OK(
1828                                   sqlite3_bind_text16(
1829                                       stmt,
1830                                       bindIndex++,
1831                                       normtopropname.getChar16Data(),
1832                                       normtopropname.size() * 2,
1833                                       SQLITE_TRANSIENT),
1834                                   db.get());
1835                           }
1836                       
1837                           for (Uint32 i = 0; i < assocClassList.size(); i++)
1838                           {
1839                               String normassocclassname = _getNormalizedName(assocClassList[i]);
1840                               CHECK_RC_OK(
1841                                   sqlite3_bind_text16(
1842                                       stmt,
1843                                       bindIndex++,
1844                                       normassocclassname.getChar16Data(),
1845                                       normassocclassname.size() * 2,
1846                                       SQLITE_TRANSIENT),
1847                                   db.get());
1848 kumpf            1.1      }
1849                       
1850                           for (Uint32 i = 0; i < resultClassList.size(); i++)
1851                           {
1852                               String normtopropname = _getNormalizedName(resultClassList[i]);
1853                               CHECK_RC_OK(
1854                                   sqlite3_bind_text16(
1855                                       stmt,
1856                                       bindIndex++,
1857                                       normtopropname.getChar16Data(),
1858                                       normtopropname.size() * 2,
1859                                       SQLITE_TRANSIENT),
1860                                   db.get());
1861                           }
1862                       
1863                           int rc;
1864                           while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
1865                           {
1866                               associatorNames.append(String(
1867                                   (const Char16*)sqlite3_column_text16(stmt, 0),
1868                                   (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
1869 kumpf            1.1      }
1870                       
1871                           CHECK_RC_DONE(rc, db.get());
1872                       
1873 kumpf            1.3      stmtDestroyer.reset();
1874 kumpf            1.2      db.release();
1875                       
1876 kumpf            1.1      PEG_METHOD_EXIT();
1877                       }
1878                       
1879                       void SQLiteStore::getClassReferenceNames(
1880                           const CIMNamespaceName& nameSpace,
1881                           const Array<CIMName>& classList,
1882                           const Array<CIMName>& resultClassList,
1883                           const String& role,
1884                           Array<String>& referenceNames)
1885                       {
1886                           PEG_METHOD_ENTER(TRC_REPOSITORY,
1887                               "SQLiteStore::getClassReferenceNames");
1888                       
1889 kumpf            1.7  #ifdef USE_ASSOC_CLASS_CACHE
1890                       
1891                           String assocClassCacheName = nameSpace.getString();
1892                           assocClassCacheName.toLower();
1893                           AssocClassCache* cache =
1894                               _assocClassCacheManager.getAssocClassCache(assocClassCacheName);
1895                       
1896                           if (!cache->isActive())
1897                           {
1898                               _initAssocClassCache(nameSpace, cache);
1899                           }
1900                       
1901                           cache->getReferenceNames(classList, resultClassList, role, referenceNames);
1902                       
1903                       #else
1904                       
1905 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
1906 kumpf            1.1  
1907                           String sqlStatement =
1908                               "SELECT DISTINCT assocclassname FROM ClassAssocTable WHERE (";
1909                       
1910                           // Match "from" class name
1911                           for (Uint32 i = 0; i < classList.size(); i++)
1912                           {
1913                               if (i > 0)
1914                               {
1915                                   sqlStatement.append(" OR ");
1916                               }
1917                       
1918                               sqlStatement.append("normfromclassname=?");
1919                           }
1920                           sqlStatement.append(')');
1921                       
1922                           // Match role
1923                           if (role.size())
1924                           {
1925                               sqlStatement.append(" AND normfrompropname=?");
1926                           }
1927 kumpf            1.1  
1928                           // Match result class name
1929                           if (resultClassList.size())
1930                           {
1931                               sqlStatement.append(" AND (");
1932                       
1933                               for (Uint32 i = 0; i < resultClassList.size(); i++)
1934                               {
1935                                   if (i > 0)
1936                                   {
1937                                       sqlStatement.append(" OR ");
1938                                   }
1939                       
1940                                   sqlStatement.append("normassocclassname=?");
1941                               }
1942                       
1943                               sqlStatement.append(')');
1944                           }
1945                       
1946                           sqlStatement.append(';');
1947                       
1948 kumpf            1.1      sqlite3_stmt* stmt = 0;
1949                           CHECK_RC_OK(
1950                               sqlite3_prepare_v2(db.get(), sqlStatement.getCString(), -1, &stmt, 0),
1951                               db.get());
1952                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
1953                       
1954                           int bindIndex = 1;
1955                       
1956                           for (Uint32 i = 0; i < classList.size(); i++)
1957                           {
1958                               String normfromclassname = _getNormalizedName(classList[i]);
1959                               CHECK_RC_OK(
1960                                   sqlite3_bind_text16(
1961                                       stmt,
1962                                       bindIndex++,
1963                                       normfromclassname.getChar16Data(),
1964                                       normfromclassname.size() * 2,
1965                                       SQLITE_TRANSIENT),
1966                                   db.get());
1967                           }
1968                       
1969 kumpf            1.1      if (role.size())
1970                           {
1971 mike             1.5          String normfrompropname = _getNormalizedName(CIMNameCast(role));
1972 kumpf            1.1          CHECK_RC_OK(
1973                                   sqlite3_bind_text16(
1974                                       stmt,
1975                                       bindIndex++,
1976                                       normfrompropname.getChar16Data(),
1977                                       normfrompropname.size() * 2,
1978                                       SQLITE_TRANSIENT),
1979                                   db.get());
1980                           }
1981                       
1982                           for (Uint32 i = 0; i < resultClassList.size(); i++)
1983                           {
1984                               String normassocclassname = _getNormalizedName(resultClassList[i]);
1985                               CHECK_RC_OK(
1986                                   sqlite3_bind_text16(
1987                                       stmt,
1988                                       bindIndex++,
1989                                       normassocclassname.getChar16Data(),
1990                                       normassocclassname.size() * 2,
1991                                       SQLITE_TRANSIENT),
1992                                   db.get());
1993 kumpf            1.1      }
1994                       
1995                           int rc;
1996                           while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
1997                           {
1998                               referenceNames.append(String(
1999                                   (const Char16*)sqlite3_column_text16(stmt, 0),
2000                                   (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
2001                           }
2002                       
2003                           CHECK_RC_DONE(rc, db.get());
2004                       
2005 kumpf            1.3      stmtDestroyer.reset();
2006 kumpf            1.2      db.release();
2007 kumpf            1.7  #endif
2008 kumpf            1.2  
2009 kumpf            1.1      PEG_METHOD_EXIT();
2010                       }
2011                       
2012                       void SQLiteStore::_addInstanceAssociationEntries(
2013                           sqlite3* db,
2014                           const CIMNamespaceName& nameSpace,
2015                           const Array<InstanceAssociation>& instanceAssocEntries)
2016                       {
2017                           PEG_METHOD_ENTER(TRC_REPOSITORY,
2018                               "SQLiteStore::_addInstanceAssociationEntries");
2019                       
2020                           const char* sqlStatement =
2021                               "INSERT INTO InstanceAssocTable VALUES(?,?,?,?,?,?,?,?);";
2022                       
2023                           sqlite3_stmt* stmt = 0;
2024                           CHECK_RC_OK(
2025                               sqlite3_prepare_v2(db, sqlStatement, -1, &stmt, 0),
2026                               db);
2027                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
2028                       
2029                           for (Uint32 i = 0; i < instanceAssocEntries.size(); i++)
2030 kumpf            1.1      {
2031                               String associnstname =
2032                                   instanceAssocEntries[i].assocInstanceName;
2033                               // Note: This converts a String to a CIMObjectPath and back to a String
2034                               String normassocinstname = CIMObjectPath(
2035                                   instanceAssocEntries[i].assocInstanceName)._toStringCanonical();
2036                               String normassocclassname = _getNormalizedName(
2037                                   instanceAssocEntries[i].assocClassName);
2038                               // Note: This converts a String to a CIMObjectPath and back to a String
2039                               String normfrominstname = CIMObjectPath(
2040                                   instanceAssocEntries[i].fromInstanceName)._toStringCanonical();
2041                               String normfrompropname = _getNormalizedName(
2042                                   instanceAssocEntries[i].fromPropertyName);
2043                               String toinstname =
2044                                   instanceAssocEntries[i].toInstanceName;
2045                               String normtoclassname = _getNormalizedName(
2046                                   instanceAssocEntries[i].toClassName);
2047                               String normtopropname = _getNormalizedName(
2048                                   instanceAssocEntries[i].toPropertyName);
2049                       
2050                               CHECK_RC_OK(
2051 kumpf            1.1              sqlite3_bind_text16(
2052                                       stmt,
2053                                       1,
2054                                       associnstname.getChar16Data(),
2055                                       associnstname.size() * 2,
2056                                       SQLITE_STATIC),
2057                                   db);
2058                               CHECK_RC_OK(
2059                                   sqlite3_bind_text16(
2060                                       stmt,
2061                                       2,
2062                                       normassocinstname.getChar16Data(),
2063                                       normassocinstname.size() * 2,
2064                                       SQLITE_STATIC),
2065                                   db);
2066                               CHECK_RC_OK(
2067                                   sqlite3_bind_text16(
2068                                       stmt,
2069                                       3,
2070                                       normassocclassname.getChar16Data(),
2071                                       normassocclassname.size() * 2,
2072 kumpf            1.1                  SQLITE_STATIC),
2073                                   db);
2074                               CHECK_RC_OK(
2075                                   sqlite3_bind_text16(
2076                                       stmt,
2077                                       4,
2078                                       normfrominstname.getChar16Data(),
2079                                       normfrominstname.size() * 2,
2080                                       SQLITE_STATIC),
2081                                   db);
2082                               CHECK_RC_OK(
2083                                   sqlite3_bind_text16(
2084                                       stmt,
2085                                       5,
2086                                       normfrompropname.getChar16Data(),
2087                                       normfrompropname.size() * 2,
2088                                       SQLITE_STATIC),
2089                                   db);
2090                               CHECK_RC_OK(
2091                                   sqlite3_bind_text16(
2092                                       stmt,
2093 kumpf            1.1                  6,
2094                                       toinstname.getChar16Data(),
2095                                       toinstname.size() * 2,
2096                                       SQLITE_STATIC),
2097                                   db);
2098                               CHECK_RC_OK(
2099                                   sqlite3_bind_text16(
2100                                       stmt,
2101                                       7,
2102                                       normtoclassname.getChar16Data(),
2103                                       normtoclassname.size() * 2,
2104                                       SQLITE_STATIC),
2105                                   db);
2106                               CHECK_RC_OK(
2107                                   sqlite3_bind_text16(
2108                                       stmt,
2109                                       8,
2110                                       normtopropname.getChar16Data(),
2111                                       normtopropname.size() * 2,
2112                                       SQLITE_STATIC),
2113                                   db);
2114 kumpf            1.1  
2115                               CHECK_RC_DONE(sqlite3_step(stmt), db);
2116                       
2117                               CHECK_RC_OK(sqlite3_reset(stmt), db);
2118                       
2119                               CHECK_RC_OK(sqlite3_clear_bindings(stmt), db);
2120                           }
2121                       
2122                           PEG_METHOD_EXIT();
2123                       }
2124                       
2125                       void SQLiteStore::_removeInstanceAssociationEntries(
2126                           sqlite3* db,
2127                           const CIMNamespaceName& nameSpace,
2128                           const CIMObjectPath& assocInstanceName)
2129                       {
2130                           PEG_METHOD_ENTER(TRC_REPOSITORY,
2131                               "SQLiteStore::_removeInstanceAssociationEntries");
2132                       
2133                           const char* sqlStatement = "DELETE FROM InstanceAssocTable "
2134                               "WHERE normassocinstname=?;";
2135 kumpf            1.1  
2136                           sqlite3_stmt* stmt = 0;
2137                           CHECK_RC_OK(
2138                               sqlite3_prepare_v2(db, sqlStatement, -1, &stmt, 0),
2139                               db);
2140                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
2141                       
2142                           String associnstname = assocInstanceName._toStringCanonical();
2143                       
2144                           CHECK_RC_OK(
2145                               sqlite3_bind_text16(
2146                                   stmt,
2147                                   1,
2148                                   associnstname.getChar16Data(),
2149                                   associnstname.size() * 2,
2150                                   SQLITE_STATIC),
2151                               db);
2152                       
2153                           CHECK_RC_DONE(sqlite3_step(stmt), db);
2154                       
2155                           PEG_METHOD_EXIT();
2156 kumpf            1.1  }
2157                       
2158                       void SQLiteStore::getInstanceAssociatorNames(
2159                           const CIMNamespaceName& nameSpace,
2160                           const CIMObjectPath& instanceName,
2161                           const Array<CIMName>& assocClassList,
2162                           const Array<CIMName>& resultClassList,
2163                           const String& role,
2164                           const String& resultRole,
2165                           Array<String>& associatorNames)
2166                       {
2167                           PEG_METHOD_ENTER(TRC_REPOSITORY,
2168                               "SQLiteStore::getInstanceAssociatorNames");
2169                       
2170 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
2171 kumpf            1.1  
2172                           String sqlStatement = "SELECT DISTINCT toinstname "
2173                               "FROM InstanceAssocTable WHERE normfrominstname=?";
2174                       
2175                           // Match role
2176                           if (role.size())
2177                           {
2178                               sqlStatement.append(" AND normfrompropname=?");
2179                           }
2180                       
2181                           // Match resultRole
2182                           if (resultRole.size())
2183                           {
2184                               sqlStatement.append(" AND normtopropname=?");
2185                           }
2186                       
2187                           // Match association class name
2188                           if (assocClassList.size())
2189                           {
2190                               sqlStatement.append(" AND (");
2191                       
2192 kumpf            1.1          for (Uint32 i = 0; i < assocClassList.size(); i++)
2193                               {
2194                                   if (i > 0)
2195                                   {
2196                                       sqlStatement.append(" OR ");
2197                                   }
2198                       
2199                                   sqlStatement.append("normassocclassname=?");
2200                               }
2201                       
2202                               sqlStatement.append(')');
2203                           }
2204                       
2205                           // Match result class name
2206                           if (resultClassList.size())
2207                           {
2208                               sqlStatement.append(" AND (");
2209                       
2210                               for (Uint32 i = 0; i < resultClassList.size(); i++)
2211                               {
2212                                   if (i > 0)
2213 kumpf            1.1              {
2214                                       sqlStatement.append(" OR ");
2215                                   }
2216                       
2217                                   sqlStatement.append("normtoclassname=?");
2218                               }
2219                       
2220                               sqlStatement.append(')');
2221                           }
2222                       
2223                           sqlStatement.append(';');
2224                       
2225                           sqlite3_stmt* stmt = 0;
2226                           CHECK_RC_OK(
2227                               sqlite3_prepare_v2(db.get(), sqlStatement.getCString(), -1, &stmt, 0),
2228                               db.get());
2229                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
2230                       
2231                           String normfrominstname = instanceName._toStringCanonical();
2232                           int bindIndex = 1;
2233                       
2234 kumpf            1.1      CHECK_RC_OK(
2235                               sqlite3_bind_text16(
2236                                   stmt,
2237                                   bindIndex++,
2238                                   normfrominstname.getChar16Data(),
2239                                   normfrominstname.size() * 2,
2240                                   SQLITE_STATIC),
2241                               db.get());
2242                       
2243                           if (role.size())
2244                           {
2245 mike             1.5          String normfrompropname = _getNormalizedName(CIMNameCast(role));
2246 kumpf            1.1          CHECK_RC_OK(
2247                                   sqlite3_bind_text16(
2248                                       stmt,
2249                                       bindIndex++,
2250                                       normfrompropname.getChar16Data(),
2251                                       normfrompropname.size() * 2,
2252                                       SQLITE_TRANSIENT),
2253                                   db.get());
2254                           }
2255                       
2256                           if (resultRole.size())
2257                           {
2258                               String normtopropname =
2259 mike             1.5              _getNormalizedName(CIMNameCast(resultRole));
2260 kumpf            1.1          CHECK_RC_OK(
2261                                   sqlite3_bind_text16(
2262                                       stmt,
2263                                       bindIndex++,
2264                                       normtopropname.getChar16Data(),
2265                                       normtopropname.size() * 2,
2266                                       SQLITE_TRANSIENT),
2267                                   db.get());
2268                           }
2269                       
2270                           for (Uint32 i = 0; i < assocClassList.size(); i++)
2271                           {
2272                               String normassocclassname = _getNormalizedName(assocClassList[i]);
2273                               CHECK_RC_OK(
2274                                   sqlite3_bind_text16(
2275                                       stmt,
2276                                       bindIndex++,
2277                                       normassocclassname.getChar16Data(),
2278                                       normassocclassname.size() * 2,
2279                                       SQLITE_TRANSIENT),
2280                                   db.get());
2281 kumpf            1.1      }
2282                       
2283                           for (Uint32 i = 0; i < resultClassList.size(); i++)
2284                           {
2285                               String normtoclassname = _getNormalizedName(resultClassList[i]);
2286                               CHECK_RC_OK(
2287                                   sqlite3_bind_text16(
2288                                       stmt,
2289                                       bindIndex++,
2290                                       normtoclassname.getChar16Data(),
2291                                       normtoclassname.size() * 2,
2292                                       SQLITE_TRANSIENT),
2293                                   db.get());
2294                           }
2295                       
2296                           int rc;
2297                           while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
2298                           {
2299                               associatorNames.append(String(
2300                                   (const Char16*)sqlite3_column_text16(stmt, 0),
2301                                   (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
2302 kumpf            1.1      }
2303                       
2304                           CHECK_RC_DONE(rc, db.get());
2305                       
2306 kumpf            1.3      stmtDestroyer.reset();
2307 kumpf            1.2      db.release();
2308                       
2309 kumpf            1.1      PEG_METHOD_EXIT();
2310                       }
2311                       
2312                       void SQLiteStore::getInstanceReferenceNames(
2313                           const CIMNamespaceName& nameSpace,
2314                           const CIMObjectPath& instanceName,
2315                           const Array<CIMName>& resultClassList,
2316                           const String& role,
2317                           Array<String>& referenceNames)
2318                       {
2319                           PEG_METHOD_ENTER(TRC_REPOSITORY,
2320                               "SQLiteStore::getInstanceReferenceNames");
2321                       
2322 kumpf            1.2      DbConnection db(_dbcm, nameSpace);
2323 kumpf            1.1  
2324                           String sqlStatement = "SELECT DISTINCT associnstname "
2325                               "FROM InstanceAssocTable WHERE normfrominstname=?";
2326                       
2327                           // Match role
2328                           if (role.size())
2329                           {
2330                               sqlStatement.append(" AND normfrompropname=?");
2331                           }
2332                       
2333                           // Match result class name
2334                           if (resultClassList.size())
2335                           {
2336                               sqlStatement.append(" AND (");
2337                       
2338                               for (Uint32 i = 0; i < resultClassList.size(); i++)
2339                               {
2340                                   if (i > 0)
2341                                   {
2342                                       sqlStatement.append(" OR ");
2343                                   }
2344 kumpf            1.1  
2345                                   sqlStatement.append("normassocclassname=?");
2346                               }
2347                       
2348                               sqlStatement.append(')');
2349                           }
2350                       
2351                           sqlStatement.append(';');
2352                       
2353                           sqlite3_stmt* stmt = 0;
2354                           CHECK_RC_OK(
2355                               sqlite3_prepare_v2(db.get(), sqlStatement.getCString(), -1, &stmt, 0),
2356                               db.get());
2357                           AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
2358                       
2359                           String normfrominstname = instanceName._toStringCanonical();
2360                           int bindIndex = 1;
2361                       
2362                           CHECK_RC_OK(
2363                               sqlite3_bind_text16(
2364                                   stmt,
2365 kumpf            1.1              bindIndex++,
2366                                   normfrominstname.getChar16Data(),
2367                                   normfrominstname.size() * 2,
2368                                   SQLITE_STATIC),
2369                               db.get());
2370                       
2371                           if (role.size())
2372                           {
2373 mike             1.5          String normfrompropname = _getNormalizedName(CIMNameCast(role));
2374 kumpf            1.1          CHECK_RC_OK(
2375                                   sqlite3_bind_text16(
2376                                       stmt,
2377                                       bindIndex++,
2378                                       normfrompropname.getChar16Data(),
2379                                       normfrompropname.size() * 2,
2380                                       SQLITE_TRANSIENT),
2381                                   db.get());
2382                           }
2383                       
2384                           for (Uint32 i = 0; i < resultClassList.size(); i++)
2385                           {
2386                               String normassocclassname = _getNormalizedName(resultClassList[i]);
2387                               CHECK_RC_OK(
2388                                   sqlite3_bind_text16(
2389                                       stmt,
2390                                       bindIndex++,
2391                                       normassocclassname.getChar16Data(),
2392                                       normassocclassname.size() * 2,
2393                                       SQLITE_TRANSIENT),
2394                                   db.get());
2395 kumpf            1.1      }
2396                       
2397                           int rc;
2398                           while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
2399                           {
2400                               referenceNames.append(String(
2401                                   (const Char16*)sqlite3_column_text16(stmt, 0),
2402                                   (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
2403                           }
2404                       
2405                           CHECK_RC_DONE(rc, db.get());
2406                       
2407 kumpf            1.3      stmtDestroyer.reset();
2408 kumpf            1.2      db.release();
2409                       
2410 kumpf            1.1      PEG_METHOD_EXIT();
2411                       }
2412                       
2413                       PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2