Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Updated db C++ API for string type primary key #501

Merged
merged 1 commit into from
Sep 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 98 additions & 1 deletion contracts/eoslib/db.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,106 @@
/**
* @ingroup databaseCpp
* Cpp implementation of database API. It is based on pimpl idiom.
* @see Table class and table_impl class
* @see Table class and table_impl and table_impl_str class
*/

template<typename T>
struct table_impl_obj {};

template<>
struct table_impl_obj<char*> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should define a string class and not use char* as strings in c++ apis.


static int32_t store( AccountName scope, TableName table, char* key, uint32_t keylen, char* data, uint32_t datalen ) {
return store_str( scope, table, key, keylen, data, datalen );
}

static int32_t update( AccountName scope, TableName table, char* key, uint32_t keylen, char* data, uint32_t datalen ) {
return update_str( scope, table, key, keylen, data, datalen );
}

static int32_t front( AccountName scope, AccountName code, TableName table, char* data, uint32_t len ) {
return front_str( scope, code, table, data, len );
}

static int32_t back( AccountName scope, AccountName code, TableName table, char* data, uint32_t len ) {
return back_str( scope, code, table, data, len );
}

static int32_t load( AccountName scope, AccountName code, TableName table, char* key, uint32_t keylen, char* data, uint32_t datalen ) {
return load_str( scope, code, table, key, keylen, data, datalen );
}

static int32_t next( AccountName scope, AccountName code, TableName table, char* key, uint32_t keylen, char* data, uint32_t datalen ) {
return next_str( scope, code, table, key, keylen, data, datalen );
}

static int32_t previous( AccountName scope, AccountName code, TableName table, char* key, uint32_t keylen, char* data, uint32_t datalen ) {
return previous_str( scope, code, table, key, keylen, data, datalen );
}

static int32_t lower_bound( AccountName scope, AccountName code, TableName table, char* key, uint32_t keylen, char* data, uint32_t datalen ) {
return lower_bound_str( scope, code, table, key, keylen, data, datalen );
}

static int32_t upper_bound( AccountName scope, AccountName code, TableName table, char* key, uint32_t keylen, char* data, uint32_t datalen ) {
return upper_bound_str( scope, code, table, key, keylen, data, datalen );
}

static int32_t remove( AccountName scope, TableName table, char* key, uint32_t keylen ) {
return remove_str( scope, table, key, keylen );
}
};


template<AccountName scope, AccountName code, TableName table, typename PrimaryType>
struct VarTable {
private:
typedef table_impl_obj<PrimaryType> impl;

public:
typedef PrimaryType Primary;

int32_t store( Primary key, uint32_t keylen, char* record, uint32_t len ) {
return impl::store( scope, table, key, keylen, record, len );
}

int32_t update( Primary key, uint32_t keylen, char* record, uint32_t len ) {
return impl::update( scope, table, key, keylen, record, len );
}

int32_t front( char* record, uint32_t len ) {
return impl::front( scope, code, table, record, len );
}

int32_t back( char* record, uint32_t len ) {
return impl::back( scope, code, table, record, len );
}

int32_t load( Primary key, uint32_t keylen, char* record, uint32_t len ) {
return impl::load( scope, code, table, key, keylen, record, len );
}

int32_t next( Primary key, uint32_t keylen, char* record, uint32_t len ) {
return impl::next( scope, code, table, key, keylen, record, len );
}

int32_t previous( Primary key, uint32_t keylen, char* record, uint32_t len ) {
return impl::previous( scope, code, table, key, keylen, record, len );
}

int32_t lower_bound( Primary key, uint32_t keylen, char* record, uint32_t len ) {
return impl::lower_bound( scope, code, table, key, keylen, record, len );
}

int32_t upper_bound( Primary key, uint32_t keylen, char* record, uint32_t len ) {
return impl::upper_bound( scope, code, table, key, keylen, record, len );
}

int32_t remove( Primary key, uint32_t keylen ) {
return impl::remove( scope, table, key, keylen );
}
};

template<int Primary, int Secondary>
struct table_impl{};

