bg

Sample Client Application

chevron

Sample client application for BangDB Server

This is just a sample client application for BangDB. It covers few basic features in simple sense, but would help user understand and build their own application.

There are follow 3 basic steps to write application;

1. Get BangDB Environment and database 2. Create tables, indexes, stream etc... and perform operations 3. Close environment
The client for BangDB is written in C/C++ and it does lot more than simply sending and receiving data over the tcp.

C++

Selected

Java

Selected

Let's first create the env and db object

        
        DBParam dpm;
        dpm.setTransactionType(DB_TRANSACTION_NONE);
        #ifdef _BANGDB_SSL_
        dpm.setSecureConn(true);
        #endif
        BangDBEnv *env = new BangDBEnv(&dpm);
        BangDBDatabase *bdb = new BangDBDatabase("mydb", env, &dpm);
Now we need table to start the operations
        TableEnv te;
        te.setTableType(NORMAL_TABLE);
        te.setKeySize(24);      // default key is string type, hence we can set the size of the key
        BangDBTable *t1 = bdb->getTable("normal_table", &te, OPENCREATE);   // Open or create
        if(!t1)
        {
                printf("normal table creation failed\n");
                return -1;
        }
let’s get the db description and print
        const char *db_desc = NULL;
        db_desc = bdb->getStats(true);
        if(!db_desc)
        {
                printf("getStats for db failed\n");
                return -1;
        }
        else
        {
                printf("getStats for db returns following:\n%s\n", db_desc);
                delete[] db_desc;
        }
we may get the table description as well
        const char *tbl_desc = t1->getStats(true);
        if(!tbl_desc)
        {
                printf("table desc failed\n");
                return -1;
        }
        else
        {
                printf("getStats for normal table returns following:\n%s\n", tbl_desc);
                delete[] tbl_desc;
        }
now let's put some data and read it
        bool flag = true;

        // let’s put some key and value
        FDT k("my_key1", 7), v("my_val1", 7);
        if(t1->put(&k, &v, INSERT_UNIQUE) < 0)
        {
                printf("put in the normal table failed\n");
                flag = false;
        }

        FDT *ov = NULL;
        if(t1->get(&k, &ov) < 0)
        {
                printf("get in the normal table failed\n");
                flag = false;
        }
        else
        {
                printf("1. key = %s, val = %s\n", (char*)k.data, (char*)ov->data);
                ov->free();
        }

use the previous key with INSERT_UNIQUE flag and it should return 1, which means key already exists
        v.data = (char*)"my_val1_update";
        v.length = 14;
        if(t1->put(&k, &v, INSERT_UNIQUE) != 1)   // unique put should fail here as key exists
        {
                printf("update in the normal table failed as it put unique data\n");
                flag = false;
        }

        // we may call put with INSERT_UPDATE to update the existing key
        if(t1->put(&k, &v, INSERT_UPDATE) < 0)
        {
                printf("update in the normal table failed as it could not update the key\n");
                flag = false;
        }

        ov = NULL;
        if(t1->get(&k, &ov) < 0)
        {
                printf("get in the normal table failed\n");
                flag = false;
        }
        else
        {
                printf("2. key = %s, val = %s\n", (char*)k.data, (char*)ov->data);
                ov->free();
        }
delete the key now
        if(t1->del(&k) < 0)
        {
                printf("del in normal table failed\n");
                flag = false;
        }

        // try to get the deleted key, you should get -1 else it’s error
        ov = NULL;
        if(t1->get(&k, &ov) >= 0)
        {
                printf("del error\n");
                flag = false;
        }
        if(ov)
        {
                printf("get in the normal table failed as it got the deleted key\n");
                flag = false;
        }
