//------------------------------------------------------------------------------ // Desc: Indexing Unit Test 2 // // Tabs: 3 // // Copyright (c) 2003-2006 Novell, Inc. All Rights Reserved. // // This program is free software; you can redistribute it and/or // modify it under the terms of version 2 of the GNU General Public // License as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, contact Novell, Inc. // // To contact Novell about this file by physical or electronic mail, // you may find current contact information at www.novell.com // // $Id: indextest2srv.cpp 3119 2006-01-19 13:39:12 -0700 (Thu, 19 Jan 2006) dsanders $ //------------------------------------------------------------------------------ #include "flmunittest.h" #ifndef DB_NAME_STR #if defined( FLM_NLM) #define DB_NAME_STR "SYS:\\IX2.DB" #else #define DB_NAME_STR "ix2.db" #endif #endif /**************************************************************************** Desc: ****************************************************************************/ class IIndexTest2Impl : public TestBase { public: const char * getName( void); RCODE runSuite1( void); RCODE runSuite2( void); RCODE execute( void); }; /**************************************************************************** Desc: ****************************************************************************/ RCODE getTest( IFlmTest ** ppTest) { RCODE rc = NE_XFLM_OK; if( (*ppTest = f_new IIndexTest2Impl) == NULL) { rc = NE_XFLM_MEM; goto Exit; } Exit: return( rc); } /**************************************************************************** Desc: ****************************************************************************/ const char * IIndexTest2Impl::getName( void) { return( "Index Test 2"); } /**************************************************************************** Desc: ****************************************************************************/ RCODE IIndexTest2Impl::execute( void) { RCODE rc = NE_XFLM_OK; if( RC_BAD( rc = runSuite1())) { goto Exit; } if( RC_BAD( rc = runSuite2())) { goto Exit; } Exit: return( rc); } /**************************************************************************** Desc: ****************************************************************************/ RCODE IIndexTest2Impl::runSuite1( void) { RCODE rc = NE_XFLM_OK; FLMBYTE szBuf[ 128]; FLMBYTE pucTemp[256]; FLMBOOL bDibCreated = FALSE; FLMBOOL bTransStarted = FALSE; IF_DOMNode * pDocument = NULL; IF_DOMNode * pAttr = NULL; IF_DOMNode * pNameNode = NULL; IF_DOMNode * pPrevResult = NULL; IF_DOMNode * pNextResult = NULL; FLMUINT uiNameDef = 0; FLMUINT uiFirstDef = 0; FLMUINT uiLastDef = 0; FLMUINT i = 0; FlagSet firstNamePlusLastNameFlags; IF_Query * pQuery = NULL; KeyIterator * pKeyIter = f_new KeyIterator(); const char * pszIndexDef1 = " " // HARD-CODED Dict Num for easy retrieval " " " " " " " " " "; // NOTE: If you make any modifications here, make sure these arrays have // the same number of elements. char * pszFirstNames[] = { "Gavin", "James", "John", "Heidi", "Darcey", "Hilary"}; char * pszLastNames[] = { "Jensen", "Stevenson", "Smith", "Christensen", "Miller", "Andersen"}; char ** pszFirstPlusLastNames = NULL; if( RC_BAD( rc = f_alloc( sizeof( char *) * sizeof( pszFirstNames) / sizeof( pszFirstNames[ 0]), &pszFirstPlusLastNames))) { goto Exit; } // Concatenate all pairs to for( i = 0; i < sizeof(pszFirstNames)/sizeof(pszFirstNames[0]); i++) { if( RC_BAD( rc = f_alloc( f_strlen( pszFirstNames[i]) + f_strlen( pszLastNames[i]) + 1, &pszFirstPlusLastNames[ i]))) { goto Exit; } f_strcpy( pszFirstPlusLastNames[i], pszFirstNames[i]); f_strcat( pszFirstPlusLastNames[i], pszLastNames[i]); } firstNamePlusLastNameFlags.init( (FLMBYTE **)pszFirstPlusLastNames, i); beginTest( "Attribute Key Removal Test", "Create a bunch of documents that will cause the generation of " "keys on our indexed attributes. Delete the documents and ensure the keys " "are removed as well.", "No further details.", ""); if( RC_BAD( rc = initCleanTestState( DB_NAME_STR))) { MAKE_FLM_ERROR_STRING( "Failed to initialize test state.", m_szDetails, rc); goto Exit; } bDibCreated = TRUE; if( RC_BAD( rc = pKeyIter->init( 1, m_pDbSystem, m_pDb))) { MAKE_FLM_ERROR_STRING( "Failed to initialize index key iter.", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = m_pDb->transBegin( XFLM_UPDATE_TRANS))) { MAKE_FLM_ERROR_STRING( "transBegin failed", m_szDetails, rc); goto Exit; } bTransStarted = TRUE; if( RC_BAD( rc = m_pDb->createElementDef( NULL, "name", XFLM_NODATA_TYPE, &uiNameDef))) { MAKE_FLM_ERROR_STRING( "createElementDef failed.", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = m_pDb->createAttributeDef(NULL, "first", XFLM_TEXT_TYPE, &uiFirstDef, NULL))) { MAKE_FLM_ERROR_STRING( "Failed to create attribute Def.", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = m_pDb->createAttributeDef(NULL, "last", XFLM_TEXT_TYPE, &uiLastDef, NULL))) { MAKE_FLM_ERROR_STRING( "Failed to create attribute Def.", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = importBuffer( pszIndexDef1, XFLM_DICT_COLLECTION))) { goto Exit; } // Make a bunch of documents for( i = 0; i < sizeof(pszFirstNames)/sizeof( pszFirstNames[0]); i++) { if ( RC_BAD( rc = m_pDb->createDocument( XFLM_DATA_COLLECTION, &pDocument))) { MAKE_FLM_ERROR_STRING( "createDocument failed.", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = pDocument->createNode( m_pDb, ELEMENT_NODE, uiNameDef, XFLM_FIRST_CHILD, &pNameNode))) { MAKE_FLM_ERROR_STRING( "createNode failed.", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = pNameNode->createAttribute( m_pDb, uiFirstDef, &pAttr))) { MAKE_ERROR_STRING( "createAttribute failed.", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = pAttr->setUTF8( m_pDb, (FLMBYTE *)pszFirstNames[ i]))) { MAKE_FLM_ERROR_STRING( "setUTF8 failed.", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = pNameNode->createAttribute( m_pDb, uiLastDef, &pAttr))) { MAKE_ERROR_STRING( "createAttribute failed.", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = pAttr->setUTF8( m_pDb, (FLMBYTE *)pszLastNames[i]))) { MAKE_FLM_ERROR_STRING( "setUTF8 failed.", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = m_pDb->documentDone( pDocument))) { MAKE_FLM_ERROR_STRING( "documentDone failed.", m_szDetails, rc); goto Exit; } } // First make sure all expected keys were generated pKeyIter->reset(); while( RC_OK( rc = pKeyIter->next())) { if( RC_BAD( rc = pKeyIter->getCurrentKeyVal( 0, szBuf, sizeof( szBuf), NULL))) { MAKE_FLM_ERROR_STRING( "Unable to get key value.", m_szDetails, rc); goto Exit; } f_strcpy( (char *)pucTemp, (char *)szBuf); if( RC_BAD( rc = pKeyIter->getCurrentKeyVal( 1, szBuf, sizeof( szBuf), NULL))) { MAKE_FLM_ERROR_STRING( "Unable to get key value.", m_szDetails, rc); goto Exit; } f_strcat( (char *)pucTemp, (char *)szBuf); if( !firstNamePlusLastNameFlags.setElemFlag( pucTemp)) { MAKE_FLM_ERROR_STRING( "Unexpected key found.", m_szDetails, rc); goto Exit; } } if ( rc == NE_XFLM_EOF_HIT) { rc = NE_XFLM_OK; } else { MAKE_FLM_ERROR_STRING( "Unexpected rc when iterating keys.", m_szDetails, rc); goto Exit; } if( !firstNamePlusLastNameFlags.allElemFlagsSet()) { rc = NE_XFLM_FAILURE; MAKE_FLM_ERROR_STRING( "Expected keys not generated.", m_szDetails, rc); goto Exit; } // Query for all the documents with last == "Miller" if( RC_BAD( rc = m_pDbSystem->createIFQuery( &pQuery))) { MAKE_FLM_ERROR_STRING( "Failed to create query object.", m_szDetails, rc); goto Exit; } // This query should return me the document node if( RC_BAD( rc = pQuery->setupQueryExpr( m_pDb, "@last == \"Miller\""))) { MAKE_FLM_ERROR_STRING( "Failed to set up query expression.", m_szDetails, rc); goto Exit; } // Delete all documents that had a last attr == "Miller" while( RC_OK( rc = pQuery->getNext( m_pDb, &pNextResult))) { if( pPrevResult) { if( RC_BAD( rc = pPrevResult->deleteNode( m_pDb))) { MAKE_FLM_ERROR_STRING( "deleteNode failed.", m_szDetails, rc); goto Exit; } pPrevResult->Release(); } pPrevResult = pNextResult; pPrevResult->AddRef(); } // Delete the final node if( pPrevResult) { if( RC_BAD( rc = pPrevResult->deleteNode( m_pDb))) { MAKE_FLM_ERROR_STRING( "deleteNode failed.", m_szDetails, rc); goto Exit; } } // remove Miller and make a new cross product firstNamePlusLastNameFlags.removeElem( (FLMBYTE *)"DarceyMiller"); firstNamePlusLastNameFlags.unsetAllFlags(); // Reset the key iterator and make sure we don't get anything unexpected // First make sure all expected keys were generated pKeyIter->reset(); while( RC_OK( rc = pKeyIter->next())) { if ( RC_BAD( rc = pKeyIter->getCurrentKeyVal( 0, szBuf, sizeof( szBuf), NULL))) { MAKE_FLM_ERROR_STRING( "Unable to get key value.", m_szDetails, rc); goto Exit; } f_strcpy( (char *)pucTemp, (char *)szBuf); if( RC_BAD( rc = pKeyIter->getCurrentKeyVal( 1, szBuf, sizeof( szBuf), NULL))) { MAKE_FLM_ERROR_STRING( "Unable to get key value.", m_szDetails, rc); goto Exit; } f_strcat( (char *)pucTemp, (char *)szBuf); if( !firstNamePlusLastNameFlags.setElemFlag( pucTemp)) { MAKE_FLM_ERROR_STRING( "Unexpected key found.", m_szDetails, rc); goto Exit; } } if( rc == NE_XFLM_EOF_HIT) { rc = NE_XFLM_OK; } else { MAKE_FLM_ERROR_STRING( "Unexpected rc when iterating keys.", m_szDetails, rc); goto Exit; } if( !firstNamePlusLastNameFlags.allElemFlagsSet()) { rc = NE_XFLM_FAILURE; MAKE_FLM_ERROR_STRING( "Expected keys not generated.", m_szDetails, rc); goto Exit; } endTest("PASS"); Exit: if( RC_BAD( rc)) { endTest("FAIL"); } for( i = 0; i < sizeof(pszFirstNames)/sizeof(pszFirstNames[0]); i++) { f_free( &pszFirstPlusLastNames[ i]); } f_free( &pszFirstPlusLastNames); if( bTransStarted) { m_pDb->transCommit(); } if( pDocument) { pDocument->Release(); } if( pAttr) { pAttr->Release(); } if( pNameNode) { pNameNode->Release(); } if( pNextResult) { pNextResult->Release(); } if( pPrevResult) { pPrevResult->Release(); } if( pQuery) { pQuery->Release(); } if( pKeyIter) { pKeyIter->Release(); } shutdownTestState( DB_NAME_STR, bDibCreated); return( rc); } /**************************************************************************** Desc: ****************************************************************************/ RCODE IIndexTest2Impl::runSuite2( void) { RCODE rc = NE_XFLM_OK; FLMBOOL bDibCreated = FALSE; FLMBOOL bTransStarted = FALSE; IF_DataVector * pSearchKey = NULL; FLMUINT uiExtAttrId = 0; char szTemp[30]; FLMUINT uiTemp; const char * pszIndexDef = "" " " " " " " ""; const char * pszDoc = " " "" " 00097210" " 2420" " Frank Sinatra / Blue skies" " cddb/jazz" " blue skies" " night and day" ""; beginTest( "Missing Presence Index Key Test", "", "No further details.", ""); if( RC_BAD( rc = initCleanTestState( DB_NAME_STR))) { MAKE_FLM_ERROR_STRING( "Failed to initialize test state.", m_szDetails, rc); goto Exit; } bDibCreated = TRUE; if( RC_BAD( rc = m_pDb->transBegin( XFLM_UPDATE_TRANS))) { MAKE_FLM_ERROR_STRING( "transBegin failed", m_szDetails, rc); goto Exit; } bTransStarted = TRUE; if( RC_BAD( rc = m_pDb->createAttributeDef( NULL, "ext", XFLM_TEXT_TYPE, &uiExtAttrId))) { MAKE_FLM_ERROR_STRING( "createAttributeDef failed", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = importBuffer( pszDoc, XFLM_DATA_COLLECTION))) { goto Exit; } if( RC_BAD( rc = importBuffer( pszIndexDef, XFLM_DICT_COLLECTION))) { goto Exit; } if( RC_BAD( rc = m_pDb->transCommit())) { MAKE_FLM_ERROR_STRING( "transCommit failed", m_szDetails, rc); goto Exit; } bTransStarted = FALSE; if( RC_BAD( rc = m_pDbSystem->createIFDataVector( &pSearchKey))) { MAKE_FLM_ERROR_STRING( "createIFDataVector failed", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = m_pDb->keyRetrieve( 13, NULL, XFLM_FIRST, pSearchKey))) { MAKE_FLM_ERROR_STRING( "keyRetrieve failed", m_szDetails, rc); goto Exit; } uiTemp = sizeof(szTemp); if( RC_BAD( rc = pSearchKey->getUTF8( 0, (FLMBYTE *)szTemp, &uiTemp))) { MAKE_FLM_ERROR_STRING( "getNative failed", m_szDetails, rc); goto Exit; } if( f_strcmp( szTemp, "blue skies") != 0) { rc = RC_SET( NE_XFLM_DATA_ERROR); MAKE_FLM_ERROR_STRING( "Invalid key component value", m_szDetails, rc); goto Exit; } if( RC_OK( rc = pSearchKey->getUINT( 1, &uiTemp))) { rc = RC_SET( NE_XFLM_DATA_ERROR); MAKE_FLM_ERROR_STRING( "Invalid key component value", m_szDetails, rc); goto Exit; } // first key - "Blue skies"/ if( RC_BAD( rc = m_pDb->keyRetrieve( 13, pSearchKey, XFLM_EXCL, pSearchKey))) { MAKE_FLM_ERROR_STRING( "keyRetrieve failed", m_szDetails, rc); goto Exit; } // second key "night and day"/ uiTemp = sizeof(szTemp); if( RC_BAD( rc = pSearchKey->getUTF8( 0, (FLMBYTE *)szTemp, &uiTemp))) { MAKE_FLM_ERROR_STRING( "getUTF8 failed", m_szDetails, rc); goto Exit; } if( f_strcmp( szTemp, "night and day") != 0) { rc = RC_SET( NE_XFLM_DATA_ERROR); MAKE_FLM_ERROR_STRING( "Invalid key component value", m_szDetails, rc); goto Exit; } if( RC_BAD( rc = pSearchKey->getUINT( 1, &uiTemp))) { MAKE_FLM_ERROR_STRING( "getUINT failed", m_szDetails, rc); goto Exit; } if( uiTemp != uiExtAttrId) { rc = RC_SET( NE_XFLM_DATA_ERROR); MAKE_FLM_ERROR_STRING( "Invalid key component value", m_szDetails, rc); goto Exit; } endTest("PASS"); Exit: if( pSearchKey) { pSearchKey->Release(); } if( RC_BAD( rc)) { endTest("FAIL"); } if( bTransStarted) { if( RC_OK(rc)) { rc = m_pDb->transCommit(); } else { m_pDb->transAbort(); } } shutdownTestState( DB_NAME_STR, !bDibCreated); return( rc); }