Expand Down
1 change: 1 addition & 0 deletions contracts/test_api/test_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ extern "C" {
WASM_TEST_HANDLER(test_db, key_i64i64i64_general);
WASM_TEST_HANDLER(test_db, key_i128i128_general);
WASM_TEST_HANDLER(test_db, key_str_general);
WASM_TEST_HANDLER(test_db, key_str_table);

//test crypto
WASM_TEST_HANDLER(test_crypto, test_sha256);
Expand Down
3 changes: 2 additions & 1 deletion contracts/test_api/test_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ struct test_db {
static unsigned int key_i128i128_general();
static unsigned int key_i64i64i64_general();
static unsigned int key_str_general();
static unsigned int key_str_table();
};

struct test_crypto {
Expand All @@ -122,4 +123,4 @@ struct test_transaction {

struct test_chain {
static unsigned int test_activeprods();
};
};
100 changes: 98 additions & 2 deletions contracts/test_api/test_db.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <eoslib/types.hpp>
#include <eoslib/message.hpp>
#include <eoslib/db.h>

#include <eoslib/db.hpp>
#include "test_api.hpp"

int primary[11] = {0,1,2,3,4,5,6,7,8,9,10};
Expand Down Expand Up @@ -67,6 +67,102 @@ extern "C" {
bool my_memcmp(void *s1, void *s2, uint32_t n);
}

unsigned int test_db::key_str_table() {

const char* keys[] = { "alice", "bob", "carol", "dave" };
const char* vals[] = { "data1", "data2", "data3", "data4" };

const char* atr[] = { "atr", "atr", "atr", "atr" };
const char* ztr[] = { "ztr", "ztr", "ztr", "ztr" };

VarTable<N(tester), N(tester), N(atr), char*> StringTableAtr;
VarTable<N(tester), N(tester), N(ztr), char*> StringTableZtr;
VarTable<N(tester), N(tester), N(str), char*> StringTableStr;

uint32_t res = 0;

// fill some data in contiguous tables
for( int ii = 0; ii < 4; ++ii ) {
res = StringTableAtr.store( (char*)keys[ii], STRLEN(keys[ii]), (char*)atr[ii], STRLEN(atr[ii]) );
WASM_ASSERT( res != 0, "atr" );

res = StringTableZtr.store( (char*)keys[ii], STRLEN(keys[ii]), (char*)ztr[ii], STRLEN(ztr[ii]) );
WASM_ASSERT(res != 0, "ztr" );
}

char tmp[64];

res = StringTableStr.store ((char *)keys[0], STRLEN(keys[0]), (char *)vals[0], STRLEN(vals[0]));
WASM_ASSERT(res != 0, "store alice" );

res = StringTableStr.store((char *)keys[1], STRLEN(keys[1]), (char *)vals[1], STRLEN(vals[1]) );
WASM_ASSERT(res != 0, "store bob" );

res = StringTableStr.store((char *)keys[2], STRLEN(keys[2]), (char *)vals[2], STRLEN(vals[2]) );
WASM_ASSERT(res != 0, "store carol" );

res = StringTableStr.store((char *)keys[3], STRLEN(keys[3]), (char *)vals[3], STRLEN(vals[3]) );
WASM_ASSERT(res != 0, "store dave" );

res = StringTableStr.load((char *)keys[0], STRLEN(keys[0]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[0]) && my_memcmp((void *)vals[0], (void *)tmp, res), "load alice");

res = StringTableStr.load((char *)keys[1], STRLEN(keys[1]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[1]) && my_memcmp((void *)vals[1], (void *)tmp, res), "load bob");

res = StringTableStr.load((char *)keys[2], STRLEN(keys[2]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[2]) && my_memcmp((void *)vals[2], (void *)tmp, res), "load carol");

res = StringTableStr.load((char *)keys[3], STRLEN(keys[3]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[3]) && my_memcmp((void *)vals[3], (void *)tmp, res), "load dave");

res = StringTableStr.previous((char *)keys[3], STRLEN(keys[3]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[2]) && my_memcmp((void *)vals[2], (void *)tmp, res), "back carol");

res = StringTableStr.previous((char *)keys[2], STRLEN(keys[2]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[1]) && my_memcmp((void *)vals[1], (void *)tmp, res), "back dave");

res = StringTableStr.previous((char *)keys[1], STRLEN(keys[1]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[0]) && my_memcmp((void *)vals[0], (void *)tmp, res), "back alice");

res = StringTableStr.previous((char *)keys[0], STRLEN(keys[0]), tmp, 64);
WASM_ASSERT(res == -1, "no prev");

res = StringTableStr.next((char *)keys[0], STRLEN(keys[0]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[1]) && my_memcmp((void *)vals[1], (void *)tmp, res), "next bob");

res = StringTableStr.next((char *)keys[1], STRLEN(keys[1]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[2]) && my_memcmp((void *)vals[2], (void *)tmp, res), "next carol");

res = StringTableStr.next((char *)keys[2], STRLEN(keys[2]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[3]) && my_memcmp((void *)vals[3], (void *)tmp, res), "next dave");

res = StringTableStr.next((char *)keys[3], STRLEN(keys[3]), tmp, 64);
WASM_ASSERT(res == -1, "no next");

res = StringTableStr.next((char *)keys[0], STRLEN(keys[0]), tmp, 0);
WASM_ASSERT(res == 0, "next 0");

res = StringTableStr.front(tmp, 64);
WASM_ASSERT(res == STRLEN(vals[0]) && my_memcmp((void *)vals[0], (void *)tmp, res), "front alice");

res = StringTableStr.back(tmp, 64);
WASM_ASSERT(res == STRLEN(vals[3]) && my_memcmp((void *)vals[3], (void *)tmp, res), "back dave");

res = StringTableStr.lower_bound((char *)keys[0], STRLEN(keys[0]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[0]) && my_memcmp((void *)vals[0], (void *)tmp, res), "lowerbound alice");

res = StringTableStr.upper_bound((char *)keys[0], STRLEN(keys[0]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[1]) && my_memcmp((void *)vals[1], (void *)tmp, res), "upperbound bob");

res = StringTableStr.lower_bound((char *)keys[3], STRLEN(keys[3]), tmp, 64);
WASM_ASSERT(res == STRLEN(vals[3]) && my_memcmp((void *)vals[3], (void *)tmp, res), "upperbound dave");

res = StringTableStr.upper_bound((char *)keys[3], STRLEN(keys[3]), tmp, 64);
WASM_ASSERT(res == -1, "no upper_bound");

return WASM_TEST_PASS;
}

unsigned int test_db::key_str_general() {

Expand Down Expand Up @@ -981,4 +1077,4 @@ unsigned int test_db::key_i128i128_general() {
return WASM_TEST_PASS;
}

//eos::print("xxxx ", res, " ", tmp2.name, " ", uint64_t(tmp2.age), " ", tmp2.phone, " ", tmp2.new_field, "\n");
//eos::print("xxxx ", res, " ", tmp2.name, " ", uint64_t(tmp2.age), " ", tmp2.phone, " ", tmp2.new_field, "\n");