scan the table now
        ResultSet *rs = NULL;
        ScanFilter sf;
        int nc = 0;
        // since there could be large amount of data and hence we may need to
        // scan multiple times in order to get the data
        // therefore we need to call scan recursively
        // BangDB simplifies this completely and allows user to call like following;
        // Note; you may add other args as well as needed
        printf("Scanning for table t1\n");
        while(true)
        {
                rs = t1->scan(rs, NULL, NULL, &sf);
                if(!rs)
                        break;
                nc += rs->count();
                while(rs->hasNext())
                {
                        // since this table has key and val as string hence can call these to print
                        printf("key = %s, val = %s\n", rs->getNextKeyStr(), rs->getNextValStr());
                        rs->moveNext();
                }
        }
        printf("num of scanned items for table t1 = %d\n", nc);
create a normal table with long as key
        te.reset();
        te.setTableType(NORMAL_TABLE);
        te.setKeyType(NORMAL_KEY_LONG);    // key is long now, not string, hence key_size is not needed
        BangDBTable *t2 = bdb->getTable("normal_table_long", &te, OPENCREATE);
        if(!t2)
        {
                printf("normal table creating failed\n");
                return -1;
        }

        // put key val
        long lv = 1;
        FDT k2(lv, 8), v2("my_val_long1", 12);
        if(t2->put(&k2, &v2, INSERT_UNIQUE) < 0)
        {
                printf("put in the normal table failed\n");
                flag = false;
        }

        // get the val for the given key
        ov = NULL;
        if(t2->get(&k2, &ov) < 0)
        {
                printf("get in the normal table failed\n");
                flag = false;
        }
        else
        {
                printf("3. key = %ld, val = %s\n", (long)k2.data, (char*)ov->data);
                ov->free();
        }
drop a table now
there are two ways to do this
1. Call dropTable() on BangDBDatabse
2. Close the table and tell server to clean close it - I.e. delete everything for the table
let’s drop the table using 2
        if(t1->closeTable(CLEANCLOSE_AT_SERVER) < 0)
        {
                printf("failed to drop the table t1\n");
                flag = false;
        }
        delete t1;

        // check if it exists
        if(bdb->doesTableExist("normal_table"))
        {
                printf("table normal_table exists after dropping it\n");
                flag = false;
        }
let’s create wide table now, table that deals with json doc, but it can also store simple text
        te.reset();
        te.setTableType(WIDE_TABLE);
        te.setKeyType(NORMAL_KEY_LONG);         // let’s use long key
        te.setAllowDuplicate(true);                     // dupl key is allowed
        te.setVersionType(BANGDB_DATA_VERSION_VALID_INVALID);   // this will maintain versions, usually we should do this

        BangDBTable *t3 = bdb->getTable("my_wide_table1", &te, OPENCREATE);
        if(!t3)
        {
                printf("wide table could not be created\n");
                return -1;
        }
put few keys and vals and get them
        FDT wk1(111, 8), wk2(222, 8), wk3(333, 8);
        FDT wv1("wide val 1", 10), wv2("wide val 2", 10), wv3("wide val 3", 10);
        if(t3->put(&wk1, &wv1, INSERT_UNIQUE) < 0)
        {
                printf("put for widetable failed\n");
                flag = false;
        }

        if(t3->put(&wk2, &wv2, INSERT_UNIQUE) < 0)
        {
                printf("put for widetable failed\n");
                flag = false;
        }

        if(t3->put(&wk3, &wv3, INSERT_UNIQUE) < 0)
        {
                printf("put for widetable failed\n");
                flag = false;
        }

         wv1.data = (char*)"wide_val_1_up";
         wv1.length = 13;
        if(t3->put(&wk1, &wv1, INSERT_UNIQUE) < 0)
        {
                printf("put for widetable failed\n");
                flag = false;
        }

        FDT *wov = NULL;
        if(t3->get(&wk1, &wov) < 0)
        {
                printf("get failed for wide table\n");
                flag = false;
        }
        else
        {
                printf("4. key = %d, val = %s\n", 111, (char*)wov->data);
                wov->free();
                delete wov;
        }
