/**
 * run
 */
MojErr MojDbShardManagerTest::run()
{
    MojErr err = MojErrNone;
    MojDb db;

    // open
    err = db.open(MojDbTestDir);
    MojTestErrCheck(err);

    MojDbShardEngine* p_eng = db.shardEngine();
    MojDbShardIdCache cache;
    err = testShardIdCacheIndexes(&cache);
    MojTestErrCheck(err);
    err = testShardIdCacheOperations(&cache);
    MojTestErrCheck(err);
    err = testShardEngine(p_eng);
    MojTestErrCheck(err);

    err = testShardCreateAndRemoveWithRecords(db);
    MojTestErrCheck(err);

    err = db.close();
    MojTestErrCheck(err);

    return err;
}
/**
 * verifyExistance1
 */
MojErr MojDbShardManagerTest::verifyShardExistance (MojDb& db, const MojDbShardInfo& shard)
{
    bool found;

    MojErr err = db.shardEngine()->isIdExist(shard.id, found);
    MojTestErrCheck(err);

    if (!found)
    {
        err = MojErrDbVerificationFailed;
        MojErrCheck(err);
    }

    return MojErrNone;
}
/**
 * Add records to first shard for a single Kind
 */
MojErr MojDbShardManagerTest::createShardObjects1 (MojDb& db, MojDbShardInfo& shard)
{
    MojObject objKind;
    MojString kindId;

    MojErr err = kindId.assign(_T("TestShard1:1"));
    MojErrCheck(err);
    err = objKind.putString(_T("_kind"), kindId.data());
    MojErrCheck(err);

    //generate
    err = generateItem(shard);
    MojErrCheck(err);

    err = addKind(TestShardKind1Str, db);
    MojErrCheck(err);
    err = verifyKindExistance(kindId, db);
    MojErrCheck(err);

    //store shard info
    err = db.shardEngine()->put(shard);
    MojErrCheck(err);

    //add record
    MojObject record;
    err = record.putString(_T("_kind"), kindId.data());
    MojErrCheck(err);

    //add value
    MojObject objId(static_cast<MojInt32>(shard.id));
    err = record.put(_T("recId"), objId);
    MojErrCheck(err);

    //put
    MojString strShardId;
    MojDbShardEngine::convertId(shard.id, strShardId);
    err = db.put(record, MojDb::FlagNone, MojDbReq(), strShardId);
    MojErrCheck(err);

    return MojErrNone;
}
/**
 * testShardCreateAndRemoveWithRecords
 *
 * - create 3 new shards
 * - add records to 1st and 2nd shard
 * - remove shard 1
 * - verify existance of shard 1
 * - verify records of shard 2
 * - remove shard 2
 * - verify existance of shard 2
 * - verify records of shard 3 (== 0)
 * - remove shard 3
 * - verify existance of shard 3
 */
MojErr MojDbShardManagerTest::testShardCreateAndRemoveWithRecords (MojDb& db)
{
    MojDbShardEngine* p_eng = db.shardEngine();
    MojTestAssert(p_eng);

    MojDbShardInfo shard1, shard2;
    MojVector<MojUInt32> arrShardIds;
    MojUInt32 count;

    //---------------------------------------------------------------
    // test shard 1
    //---------------------------------------------------------------

    MojErr err = createShardObjects1(db, shard1);
    MojErrCheck(err);

    //verify number of records for shard 1 (shard is active)
    err = verifyRecords(_T("TestShard1:1"), db, shard1, count);
    MojTestErrCheck(err);
    MojTestAssert(count == 1);

    //err = db.shardEngine()->purgeShardObjects(1);
    //MojTestErrCheck(err);

    //remove shard 1
    arrShardIds.push(shard1.id);
    err = p_eng->removeShardObjects(arrShardIds);
    MojErrCheck(err);

    //verify number of records for shard 1
    err = verifyRecords(_T("TestShard1:1"), db, shard1, count);
    MojErrCheck(err);
    MojTestAssert(count == 0);

    //verify existance of shard 1
    err = verifyShardExistance(db, shard1);
    MojErrCheck(err);

    //---------------------------------------------------------------
    // test shard 2
    //---------------------------------------------------------------

    err = createShardObjects2(db, shard2);
    MojErrCheck(err);

    //verify number of records for shard 1 (shard is active)
    err = verifyRecords(_T("TestShard1:1"), db, shard2, count);
    MojTestErrCheck(err);
    MojTestAssert(count == 1);

    err = verifyRecords(_T("TestShard2:1"), db, shard2, count);
    MojTestErrCheck(err);
    MojTestAssert(count == 1);

    err = verifyRecords(_T("TestShard3:1"), db, shard2, count);
    MojTestErrCheck(err);
    MojTestAssert(count == 1);

    //remove shard 1
    arrShardIds.push(shard2.id);
    err = p_eng->removeShardObjects(arrShardIds);
    MojErrCheck(err);

    //verify number of records for shard 1
    err = verifyRecords(_T("TestShard1:1"), db, shard2, count);
    MojErrCheck(err);
    MojTestAssert(count == 0);

    err = verifyRecords(_T("TestShard2:1"), db, shard2, count);
    MojErrCheck(err);
    MojTestAssert(count == 0);

    err = verifyRecords(_T("TestShard3:1"), db, shard2, count);
    MojErrCheck(err);
    MojTestAssert(count == 0);

    //verify existance of shard 1
    err = verifyShardExistance(db, shard2);
    MojErrCheck(err);

    return MojErrNone;
}