/* Should we stop iterating the database with this cursor? If so, destroy * the sophia cursor object, but leave intact its Python wrapper. */ static inline int sophia_stop_iteration(SophiaCursor *cursor) { if (!cursor->cursor || !sp_fetch(cursor->cursor)) { if (cursor->cursor) sophia_cursor_dealloc_internal(cursor); return 1; } return 0; }
int todo_db_foreach (todo_db_t *db, void (*fn)(char *key, char *value, todo_db_t *db)) { void *c = sp_cursor(db->dbh, SPGT, NULL, 0); if (NULL == c) { return -1; } while (sp_fetch(c)) { fn(strdup(sp_key(c)), strdup(sp_value(c)), db); } sp_destroy(c); return 0; }
sphia_iterator_node_t * sphia_iterator_next (sphia_iterator_t *self) { sphia_iterator_node_t *node = NULL; size_t keysize = 0; size_t valuesize = 0; const char *key = NULL; const char *value = NULL; if (NULL == self->cursor) { self->cursor = sp_cursor(self->db , self->direction , self->last_key , self->last_keysize); if (NULL == self->cursor) return NULL; } if (0 == sp_fetch(self->cursor)) return NULL; if (!(node = malloc(sizeof(sphia_iterator_node_t)))) return NULL; node->key = NULL; node->value = NULL; if (!(key = sp_key(self->cursor)) || !(value = sp_value(self->cursor))) { free(node); return NULL; } keysize = sp_keysize(self->cursor); valuesize = sp_valuesize(self->cursor); // record so we can create a // cursor at this position self->last_key = key; self->last_keysize = keysize; if (!(node->key = sphia_strdup(key)) || !(node->value = sphia_strdup(value))) { sphia_iterator_node_free(node); return NULL; } return node; }
static int rangefwd(int n) { void *c = sp_cursor(db, SPGTE, NULL, 0); if (c == NULL) { printf("cursor failed: %s\n", sp_error(db)); return 1; } while (sp_fetch(c)) { const char *k = sp_key(c); size_t sz = sp_valuesize(c); (void)k; (void)sz; keytraversed++; } sp_destroy(c); return 0; }
/* Count the number of records in the database. This is O(n) time, * and then absolutely inefficient, but keeping an up-to-date counter * of the records would require to check the existence of a record before * each insert or delete operation, which would be very costly at the end. */ static PyObject * sophia_db_count_records(SophiaDB *db) { size_t count = 0; ensure_is_opened(db, NULL); void *cur = sp_cursor(db->db, SPGT, NULL, 0); if (!cur) { PyErr_SetString(SophiaError, sp_error(db->db)); return NULL; } while ((sp_fetch(cur))) count++; sp_destroy(cur); return PyLong_FromSize_t(count); }
int todo_db_rm_each (todo_db_t *db, int (*fn)(char *key, char *value, todo_db_t *db)) { int rc = -1; int i = 0, l = 0; void *c = sp_cursor(db->dbh, SPGT, NULL, 0); const char *ckey; const char *cvalue; char *keys[512]; size_t sizes[512] = { }; size_t size; while (sp_fetch(c)) { ckey = sp_key(c); cvalue = sp_value(c); size = sp_keysize(c); rc = fn(strdup((char *) ckey), strdup((char *)cvalue), db); if (0 == rc) { keys[i++] = (char *)ckey; sizes[i] = size; if (-1 == rc) { return rc; } } } sp_destroy(c); l = i; i = 0; for (; i < l; ++i) { rc = sp_delete(db->dbh, (const char *)keys[i], strlen((const char*) keys[i])); if (-1 == rc) { return rc; } } return rc; }
char * todo_db_reduce (todo_db_t *db, char *(*fn)(char *curkey, char *curvalue, char *nextkey, char *nextvalue, todo_db_t *db)) { void *c = sp_cursor(db->dbh, SPGT, NULL, 0); char *reduced = NULL; char *tmp = ""; int i = 0; char *ckey, *cvalue; char *nkey, *nvalue; if (NULL == c) { return NULL; } while (sp_fetch(c)) { // next value if (i++ % 2) { nkey = strndup(sp_key(c), sp_keysize(c)); nvalue = strndup(sp_value(c), sp_valuesize(c)); reduced = fn(ckey, cvalue, nkey, nvalue, db); free(nkey); free(nvalue); } else { ckey = strdup(sp_key(c)); cvalue = strdup(sp_value(c)); } if (NULL != reduced) break; } if (NULL == reduced) { reduced = fn(ckey, cvalue, tmp, tmp, db); } sp_destroy(c); return reduced; }