scan for some key range - this will recursively scan until all keys and values are scanned
        rs = NULL;
        sf.reset();
        nc = 0;
        printf("Scanning for table t3\n");
        while(true)
        {
                rs = t3->scan(rs, &wk1, &wk3, &sf);
                if(!rs)
                        break;
                nc += rs->count();
                while(rs->hasNext())
                {
                        printf("key = %ld, val = %s\n", rs->getNextKeyLong(), rs->getNextValStr());
                        rs->moveNext();
                }
        }
        printf("num of scanned items for table t3 = %d\n", nc);
may count number of keys as well, with or without range
        printf("total num of elements in t3 = %ld\n", t3->count());
        printf("num of elements between wk2 and wk3 in t3 = %ld\n", t3->count(&wk2, &wk3));
try now with json doc - usually we should only put docs or non-docs, mixing may not be very logical, hence let’s create new wide table
        te.reset();
        te.setAllowDuplicate(true);
        te.reset();
        te.setTableType(WIDE_TABLE);
        te.setKeyType(NORMAL_KEY_LONG);
        te.setAllowDuplicate(true);
        te.setVersionType(BANGDB_DATA_VERSION_VALID_INVALID);

        BangDBTable *t4 = bdb->getTable("my_wide_table2", &te, OPENCREATE);
        if(!t4)
        {
                printf("wide table t4 could not be created\n");
                return -1;
        }
Add few indexes
        // this one creates an index on string type field where max size is 16 bytes
        if(t4->addIndex_str("org", 16, true) < 0)
        {
                printf("error in adding index org\n");
                flag = false;
        }

        // this one creates an index on string type field where max size is 24 bytes
        // note, it’s a nested index
        if(t4->addIndex_str("family.favsport", 24, true) < 0)
        {
                printf("error in adding index family.favsport\n");
                flag = false;
        }
now let's put some docs
        const char *doc1 = "{\"name\":\"sachin sinha\", \"org\":\"iqlect\", \"likes\":[\"music\", \"sports\", \"movies\"], \"family\":{\"wife\":\"vijeta\", \"father\":\"k m n sinha\",\"favsport\":\"cricket\"}}";

        const char *doc2 = "{\"name\":\"mukesh prasad singh\", \"org\":\"zopsmart\", \"likes\":[\"tech\", \"sports\", \"movies\"], \"family\":{\"wife\":\"julie\", \"father\":\"p prasad\",\"favsport\":\"football\"}}";

        const char *doc3 = "{\"name\":\"aman thakur\", \"org\":\"google\", \"likes\":[\"investment\", \"ping pong\", \"movies\"], \"family\":{\"wife\":\"koyal\", \"father\":\"h thakur\",\"favsport\":\"cricket\"}}";

        const char *doc4 = "{\"name\":\"arjun\", \"org\":\"nps\", \"likes\":[\"music\", \"video games\", \"movies\"], \"family\":{\"father\":\"Sachin Sinha\", \"mother\":\"vijeta\",\"favsport\":\"cricket\"}}";

        if(t4->putDoc(doc1) < 0)         // note we are not supplying any key, in this case db will pick timestamp (in microsec) as the key
        {
                printf("put failed for doc1\n");
                flag = false;
        }

        if(t4->putDoc(doc2) < 0)
        {
                printf("put failed for doc2\n");
                flag = false;
        }

        if(t4->putDoc(doc3) < 0)
        {
                printf("put failed for doc3\n");
                flag = false;
        }

        if(t4->putDoc(doc4) < 0)
        {
                printf("put failed for doc4\n");
                flag = false;
        }
let’s define some query for which we wish to scan the data, query selects data where "org=iqlect"
        DataQuery dq;
        const char *idx_query;
        dq.addQuery("org", EQ, "iqlect", JO_INVALID);   // select all where org = Iqlect
        idx_query = dq.getQuery();
        rs = NULL; // must set it to null
        sf.reset();
        nc = 0;
        printf("Scan query : select * from t4 where org = iqlect\n");
        while(true)
        {
                if((rs = t4->scanDoc(rs, NULL, NULL, idx_query, &sf)) == NULL)  // note scanDoc() here and not scan()
                        break;
                nc += rs->count();
                while(rs->hasNext())
                {
                        printf("key = %ld, val = %s\n", rs->getNextKeyLong(), rs->getNextValStr());
                        rs->moveNext();
                }
        }
        printf("num of scanned items for table t4 (select * from t4 where org = iqlect) = %d\n", nc);
