static int database_cursor_open(libretrodb_t *db, libretrodb_cursor_t *cur, const char *path, const char *query) { const char *error = NULL; libretrodb_query_t *q = NULL; if ((libretrodb_open(path, db)) != 0) return -1; if (query) q = (libretrodb_query_t*)libretrodb_query_compile(db, query, strlen(query), &error); if (error) goto error; if ((libretrodb_cursor_open(db, cur, q)) != 0) goto error; if (q) libretrodb_query_free(q); return 0; error: if (q) libretrodb_query_free(q); libretrodb_close(db); return -1; }
static int db_query(lua_State *L) { int rv; libretrodb_cursor_t *cursor = NULL; libretrodb_t *db = checkdb(L); const char *query = luaL_checkstring(L, -1); const char *error = NULL; libretrodb_query_t *q = libretrodb_query_compile( db, query, strlen(query), &error); if (error) { lua_pushnil(L); lua_pushstring(L, error); } else { cursor = lua_newuserdata(L, sizeof(libretrodb_t)); if ((rv = libretrodb_cursor_open(db, cursor, q)) == 0) { luaL_getmetatable(L, "RarchDB.Cursor"); lua_setmetatable(L, -2); lua_pushnil(L); } else { lua_pop(L, 1); lua_pushnil(L); lua_pushstring(L, strerror(-rv)); } libretrodb_query_free(q); } return 2; }
/** * libretrodb_cursor_close: * @cursor : Handle to database cursor. * * Closes cursor and frees up allocated memory. **/ void libretrodb_cursor_close(libretrodb_cursor_t *cursor) { if (!cursor) return; close(cursor->fd); cursor->is_valid = 0; cursor->fd = -1; cursor->eof = 1; cursor->db = NULL; if (cursor->query) libretrodb_query_free(cursor->query); cursor->query = NULL; }
void *libretrodb_query_compile(libretrodb_t *db, const char *query, size_t buff_len, const char **error) { struct buffer buff; struct query *q = (struct query*)malloc(sizeof(struct query)); if (!q) goto clean; memset(q, 0, sizeof(struct query)); q->ref_count = 1; buff.data = query; buff.len = buff_len; buff.offset = 0; *error = NULL; buff = chomp(buff); if (peek(buff, "{")) { buff = parse_table(buff, &q->root, error); if (*error) goto clean; } else if (isalpha(buff.data[buff.offset])) buff = parse_method_call(buff, &q->root, error); buff = expect_eof(buff, error); if (*error) goto clean; if (!q->root.func) { raise_unexpected_eof(buff.offset, error); return NULL; } goto success; clean: if (q) libretrodb_query_free(q); success: return q; }
void *libretrodb_query_compile(libretrodb_t *db, const char *query, size_t buff_len, const char **error_string) { struct buffer buff; struct query *q = (struct query*)calloc(1, sizeof(*q)); if (!q) goto error; q->ref_count = 1; buff.data = query; buff.len = buff_len; buff.offset = 0; *error_string = NULL; buff = query_chomp(buff); if (query_peek(buff, "{")) { buff = query_parse_table(buff, &q->root, error_string); if (*error_string) goto error; } else if (isalpha((int)buff.data[buff.offset])) buff = query_parse_method_call(buff, &q->root, error_string); buff = query_expect_eof(buff, error_string); if (*error_string) goto error; if (!q->root.func) { query_raise_unexpected_eof(buff.offset, error_string); goto error; } return q; error: if (q) libretrodb_query_free(q); return NULL; }