Ayende Rahien - 2008-07-05

This block of code should create an associates between two tress and follow it when called.
However, it does not do so. I also attached a C version of the code, which does work.

private DbFile.KeyGenStatus extract_key(DbFile secondary, ref DbEntry key, ref DbEntry data, out DbEntry result)
{
   var bytes = Encoding.UTF8.GetBytes("test");
   result = DbEntry.InOut(bytes);
   return DbFile.KeyGenStatus.Success;
}

public static void Main()
{

var envCreateFlags = Env.OpenFlags.Create |
            Env.OpenFlags.InitLock |
            Env.OpenFlags.InitLog |
            Env.OpenFlags.ThreadSafe |
            Env.OpenFlags.Register |
            Env.OpenFlags.InitMPool |
            Env.OpenFlags.InitTxn |
            Env.OpenFlags.Recover;

string path = "E:\\temp\\BerkeleyDb\\BerkeleyDb\\Debug\\test";

Env env=new Env(EnvCreateFlags.None);
env.Open(path, envCreateFlags,0);

var createDbDb = env.CreateDatabase(DbCreateFlags.None);
var db = createDbDb.Open(null, "my-test-tree", null, DbType.BTree, Db.OpenFlags.Create, 0);

var createIdxDb = env.CreateDatabase(DbCreateFlags.None);
var idx = createIdxDb.Open(null, "my-test-idx", null, DbType.BTree, Db.OpenFlags.Create, 0);

db.Associate(idx, extract_key, DbFile.AssociateFlags.None);

DbEntry key = DbEntry.InOut(Encoding.UTF8.GetBytes("hello"));
DbEntry data = DbEntry.InOut(BitConverter.GetBytes(13));

db.Put(null, ref key, ref data);

DbEntry key2 = DbEntry.InOut(Encoding.UTF8.GetBytes("test"));
DbEntry data2 = DbEntry.InOut(new byte[4]);

idx.Get(null, ref key2, ref data2, DbFile.ReadFlags.None);

int intValue = BitConverter.ToInt32(data2.Buffer, 0);

Console.WriteLine( intValue );

createIdxDb.Close();
createIdxDb.Close();
env.Close();

}

C Version:

int extract_key(DB *sdbp,          /* secondary db handle */
              const DBT *pkey,   /* primary db record's key */
              const DBT *pdata,  /* primary db record's data */
              DBT *skey)         /* secondary db record's key */
{
    memset(skey, 0, sizeof(DBT));
    skey->data = "test";
    skey->size = strlen("test") + 1;

    /* Return 0 to indicate that the record can be created/updated. */
    return (0);
}

int main(array<System::String ^> ^args)
{
   
    u_int32_t envCreateFlags = DB_CREATE |
                   DB_INIT_LOCK|
                   DB_INIT_LOG|
                   DB_INIT_MPOOL|
                   DB_INIT_TXN|
                   DB_RECOVER;

    char* path = "E:\\temp\\BerkeleyDb\\BerkeleyDb\\Debug\\test";

    DB_ENV *createDbEnv;
    db_env_create(&createDbEnv, 0);
    createDbEnv->open(createDbEnv,path, envCreateFlags, 0);

    DB *createDbDb;
    db_create(&createDbDb, createDbEnv, 0);

    createDbDb->open(createDbDb, NULL, "my-test-tree", NULL, DB_BTREE, DB_CREATE, 0);
   
    DB *createIdxDb;
    db_create(&createIdxDb, createDbEnv, 0);

    createIdxDb->open(createIdxDb, NULL, "my-test-idx", NULL, DB_BTREE, DB_CREATE, 0);
    createDbDb->associate(createDbDb,NULL, createIdxDb,extract_key, 0);

    DBT key, data;
    memset(&key, 0, sizeof(DBT));
    memset(&data, 0, sizeof(DBT));

    key.data = "hello";
    key.size= key.ulen = sizeof("hello")+1;

    int intValue=13;
    data.data = &intValue;
    data.ulen =data.size = sizeof(int);

    createDbDb->put(createDbDb, NULL, &key, &data, 0);

    DBT key2, data2;
    memset(&key2, 0, sizeof(DBT));
    memset(&data2, 0, sizeof(DBT));

    key2.data = "test";
    key2.size= key.ulen = sizeof("test")+1;

    int intValue2=13;
    data2.data = &intValue2;
    data2.ulen = data.size = sizeof(int);
   

    createIdxDb->get(createIdxDb,NULL, &key2, &data2, 0);

    Console::WriteLine( intValue2 );

    createIdxDb->close(createIdxDb, 0);
    createDbDb->close(createDbDb, 0);
    createDbEnv->close(createDbEnv, 0);

    return 0;
}