now select all where family favsports = cricket.
        dq.reset();
        dq.addQuery("family.favsport",  EQ, "cricket", JO_INVALID);
        idx_query = dq.getQuery();
        rs = NULL; // must set it to null
        sf.reset();
        nc = 0;
        printf("Scanning query : select * from t4 where family.favsport = cricket\n");
        while(true)
        {
                if((rs = t4->scanDoc(rs, NULL, NULL, idx_query, &sf)) == NULL)
                        break;
                nc += rs->count();
                while(rs->hasNext())
                {
                        printf("key = %ld, val = %s\n", rs->getNextKeyLong(), rs->getNextValStr());
                        rs->moveNext();
                }
        }
        printf("num of scanned items for table t4 (select * from t4 where family.favsport = cricket) = %d\n", nc);
we can simply count with filter/query as well
         printf("t4 count for filter based scan = %ld with total count = %ld\n", t4->count(NULL, NULL, idx_query, &sf), t4->count());
Let's check number of tables in the db
        printf("num of tables in the db = %ld\n", bdb->getNumTables());

        printf("does table t3 exist? ans = %s\n", bdb->doesTableExist("my_wide_table1") ? "yes" : "no");

        printf("does table t1 exist? ans = %s\n", bdb->doesTableExist("normal_table") ? "yes" : "no");
get all table list and print - note you will get these tables in describe database or describe table api calls as well
        const char *tbl_list = bdb->getTableList();

        if(!tbl_list)
        {
                printf("tbl list is NULL\n");
                flag = false;
        }
        else
        {
                printf("table list = \n%s\n", tbl_list);
                delete[] tbl_list;
        }
drop the "org" index and put some value and then scan using index
        if(t4->dropIndex("org") < 0)
        {
                printf("drop index failed for index org\n");
                flag = false;
        }
now we can still put docs and query for index "org", even though it's not there, db would still fetch the results for the query. Index helps the performance of query however it's not needed for the query
        const char *doc5 = "{\"name\":\"raj\", \"org\":\"iqlect\", \"likes\":[\"music\", \"sprots\", \"movies\"], \"family\":{\"wife\":\"richa pandey\", \"father\":\"kevin\", \"mother\":\"latika\"}}";
        if(t4->putDoc(doc5) < 0)
        {
                printf("put failed for doc5\n");
                flag = false;
        }

        printf("........ scan again for org index = iqlect .......\n");

        dq.reset();
        dq.addQuery("org", EQ, "iqlect", JO_INVALID);
        idx_query = dq.getQuery();
        rs = NULL; // must set it to null
        sf.reset();
        nc = 0;
        printf("Scan query - select * from t4 where org = iqlect\n");
        while(true)
        {
                if((rs = t4->scanDoc(rs, NULL, NULL, idx_query, &sf)) == NULL)
                        break;
                nc += rs->count();
                while(rs->hasNext())
                {
                        printf("key = %ld, val = %s\n", rs->getNextKeyLong(), rs->getNextValStr());
                        rs->moveNext();
                }
        }
        printf("num of scanned items for table t4 (select * from t4 where org = iqlect) = %d\n", nc);
you may close the table when done or in the end when you close database, all tables get closed as well
        if(t2->closeTable() < 0)
        {
                printf("normal closeTable failed\n");
                flag = false;
        }
        delete t2;    // even if you don’t close the table, it’s a good practice to delete the table object, db won’t clean this object, will just close the table
close the db, it will close all other db resources as well
        env->closeDatabase(bdb, CLEANCLOSE_AT_SERVER);
        delete bdb;
        delete env;
        printf("test %s\n", flag ? "passed" : "failed");
        return flag ? 0 : -1;
You can download the sample test file and run.

