Cursor, seek by key

45 views
Skip to first unread message

Sergei Potapenko

unread,
Sep 29, 2016, 10:06:28 AM9/29/16
to Sophia database
I created three keys, and seek resource parameters by keys 'uri' and 'id' (like RESTful service)
See code below (based on original example):

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <assert.h>

#include "sophia.h"

int main(int argc, char *argv[])
{
   
(void)argc;
   
(void)argv;

   
/* open or create environment and database */
   
void *env = sp_env();
    sp_setstring
(env, "sophia.path", "./sophia", 0);
    sp_setstring
(env, "db", "restful", 0);
    sp_setstring
(env, "db.restful.scheme", "uri", 0);
    sp_setstring
(env, "db.restful.scheme", "id", 0);
    sp_setstring
(env, "db.restful.scheme", "key", 0);
    sp_setstring
(env, "db.restful.scheme", "value", 0);
    sp_setstring
(env, "db.restful.scheme.uri",  "string,key(0)", 0);
    sp_setstring
(env, "db.restful.scheme.id",   "u32,key(1)", 0);
    sp_setstring
(env, "db.restful.scheme.key",  "string,key(2)", 0);
    sp_setstring
(env, "db.restful.scheme.value", "string", 0);

   
void *db = sp_getobject(env, "db.restful");

   
int rc = sp_open(env);

   
if (rc == -1)
       
goto error;

   
/* set */
   
char* uri[] = { "user", "note", "comment"};
   
char* key[] = { "name", "type", "class"};
   
char  val[256] ={0};

   
for (int i = 0; i < 3; i++)
   
{
       
for (int j = 0; j < 3; j++)
       
{
           
for (int k = 0; k < 3; k++)
           
{
               
void *o = sp_document(db);
                sp_setstring
(o, "uri",  uri[i], 0);
                sp_setint
(o, "id", j);
                sp_setstring
(o, "key",  key[k], 0);

                sprintf
(val, "%s/%"PRIu32"/%s", uri[i], j, key[k]);

               
//fprintf(stderr, "%s\n", val);

                sp_setstring
(o, "value",  val, 0);
                rc
= sp_set(db, o);
               
if (rc == -1)
                   
goto error;
           
}
       
}
   
}

   
/* do forward iteration */
   
void *cursor = sp_cursor(env);
    o
= sp_document(db);
   
//sp_setstring(o, "order", "=", 0);
    sp_setstring
(o, "uri", "user", 0);
    sp_setint
(o, "id", 1);
   
while ((o = sp_get(cursor, o)))
   
{
       
int sz;
       
char* ptr = sp_getstring(o, "value", &sz);
       
int id = sp_getint(o, "id");

       
if(ptr)
       
{
            memcpy
(val, ptr, sz);
            val
[sz]=0;
            fprintf
(stderr, "[%"PRIu32"] = %s\n", id, val);
       
};
   
}
    sp_destroy
(cursor);

   
/* finish work */
    sp_destroy
(env);
   
return 0;

error
:
   
;
   
int size;
   
char *error = sp_getstring(env, "sophia.error", &size);
    printf
("error: %s\n", error);
    free
(error);
    sp_destroy
(env);
   
return 1;
}

I expect to see:
[1] = user/1/class
[1] = user/1/name
[1] = user/1/type

but realy I see:
[1] = user/1/class
[1] = user/1/name
[1] = user/1/type
[2] = user/2/class
[2] = user/2/name
[2] = user/2/type

How to seek items by key? By two keys?
Where can I read further about cursors? I have read here: http://charlesleifer.com/blog/announcing-sophy-fast-python-bindings-for-sophia-database/

Thank you, BR

Dmitry Simonenko

unread,
Sep 30, 2016, 5:12:19 AM9/30/16
to Sophia database
Hi,

When multi-part key is not completely specified (and order is default, which is '=') then cursor will be automatically set to >= and non-specified part will be assumed minimal value for the field-type. In other words, sophia will position its cursor for key { a, b, MIN }.

If you need to return only first record which matches non-complete key, you may try to stop iteration after first sp_get(cursor) invocation or you can try not to use cursors and ask database directly, like this:

void *key = sp_document(db);
sp_setstring
(key, "uri", ...);
sp_setstring
(key, "id", ...);
sp_setstring
(key, "order", ">=");
void *result = sp_get(key);
if (result) {
   
/* will return first record which matches uri and id */
   sp_destroy
(result);
}


Cursor usage documentation is here: http://sophia.systems/v2.2/crud/cursors.html but yet it
might be not complete and lack of such examples, sorry.
Reply all
Reply to author
Forward
0 new messages