Files
mars-flaim/xflaim/util/indextest2srv.cpp
ahodgkinson 12a621dc04 Changed license to LGPL.
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@1010 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2007-01-23 11:22:22 +00:00

679 lines
15 KiB
C++

//------------------------------------------------------------------------------
// Desc: Indexing Unit Test 2
// Tabs: 3
//
// Copyright (c) 2003-2007 Novell, Inc. All Rights Reserved.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version 2.1
// of the License.
//
// This library 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
// Library Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; 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$
//------------------------------------------------------------------------------
#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 =
"<xflaim:Index "
" xmlns:xflaim=\"http://www.novell.com/XMLDatabase/Schema\""
" xflaim:name=\"first+last\" "
" xflaim:DictNumber=\"1\"> " // HARD-CODED Dict Num for easy retrieval
" <xflaim:ElementComponent xflaim:name=\"name\">"
" <xflaim:AttributeComponent"
" xflaim:name=\"first\" "
" xflaim:IndexOn=\"value\" "
" xflaim:KeyComponent=\"1\" />"
" <xflaim:AttributeComponent"
" xflaim:name=\"last\" "
" xflaim:IndexOn=\"value\" "
" xflaim:KeyComponent=\"2\" />"
" </xflaim:ElementComponent> "
"</xflaim:Index> ";
// 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 =
"<prfx0:Index xmlns:prfx0=\"http://www.novell.com/XMLDatabase/Schema\" "
" prfx0:DictNumber=\"13\" "
" prfx0:CollectionNumber=\"65534\" "
" prfx0:name=\"track/ext index\" "
" prfx0:State=\"online\">"
" <prfx0:ElementComponent prfx0:name=\"track\" prfx0:KeyComponent=\"1\" prfx0:Required=\"1\">"
" <prfx0:AttributeComponent "
" prfx0:name=\"ext\" "
" prfx0:IndexOn=\"presence\" "
" prfx0:KeyComponent=\"2\"/>"
" </prfx0:ElementComponent>"
"</prfx0:Index>";
const char * pszDoc =
"<?xml version=\"1.0\"?> "
"<disc>"
" <id>00097210</id>"
" <length>2420</length>"
" <title>Frank Sinatra / Blue skies</title>"
" <genre>cddb/jazz</genre>"
" <track index=\"1\" offset=\"150\">blue skies</track>"
" <track index=\"2\" offset=\"11693\" ext=\"Frank Sinatra\">night and day</track>"
"</disc>";
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"/<nothing>
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"/<ext's name id>
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);
}