Load the lib and create the env and db

                System.loadLibrary("bangdb-client-java");
                DBParam dbp = new DBParam();
                dbp.set_port("10101");
                dbp.set_host("127.0.0.1");
                dbp.setTransactionType(TransactionType.DB_MULTIOPS_TRANSACTION_NONE);
                BangDBEnv dbenv = new BangDBEnv(dbp);
                BangDBDatabase bdb = new BangDBDatabase("mydb", dbenv, dbp);
let's create a normal table, note for normal table val is opaque
                TableEnv te = new TableEnv();
                te.setTableType(TableType.NORMAL_TABLE);
                te.setKeySize(24);      // default key is String type, hence we can set the size of the key
                BangDBTable t1 = bdb.getTable("normal_table", te, OpenType.OPENCREATE);   // Open or create
                if(t1 == null)
                {
                        System.out.print("normal table creating failed\n");
                        return -1;
                }
let’s get the db description and print
                String db_desc = null;
                db_desc = bdb.getStats(true);
                if(db_desc == null)
                {
                        System.out.print("getStats for db failed\n");
                        return -1;
                }
                else
                {
                        System.out.print("getStats for db returns following:\n" + db_desc);
                }

                // we may get the table description as well
                String tbl_desc = t1.getStats(true);
                if(tbl_desc == null)
                {
                        System.out.print("table desc failed\n");
                        return -1;
                }
                else
                {
                        System.out.print("getStats for normal table returns following:\n" + tbl_desc);
                }
let’s put some key and value
                String key = "my_key1";
                String val = "my_val1";
                if(t1.put(key, val.getBytes(), InsertOptions.INSERT_UNIQUE, null) < 0)
                {
                        System.out.print("put in the normal table failed\n");
                        flag = false;
                }

                byte[] ov = null;
                if((ov = t1.get(key, null)) == null)
                {
                        System.out.print("get in the normal table failed\n");
                        flag = false;
                }
                else
                {
                        System.out.println("1. key = " + key + " val = " + new String(ov));
                }
use the previous key to inter unique, it should return 1, which means key already exists, also when called get(), it will return the updated data
                val = "my_val1_update";
                if(t1.put(key, val.getBytes(), InsertOptions.INSERT_UNIQUE, null) != 1)   // unique put should fail here as key exists
                {
                        System.out.print("update in the normal table failed as it put unique data\n");
                        flag = false;
                }

                // we may call put with INSERT_UPDATE to update the existing key
                if(t1.put(key, val.getBytes(), InsertOptions.INSERT_UPDATE, null) < 0)
                {
                        System.out.print("update in the normal table failed as it could not update the key\n");
                        flag = false;
                }

                ov = null;
                if((ov = t1.get(key, null)) == null)
                {
                        System.out.print("get in the normal table failed\n");
                        flag = false;
                }
                else
                {
                        System.out.println("1. key = " + key + " val = " + new String(ov));
                }
delete the key now
                if(t1.del(key, null) < 0)
                {
                        System.out.print("del in normal table failed\n");
                        flag = false;
                }

                // try to get the deleted key, you should get -1 else it’s error
                ov = null;
                if((ov = t1.get(key, null)) != null)
                {
                        System.out.print("del error\n");
                        flag = false;
                }
                if(ov != null)
                {
                        System.out.print("get in the normal table failed as it got the deleted key\n");
                        flag = false;
                }
scan the table now
                ResultSet rs = null;
                ScanFilter sf = new ScanFilter();
                String sk = null;
                int nc = 0;
                // since there could be large amount of data and hence we may need to
                // scan multiple times in order to get the data
                // therefore we need to call scan recursively
                // BangDB simplifies this completely and allows user to call like following;
                // Note; you may add other args as well as needed
                System.out.print("Scanning for table t1\n");
                while(true)
                {
                        rs = t1.scan(rs, sk, null, sf, null);
                        if(rs == null)
                                break;
                        nc += rs.count();
                        while(rs.hasNext())
                        {
                                System.out.println("key = " + new String(rs.getNextKey()) + "val = " + new String(rs.getNextVal()));
                                rs.moveNext();
                        }
                }
                System.out.println("num of scanned items for table t1 = "+ nc);
create a normal table with long as key
                te.reset();
                te.setTableType(TableType.NORMAL_TABLE);
                te.setKeyType(KeyType.NORMAL_KEY_LONG);    // key is long now, not String, hence key_size is not needed
                BangDBTable t2 = bdb.getTable("normal_table_long", te, OpenType.OPENCREATE);
                if(t2 == null)
                {
                        System.out.print("normal table creating failed\n");
                        return -1;
                }
put key val
                long lk = 1;
                val = "my_val_long1";
                if(t2.put(lk, val.getBytes(), InsertOptions.INSERT_UNIQUE, null) < 0)
                {
                        System.out.print("put in the normal table failed\n");
                        flag = false;
                }

                // get the val for the given key
                ov = null;
                if((ov = t2.get(lk, null)) == null)
                {
                        System.out.print("get in the normal table failed\n");
                        flag = false;
                }
                else
                {
                        System.out.println("3. key = " + lk + " val = " + new String(ov));
                }
drop a table now
there are two ways to do this
1. Call dropTable() on BangDBDatabse
2. Close the table and tell server to clean close it - I.e. delete everything for the table
Let’s drop the table using 2
                if(t1.closeTable(CloseType.CLEANCLOSE_AT_SERVER, true) < 0)
                {
                        System.out.print("failed to drop the table t1\n");
                        flag = false;
                }

                // check if it exists
                if(bdb.doesTableExist("normal_table", 0))
                {
                        System.out.print("table normal_table exists after dropping it\n");
                        flag = false;
                }
let’s create wide table now, table that deals with json doc, but it can also store simple text
                te.reset();
                te.setTableType(TableType.WIDE_TABLE);
                te.setKeyType(KeyType.NORMAL_KEY_LONG);         // let’s use long key
                te.setAllowDuplicate(1);                        // dupl key is allowed
                te.setVersionType(VersionType.BANGDB_DATA_VERSION_VALID);   // this will maintain versions, usually we should do this

                BangDBTable t3 = bdb.getTable("my_wide_table1", te, OpenType.OPENCREATE);
                if(t3 == null)
                {
                        System.out.print("wide table could not be created\n");
                        return -1;
                }
put few keys and vals
                lk = 111;
                val = "wide val 1";
                if(t3.put(lk, val.getBytes(), InsertOptions.INSERT_UNIQUE, null) < 0)
                {
                        System.out.print("put for widetable failed\n");
                        flag = false;
                }

                lk = 222;
                val = "wide val 2";
                if(t3.put(lk, val.getBytes(), InsertOptions.INSERT_UNIQUE, null) < 0)
                {
                        System.out.print("put for widetable failed\n");
                        flag = false;
                }

                lk = 333;
                val = "wide val 3";
                if(t3.put(lk, val.getBytes(), InsertOptions.INSERT_UNIQUE, null) < 0)
                {
                        System.out.print("put for widetable failed\n");
                        flag = false;
                }

                lk = 111;
                val = "wide_val_1_up";
                if(t3.put(lk, val.getBytes(), InsertOptions.INSERT_UNIQUE, null) < 0)
                {
                        System.out.print("put for widetable failed\n");
                        flag = false;
                }

                ov = null;
                if((ov = t3.get(lk, null)) == null)
                {
                        System.out.print("get failed for wide table\n");
                        flag = false;
                }
                else
                {
                        System.out.println("4. key = " + lk + " val = " + new String(ov));
                }
scan for some key range - this will recursively scan until all keys and values are scanned
                rs = null;
                sf.reset();
                nc = 0;
                long lk1 = 111, lk3 = 333;
                System.out.print("Scanning for table t3\n");
                while(true)
                {
                        rs = t3.scan(rs, lk1, lk3, sf, null);
                        if(rs == null)
                                break;
                        nc += rs.count();
                        while(rs.hasNext())
                        {
                                System.out.println("key = " + rs.getNextKeyLong() + " val = " + new String(rs.getNextVal()));
                                rs.moveNext();
                        }
                }
                System.out.println("num of scanned items for table t3 = " + nc);

                // may count number of keys as well, with or without range
                System.out.println("total num of elements in t3 = " + t3.count());
                long lk2 = 222;
                sf.reset();
                System.out.println("num of elements between lk2 and lk3 in t3 = " + t3.count(lk2, lk3, null, sf));
try now json doc - usually we should only put docs or non-docs, mixing may not be very logical
hence let’s create new wide table
                te.reset();
                te.setAllowDuplicate(1);
                te.reset();
                te.setTableType(TableType.WIDE_TABLE);
                te.setKeyType(KeyType.NORMAL_KEY_LONG);
                te.setAllowDuplicate(1);
                te.setVersionType(VersionType.BANGDB_DATA_VERSION_VALID);

                BangDBTable t4 = bdb.getTable("my_wide_table2", te, OpenType.OPENCREATE);
                if(t4 == null)
                {
                        System.out.print("wide table t4 could not be created\n");
                        return -1;
                }
Let's add few indexes as well
this one creates an index on String type field where max size is 16
                if(t4.addIndex_str("org", 16, true) < 0)
                {
                        System.out.print("error in adding index org\n");
                        flag = false;
                }

                // this one creates an index on String type field where max size is 24 bytes
                // note, it’s a nested index
                if(t4.addIndex_str("family.favsport", 24, true) < 0)
                {
                        System.out.print("error in adding index family.favsport\n");
                        flag = false;
                }
Let's add some data
                String doc1 = "{\"name\":\"sachin sinha\", \"org\":\"iqlect\", \"likes\":[\"music\", \"sports\", \"movies\"], \"family\":{\"wife\":\"vijeta\", \"father\":\"k m n sinha\",\"favsport\":\"cricket\"}}";

                String doc2 = "{\"name\":\"mukesh prasad singh\", \"org\":\"zopsmart\", \"likes\":[\"tech\", \"sports\", \"movies\"], \"family\":{\"wife\":\"julie\", \"father\":\"p prasad\",\"favsport\":\"football\"}}";

                String doc3 = "{\"name\":\"aman thakur\", \"org\":\"google\", \"likes\":[\"investment\", \"ping pong\", \"movies\"], \"family\":{\"wife\":\"koyal\", \"father\":\"h thakur\",\"favsport\":\"cricket\"}}";

                String doc4 = "{\"name\":\"arjun\", \"org\":\"nps\", \"likes\":[\"music\", \"video games\", \"movies\"], \"family\":{\"father\":\"Sachin Sinha\", \"mother\":\"vijeta\",\"favsport\":\"cricket\"}}";

                if(t4.putDoc(doc1, 0, null, InsertOptions.INSERT_UNIQUE) < 0)         // note we are not supplying any key, in this case db will pick timestamp (in microsec) as the key
                {
                        System.out.print("put failed for doc1\n");
                        flag = false;
                }

                if(t4.putDoc(doc2, 0, null, InsertOptions.INSERT_UNIQUE) < 0)
                {
                        System.out.print("put failed for doc2\n");
                        flag = false;
                }

                if(t4.putDoc(doc3, 0, null, InsertOptions.INSERT_UNIQUE) < 0)
                {
                        System.out.print("put failed for doc3\n");
                        flag = false;
                }

                if(t4.putDoc(doc4, 0, null, InsertOptions.INSERT_UNIQUE) < 0)
                {
                        System.out.print("put failed for doc4\n");
                        flag = false;
                }
let’s define some query for which we wish to scan the data. Let's use the query select * from t4 where "org" = "iqlect"
                DataQuery dq = new DataQuery();
                String idx_query = null;
                dq.addQuery("org", ScanOperator.EQ, "iqlect", JoinType.JO_INVALID);   // select all where org = Iqlect
                idx_query = dq.getQuery();
                rs = null; // must set it to null
                sf.reset();
                nc = 0;
                System.out.print("Scan query : select * from t4 where org = iqlect\n");
                while(true)
                {
                        if((rs = t4.scanDoc(rs, 0, 0, idx_query, sf)) == null)  // note scanDoc() here and not scan()
                                break;
                        nc += rs.count();
                        while(rs.hasNext())
                        {
                                System.out.println("key = " + rs.getNextKeyLong() + " val = " + new String(rs.getNextVal()));
                                rs.moveNext();
                        }
                }
                System.out.println("num of scanned items for table t4 (select * from t4 where org = iqlect) = " + nc);
now select all where family favsports = cricket.
                dq.reset();
                dq.addQuery("family.favsport",  ScanOperator.EQ, "cricket", JoinType.JO_INVALID);
                idx_query = dq.getQuery();
                rs = null; // must set it to null
                sf.reset();
                nc = 0;
                System.out.print("Scanning query : select * from t4 where family.favsport = cricket\n");
                while(true)
                {
                        if((rs = t4.scanDoc(rs, 0, 0, idx_query, sf)) == null)  // note scanDoc() here and not scan()
                                break;
                        nc += rs.count();
                        while(rs.hasNext())
                        {
                                System.out.println("key = " + rs.getNextKeyLong() + " val = " + new String(rs.getNextVal()));
                                rs.moveNext();
                        }
                }
                System.out.println("num of scanned items for table t4 (select * from t4 where family.favsport = cricket) = " + nc);
We can also count for the given query
System.out.println("t4 count for filter based scan = " + t4.count(null, null, idx_query, sf) + " with total count = " + t4.count());
Now, let's just check thetables
                System.out.println("num of tables in the db = " + bdb.getNumTables(3));

                System.out.println("does table t3 exist? ans = " + bdb.doesTableExist("my_wide_table1", 0));

                System.out.println("does table t1 exist? ans = " + bdb.doesTableExist("normal_table", 0));
get all table list and print - note you will get these tables in describe database or describe table api calls as well
                String tbl_list = bdb.getTableList();

                if(tbl_list == null)
                {
                        System.out.print("tbl list is null\n");
                        flag = false;
                }
                else
                {
                        System.out.println("table list = \n"+ tbl_list);
                }
drop the "org" index and put some value and then scan using index
                if(t4.dropIndex("org") < 0)
                {
                        System.out.print("drop index failed for index org\n");
                        flag = false;
                }
now we put the doc again, and search using same index.
and even though the index is deleted, db will still fetch the data for query that involves the index.
Note that, index is not needed for query to be successful, however index improves the performance significantly
                System.out.print("........ scan again for org index = iqlect .......\n");

                dq.reset();
                dq.addQuery("org", ScanOperator.EQ, "iqlect", JoinType.JO_INVALID);
                idx_query = dq.getQuery();
                rs = null; // must set it to null
                sf.reset();
                nc = 0;
                System.out.print("Scan query - select * from t4 where org = iqlect\n");
                while(true)
                {
                        if((rs = t4.scanDoc(rs, 0, 0, idx_query, sf)) == null)  // note scanDoc() here and not scan()
                                break;
                        nc += rs.count();
                        while(rs.hasNext())
                        {
                                System.out.println("key = " + rs.getNextKeyLong() + " val = " + new String(rs.getNextVal()));
                                rs.moveNext();
                        }
                }
                System.out.println("num of scanned items for table t4 (select * from t4 where org = iqlect) = " + nc);
you may close the table when done or in the end when you close database, all tables get closed as well
                if(t2.closeTable(CloseType.DEFAULT_AT_SERVER, false) < 0)
                {
                        System.out.print("normal closeTable failed\n");
                        flag = false;
                }
to close the db, simply call the closeDatabase(), this clears every other resources in the db
                dbenv.closeDatabase(CloseType.CLEANCLOSE_AT_SERVER);
                if(flag)
                        System.out.println("test passed");
                else
                        System.out.println("test failed");
                return flag ? 0 : -1;
You can download the sample and run