mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-15 06:50:32 +00:00
(LibretroDB) Update
This commit is contained in:
parent
fb5384feab
commit
fc82bd4d9d
@ -173,7 +173,7 @@ OBJ += frontend/frontend.o \
|
||||
|
||||
ifeq ($(HAVE_LIBRETRODB), 1)
|
||||
OBJ += libretrodb/bintree.o \
|
||||
libretrodb/rarchdb.o \
|
||||
libretrodb/libretrodb.o \
|
||||
libretrodb/query.o \
|
||||
libretrodb/rmsgpack.o \
|
||||
libretrodb/rmsgpack_dom.o
|
||||
|
@ -810,7 +810,7 @@ XML
|
||||
============================================================ */
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
#include "../libretrodb/bintree.c"
|
||||
#include "../libretrodb/rarchdb.c"
|
||||
#include "../libretrodb/libretrodb.c"
|
||||
#include "../libretrodb/rmsgpack.c"
|
||||
#include "../libretrodb/rmsgpack_dom.c"
|
||||
#include "../libretrodb/query.c"
|
||||
|
@ -4,7 +4,7 @@ INCFLAGS = -I. -I../libretro-sdk/include
|
||||
LUA_CONVERTER_OBJ = rmsgpack.o \
|
||||
rmsgpack_dom.o \
|
||||
lua_common.o \
|
||||
rarchdb.o \
|
||||
libretrodb.o \
|
||||
bintree.o \
|
||||
query.o \
|
||||
lua_converter.o \
|
||||
@ -13,10 +13,10 @@ LUA_CONVERTER_OBJ = rmsgpack.o \
|
||||
|
||||
RARCHDB_TOOL_OBJ = rmsgpack.o \
|
||||
rmsgpack_dom.o \
|
||||
rarchdb_tool.o \
|
||||
libretrodb_tool.o \
|
||||
bintree.o \
|
||||
query.o \
|
||||
rarchdb.o \
|
||||
libretrodb.o \
|
||||
compat_fnmatch.c \
|
||||
$(NULL)
|
||||
|
||||
@ -24,7 +24,7 @@ TESTLIB_C = testlib.c \
|
||||
lua_common.c \
|
||||
query.c \
|
||||
compat_fnmatch.c \
|
||||
rarchdb.c \
|
||||
libretrodb.c \
|
||||
bintree.c \
|
||||
rmsgpack.c \
|
||||
rmsgpack_dom.c \
|
||||
@ -35,7 +35,7 @@ TESTLIB_FLAGS = ${CFLAGS} ${LUA_FLAGS} -shared -fpic
|
||||
|
||||
.PHONY: all clean check
|
||||
|
||||
all: rmsgpack_test rarchdb_tool lua_converter
|
||||
all: rmsgpack_test libretrodb_tool lua_converter
|
||||
|
||||
%.o: %.c
|
||||
${CC} $(INCFLAGS) $< -c ${CFLAGS} -o $@
|
||||
@ -43,7 +43,7 @@ all: rmsgpack_test rarchdb_tool lua_converter
|
||||
lua_converter: ${LUA_CONVERTER_OBJ}
|
||||
${CC} $(INCFLAGS) ${LUA_CONVERTER_OBJ} ${LUA_FLAGS} -o $@
|
||||
|
||||
rarchdb_tool: ${RARCHDB_TOOL_OBJ}
|
||||
libretrodb_tool: ${RARCHDB_TOOL_OBJ}
|
||||
${CC} $(INCFLAGS) ${RARCHDB_TOOL_OBJ} -o $@
|
||||
|
||||
rmsgpack_test:
|
||||
@ -56,4 +56,4 @@ check: testlib.so tests.lua
|
||||
lua ./tests.lua
|
||||
|
||||
clean:
|
||||
rm -rf *.o rmsgpack_test lua_converter rarchdb_tool testlib.so
|
||||
rm -rf *.o rmsgpack_test lua_converter libretrodb_tool testlib.so
|
||||
|
@ -1,13 +1,13 @@
|
||||
# rarchdb
|
||||
# libretrodb
|
||||
A small read only database
|
||||
Mainly to be used by retroarch
|
||||
|
||||
# Usage
|
||||
Files specified later in the chain **will override** earlier ones if the same key exists multiple times.
|
||||
|
||||
To list out the content of a db `rarchdb_tool <db file> list`
|
||||
To create an index `rarchdb_tool <db file> create-index <index name> <field name>`
|
||||
To find an entry with an index `rarchdb_tool <db file> find <index name> <value>`
|
||||
To list out the content of a db `libretrodb_tool <db file> list`
|
||||
To create an index `libretrodb_tool <db file> create-index <index name> <field name>`
|
||||
To find an entry with an index `libretrodb_tool <db file> find <index name> <value>`
|
||||
|
||||
# lua converters
|
||||
In order to write you own converter you must have a lua file that implements the following functions:
|
||||
@ -54,15 +54,15 @@ dat_converter snes.rdb rom.crc snes1.dat snes2.dat
|
||||
~~~
|
||||
|
||||
# Query examples
|
||||
Some examples of queries you can use with rarchdbtool:
|
||||
Some examples of queries you can use with libretrodbtool:
|
||||
|
||||
1) Glob pattern matching
|
||||
Usecase : Search for all games starting with 'Street Fighter' in the 'name' field (glob pattern matching)
|
||||
|
||||
`rarchdb_tool <db file> find "{'name':glob('Street Fighter*')}"`
|
||||
`libretrodb_tool <db file> find "{'name':glob('Street Fighter*')}"`
|
||||
|
||||
2) Combined number matching query
|
||||
Usecase: Search for all games released on October 1995.
|
||||
|
||||
`rarchdb_tool <db file> find "{'releasemonth':10,'releaseyear':1995}"`
|
||||
`libretrodb_tool <db file> find "{'releasemonth':10,'releaseyear':1995}"`
|
||||
|
||||
|
291
libretrodb/dat_converter.c
Normal file
291
libretrodb/dat_converter.c
Normal file
@ -0,0 +1,291 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "rarchdb.h"
|
||||
#include "db_parser.h"
|
||||
|
||||
#define MAX_TOKEN 256
|
||||
|
||||
static char *strndup_(const char *s, size_t n)
|
||||
{
|
||||
char* buff = calloc(n, sizeof(char));
|
||||
|
||||
if (!buff)
|
||||
return 0;
|
||||
|
||||
strncpy(buff, s, n);
|
||||
return buff;
|
||||
}
|
||||
|
||||
static struct rmsgpack_dom_value *get_map_value(const struct rmsgpack_dom_value *m, char* key)
|
||||
{
|
||||
struct rmsgpack_dom_value v;
|
||||
|
||||
v.type = RDT_STRING;
|
||||
v.string.len = strlen(key);
|
||||
v.string.buff = key;
|
||||
return rmsgpack_dom_value_map_value(m, &v);
|
||||
}
|
||||
|
||||
static int load_string(int fd, struct rmsgpack_dom_value *out)
|
||||
{
|
||||
char tok[MAX_TOKEN];
|
||||
ssize_t tok_size;
|
||||
|
||||
if ((tok_size = get_token(fd, tok, MAX_TOKEN)) < 0)
|
||||
return tok_size;
|
||||
|
||||
out->type = RDT_STRING;
|
||||
out->string.len = tok_size;
|
||||
out->string.buff = strndup_(tok, tok_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_uint(int fd, struct rmsgpack_dom_value *out)
|
||||
{
|
||||
char tok[MAX_TOKEN], *c;
|
||||
ssize_t tok_size;
|
||||
uint64_t value = 0;
|
||||
|
||||
if ((tok_size = get_token(fd, tok, MAX_TOKEN)) < 0)
|
||||
return tok_size;
|
||||
|
||||
for (c = tok; c < tok + tok_size; c++)
|
||||
{
|
||||
value *= 10;
|
||||
value += *c - '0';
|
||||
}
|
||||
|
||||
out->type = RDT_UINT;
|
||||
out->uint_ = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_bin(int fd, struct rmsgpack_dom_value *out)
|
||||
{
|
||||
char tok[MAX_TOKEN];
|
||||
ssize_t tok_size;
|
||||
uint8_t h;
|
||||
uint8_t l;
|
||||
int i;
|
||||
|
||||
if ((tok_size = get_token(fd, tok, MAX_TOKEN)) < 0)
|
||||
return tok_size;
|
||||
|
||||
out->type = RDT_BINARY;
|
||||
out->binary.len = tok_size / 2;
|
||||
|
||||
for (i = 0; i < tok_size; i += 2)
|
||||
{
|
||||
if (tok[i] <= '9')
|
||||
h = tok[i] - '0';
|
||||
else
|
||||
h = (tok[i] - 'A') + 10;
|
||||
if (tok[i+1] <= '9')
|
||||
l = tok[i+1] - '0';
|
||||
else
|
||||
l = (tok[i+1] - 'A') + 10;
|
||||
tok[i/2] = h * 16 + l;
|
||||
}
|
||||
|
||||
out->binary.buff = malloc(out->binary.len);
|
||||
memcpy(out->binary.buff, tok, out->binary.len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dat_value_provider(void *ctx, struct rmsgpack_dom_value *out)
|
||||
{
|
||||
int rv, i;
|
||||
static const int field_count = 22;
|
||||
int fd = *((int*)ctx);
|
||||
char* key;
|
||||
|
||||
out->type = RDT_MAP;
|
||||
out->map.len = field_count;
|
||||
out->map.items = calloc(field_count, sizeof(struct rmsgpack_dom_pair));
|
||||
|
||||
if (find_token(fd, "game") < 0)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < field_count; i++)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].key)) < 0)
|
||||
goto failed;
|
||||
|
||||
key = out->map.items[i].key.string.buff;
|
||||
|
||||
if (strncmp(key, "name", sizeof("name")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "description", sizeof("description")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "users", sizeof("users")) == 0)
|
||||
{
|
||||
if ((rv = load_uint(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "releasemonth", sizeof("releasemonth")) == 0)
|
||||
{
|
||||
if ((rv = load_uint(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "releaseyear", sizeof("releaseyear")) == 0)
|
||||
{
|
||||
if ((rv = load_uint(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "rumble", sizeof("rumble")) == 0)
|
||||
{
|
||||
if ((rv = load_uint(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "analog", sizeof("analog")) == 0)
|
||||
{
|
||||
if ((rv = load_uint(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "serial", sizeof("serial")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "esrb_rating", sizeof("esrb_rating")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "elspa_rating", sizeof("elspa_rating")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "pegi_rating", sizeof("pegi_rating")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "cero_rating", sizeof("cero_rating")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "developers", sizeof("developers")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "publisher", sizeof("publisher")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "origin", sizeof("origin")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "rom", sizeof("rom")) == 0)
|
||||
{
|
||||
if (find_token(fd, "name") < 0)
|
||||
goto failed;
|
||||
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "size", sizeof("size")) == 0)
|
||||
{
|
||||
if ((rv = load_uint(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "sha1", sizeof("sha1")) == 0)
|
||||
{
|
||||
if ((rv = load_bin(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "crc", sizeof("crc")) == 0)
|
||||
{
|
||||
if ((rv = load_bin(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "md5", sizeof("md5")) == 0)
|
||||
{
|
||||
if ((rv = load_bin(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, "serial", sizeof("serial")) == 0)
|
||||
{
|
||||
if ((rv = load_string(fd, &out->map.items[i].value)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
else if (strncmp(key, ")", sizeof(")")) == 0)
|
||||
{
|
||||
rmsgpack_dom_value_free(&out->map.items[i].key);
|
||||
out->map.len = i;
|
||||
printf("Couldn't find all fields for item\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
rmsgpack_dom_value_free(&out->map.items[i].key);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
printf("Inserting '%s' (%02X%02X%02X%02X)...\n",
|
||||
get_map_value(out, "name")->string.buff,
|
||||
(unsigned char)get_map_value(out, "crc")->binary.buff[0],
|
||||
(unsigned char)get_map_value(out, "crc")->binary.buff[1],
|
||||
(unsigned char)get_map_value(out, "crc")->binary.buff[2],
|
||||
(unsigned char)get_map_value(out, "crc")->binary.buff[3]
|
||||
);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
rmsgpack_dom_value_free(out);
|
||||
out->type = RDT_NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rv = 0;
|
||||
int src = -1;
|
||||
int dst = -1;
|
||||
if (argc != 3)
|
||||
printf("Usage: %s <dat file> <output file>\n", argv[0]);
|
||||
|
||||
src = open(argv[1], O_RDONLY);
|
||||
if (src == -1)
|
||||
{
|
||||
printf("Could not open source file '%s': %s\n", argv[1], strerror(errno));
|
||||
rv = errno;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
dst = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||
if (dst == -1)
|
||||
{
|
||||
printf("Could not open destination file '%s': %s\n", argv[1], strerror(errno));
|
||||
rv = errno;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
rv = rarchdb_create(dst, &dat_value_provider, &src);
|
||||
|
||||
clean:
|
||||
if (src != -1)
|
||||
close(src);
|
||||
if (dst != -1)
|
||||
close(dst);
|
||||
return rv;
|
||||
}
|
80
libretrodb/db_parser.c
Normal file
80
libretrodb/db_parser.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include "db_parser.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
ssize_t get_token(int fd, char *token, size_t max_len)
|
||||
{
|
||||
char *c = token;
|
||||
int rv;
|
||||
ssize_t len = 0;
|
||||
int in_string = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
rv = read(fd, c, 1);
|
||||
if (rv == 0)
|
||||
return 0;
|
||||
else if (rv < 1)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EINTR:
|
||||
case EAGAIN:
|
||||
continue;
|
||||
default:
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
switch (*c)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
if (c == token)
|
||||
continue;
|
||||
|
||||
if (!in_string)
|
||||
{
|
||||
*c = '\0';
|
||||
return len;
|
||||
}
|
||||
break;
|
||||
case '\"':
|
||||
if (c == token)
|
||||
{
|
||||
in_string = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
*c = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
len++;
|
||||
c++;
|
||||
if (len == (ssize_t)max_len)
|
||||
{
|
||||
*c = '\0';
|
||||
return len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int find_token(int fd, const char *token)
|
||||
{
|
||||
int tmp_len = strlen(token);
|
||||
char *tmp_token = (char*)calloc(tmp_len, 1);
|
||||
if (!tmp_token)
|
||||
return -1;
|
||||
while (strncmp(tmp_token, token, tmp_len) != 0)
|
||||
{
|
||||
if (get_token(fd, tmp_token, tmp_len) <= 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#include "rarchdb.h"
|
||||
#include "libretrodb.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef _WIN32
|
||||
@ -17,43 +17,26 @@
|
||||
#include "rmsgpack_dom.h"
|
||||
#include "rmsgpack.h"
|
||||
#include "bintree.h"
|
||||
#include "rarchdb_endian.h"
|
||||
#include "libretrodb_endian.h"
|
||||
#include "query.h"
|
||||
|
||||
#define MAGIC_NUMBER "RARCHDB"
|
||||
|
||||
struct rarchdb_header {
|
||||
char magic_number[sizeof(MAGIC_NUMBER)-1];
|
||||
uint64_t metadata_offset;
|
||||
};
|
||||
|
||||
struct rarchdb_metadata {
|
||||
uint64_t count;
|
||||
};
|
||||
|
||||
struct rarchdb_index {
|
||||
char name[50];
|
||||
uint64_t key_size;
|
||||
uint64_t next;
|
||||
};
|
||||
|
||||
struct node_iter_ctx {
|
||||
struct rarchdb * db;
|
||||
struct rarchdb_index * idx;
|
||||
libretrodb_t *db;
|
||||
libretrodb_index_t *idx;
|
||||
};
|
||||
|
||||
static struct rmsgpack_dom_value sentinal;
|
||||
|
||||
static int rarchdb_read_metadata(
|
||||
static int libretrodb_read_metadata(
|
||||
int fd,
|
||||
struct rarchdb_metadata * md
|
||||
libretrodb_metadata_t *md
|
||||
){
|
||||
return rmsgpack_dom_read_into(fd, "count", &md->count, NULL);
|
||||
}
|
||||
|
||||
static int rarchdb_write_metadata(
|
||||
static int libretrodb_write_metadata(
|
||||
int fd,
|
||||
struct rarchdb_metadata * md
|
||||
libretrodb_metadata_t *md
|
||||
){
|
||||
rmsgpack_write_map_header(fd, 1);
|
||||
rmsgpack_write_string(fd, "count", strlen("count"));
|
||||
@ -93,24 +76,26 @@ static int validate_document(const struct rmsgpack_dom_value * doc) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
int rarchdb_create(
|
||||
int libretrodb_create(
|
||||
int fd,
|
||||
rarchdb_value_provider value_provider,
|
||||
libretrodb_value_provider value_provider,
|
||||
void * ctx
|
||||
){
|
||||
int rv;
|
||||
struct rarchdb_metadata md;
|
||||
off_t root;
|
||||
off_t root;
|
||||
uint64_t item_count = 0;
|
||||
libretrodb_metadata_t md;
|
||||
struct rmsgpack_dom_value item = {};
|
||||
struct rarchdb_header header = {};
|
||||
libretrodb_header_t header = {};
|
||||
|
||||
memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1);
|
||||
root = lseek(fd, 0, SEEK_CUR);
|
||||
|
||||
// We write the header in the end because we need to know the size of
|
||||
// the db first
|
||||
lseek(fd, sizeof(struct rarchdb_header), SEEK_CUR);
|
||||
/* We write the header in the end because we need to know the size of
|
||||
* the db first */
|
||||
|
||||
lseek(fd, sizeof(libretrodb_header_t), SEEK_CUR);
|
||||
|
||||
while ((rv = value_provider(ctx, &item)) == 0) {
|
||||
|
||||
if ((rv = validate_document(&item)) < 0)
|
||||
@ -130,7 +115,7 @@ int rarchdb_create(
|
||||
|
||||
header.metadata_offset = httobe64(lseek(fd, 0, SEEK_CUR));
|
||||
md.count = item_count;
|
||||
rarchdb_write_metadata(fd, &md);
|
||||
libretrodb_write_metadata(fd, &md);
|
||||
lseek(fd, root, SEEK_SET);
|
||||
write(fd, &header, sizeof(header));
|
||||
clean:
|
||||
@ -138,10 +123,9 @@ clean:
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int rarchdb_read_index_header(
|
||||
int fd,
|
||||
struct rarchdb_index * idx
|
||||
){
|
||||
static int libretrodb_read_index_header(
|
||||
int fd, libretrodb_index_t *idx)
|
||||
{
|
||||
uint64_t name_len = 50;
|
||||
return rmsgpack_dom_read_into(
|
||||
fd,
|
||||
@ -152,10 +136,9 @@ static int rarchdb_read_index_header(
|
||||
);
|
||||
}
|
||||
|
||||
static void rarchdb_write_index_header(
|
||||
int fd,
|
||||
struct rarchdb_index * idx
|
||||
){
|
||||
static void libretrodb_write_index_header(
|
||||
int fd, libretrodb_index_t * idx)
|
||||
{
|
||||
rmsgpack_write_map_header(fd, 3);
|
||||
rmsgpack_write_string(fd, "name", strlen("name"));
|
||||
rmsgpack_write_string(fd, idx->name, strlen(idx->name));
|
||||
@ -165,20 +148,22 @@ static void rarchdb_write_index_header(
|
||||
rmsgpack_write_uint(fd, idx->next);
|
||||
}
|
||||
|
||||
void rarchdb_close(struct rarchdb * db)
|
||||
void libretrodb_close(libretrodb_t * db)
|
||||
{
|
||||
close(db->fd);
|
||||
db->fd = -1;
|
||||
}
|
||||
|
||||
int rarchdb_open(
|
||||
int libretrodb_open(
|
||||
const char * path,
|
||||
struct rarchdb * db
|
||||
){
|
||||
struct rarchdb_header header;
|
||||
struct rarchdb_metadata md;
|
||||
libretrodb_t * db
|
||||
)
|
||||
{
|
||||
libretrodb_header_t header;
|
||||
libretrodb_metadata_t md;
|
||||
int rv;
|
||||
int fd = open(path, O_RDWR);
|
||||
|
||||
if (fd == -1)
|
||||
return -errno;
|
||||
|
||||
@ -195,7 +180,7 @@ int rarchdb_open(
|
||||
|
||||
header.metadata_offset = betoht64(header.metadata_offset);
|
||||
lseek(fd, header.metadata_offset, SEEK_SET);
|
||||
if (rarchdb_read_metadata(fd, &md) < 0) {
|
||||
if (libretrodb_read_metadata(fd, &md) < 0) {
|
||||
rv = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
@ -208,19 +193,22 @@ error:
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int rarchdb_find_index(
|
||||
struct rarchdb * db,
|
||||
const char * index_name,
|
||||
struct rarchdb_index * idx
|
||||
static int libretrodb_find_index(
|
||||
libretrodb_t *db,
|
||||
const char *index_name,
|
||||
libretrodb_index_t *idx
|
||||
){
|
||||
off_t eof = lseek(db->fd, 0, SEEK_END);
|
||||
off_t offset = lseek(db->fd, db->first_index_offset, SEEK_SET);
|
||||
while (offset < eof) {
|
||||
rarchdb_read_index_header(db->fd, idx);
|
||||
if (strncmp(index_name, idx->name, strlen(idx->name)) == 0)
|
||||
return 0;
|
||||
offset = lseek(db->fd, idx->next, SEEK_CUR);
|
||||
}
|
||||
|
||||
while (offset < eof)
|
||||
{
|
||||
libretrodb_read_index_header(db->fd, idx);
|
||||
if (strncmp(index_name, idx->name, strlen(idx->name)) == 0)
|
||||
return 0;
|
||||
offset = lseek(db->fd, idx->next, SEEK_CUR);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -255,21 +243,20 @@ static int binsearch(
|
||||
return binsearch(current + item_size, item, count - mid, field_size, offset);
|
||||
}
|
||||
|
||||
int rarchdb_find_entry(
|
||||
struct rarchdb * db,
|
||||
const char * index_name,
|
||||
const void * key,
|
||||
int libretrodb_find_entry(
|
||||
libretrodb_t *db,
|
||||
const char *index_name,
|
||||
const void *key,
|
||||
struct rmsgpack_dom_value * out
|
||||
) {
|
||||
struct rarchdb_index idx;
|
||||
libretrodb_index_t idx;
|
||||
int rv;
|
||||
void * buff;
|
||||
uint64_t offset;
|
||||
ssize_t bufflen, nread = 0;
|
||||
|
||||
if (rarchdb_find_index(db, index_name, &idx) < 0) {
|
||||
if (libretrodb_find_index(db, index_name, &idx) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
bufflen = idx.next;
|
||||
buff = malloc(bufflen);
|
||||
@ -302,25 +289,25 @@ int rarchdb_find_entry(
|
||||
}
|
||||
|
||||
/**
|
||||
* rarchdb_cursor_reset:
|
||||
* libretrodb_cursor_reset:
|
||||
* @cursor : Handle to database cursor.
|
||||
*
|
||||
* Resets cursor.
|
||||
*
|
||||
* Returns: ???.
|
||||
**/
|
||||
int rarchdb_cursor_reset(struct rarchdb_cursor * cursor)
|
||||
int libretrodb_cursor_reset(libretrodb_cursor_t *cursor)
|
||||
{
|
||||
cursor->eof = 0;
|
||||
return lseek(
|
||||
cursor->fd,
|
||||
cursor->db->root + sizeof(struct rarchdb_header),
|
||||
cursor->db->root + sizeof(libretrodb_header_t),
|
||||
SEEK_SET
|
||||
);
|
||||
}
|
||||
|
||||
int rarchdb_cursor_read_item(
|
||||
struct rarchdb_cursor * cursor,
|
||||
int libretrodb_cursor_read_item(
|
||||
libretrodb_cursor_t *cursor,
|
||||
struct rmsgpack_dom_value * out
|
||||
) {
|
||||
int rv;
|
||||
@ -338,7 +325,7 @@ retry:
|
||||
}
|
||||
|
||||
if (cursor->query) {
|
||||
if (!rarchdb_query_filter(cursor->query, out)) {
|
||||
if (!libretrodb_query_filter(cursor->query, out)) {
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
@ -347,12 +334,12 @@ retry:
|
||||
}
|
||||
|
||||
/**
|
||||
* rarchdb_cursor_close:
|
||||
* libretrodb_cursor_close:
|
||||
* @cursor : Handle to database cursor.
|
||||
*
|
||||
* Closes cursor and frees up allocated memory.
|
||||
**/
|
||||
void rarchdb_cursor_close(struct rarchdb_cursor * cursor)
|
||||
void libretrodb_cursor_close(libretrodb_cursor_t *cursor)
|
||||
{
|
||||
close(cursor->fd);
|
||||
cursor->is_valid = 0;
|
||||
@ -360,12 +347,12 @@ void rarchdb_cursor_close(struct rarchdb_cursor * cursor)
|
||||
cursor->eof = 1;
|
||||
cursor->db = NULL;
|
||||
if (cursor->query)
|
||||
rarchdb_query_free(cursor->query);
|
||||
libretrodb_query_free(cursor->query);
|
||||
cursor->query = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* rarchdb_cursor_open:
|
||||
* libretrodb_cursor_open:
|
||||
* @db : Handle to database.
|
||||
* @cursor : Handle to database cursor.
|
||||
* @q : Query to execute.
|
||||
@ -374,10 +361,10 @@ void rarchdb_cursor_close(struct rarchdb_cursor * cursor)
|
||||
*
|
||||
* Returns: 0 if successful, otherwise negative.
|
||||
**/
|
||||
int rarchdb_cursor_open(
|
||||
struct rarchdb * db,
|
||||
struct rarchdb_cursor * cursor,
|
||||
rarchdb_query * q
|
||||
int libretrodb_cursor_open(
|
||||
libretrodb_t *db,
|
||||
libretrodb_cursor_t *cursor,
|
||||
libretrodb_query_t *q
|
||||
)
|
||||
{
|
||||
cursor->fd = dup(db->fd);
|
||||
@ -387,11 +374,11 @@ int rarchdb_cursor_open(
|
||||
|
||||
cursor->db = db;
|
||||
cursor->is_valid = 1;
|
||||
rarchdb_cursor_reset(cursor);
|
||||
libretrodb_cursor_reset(cursor);
|
||||
cursor->query = q;
|
||||
|
||||
if (q)
|
||||
rarchdb_query_inc_ref(q);
|
||||
libretrodb_query_inc_ref(q);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -406,41 +393,41 @@ static int node_iter(void * value, void * ctx)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint64_t rarchdb_tell(struct rarchdb * db)
|
||||
static uint64_t libretrodb_tell(libretrodb_t *db)
|
||||
{
|
||||
return lseek(db->fd, 0, SEEK_CUR);
|
||||
}
|
||||
|
||||
int rarchdb_create_index(
|
||||
struct rarchdb * db,
|
||||
const char * name,
|
||||
const char * field_name
|
||||
int libretrodb_create_index(
|
||||
libretrodb_t *db,
|
||||
const char *name,
|
||||
const char *field_name
|
||||
){
|
||||
int rv;
|
||||
struct node_iter_ctx nictx;
|
||||
struct rmsgpack_dom_value key;
|
||||
struct rarchdb_index idx;
|
||||
libretrodb_index_t idx;
|
||||
struct rmsgpack_dom_value item;
|
||||
struct rmsgpack_dom_value * field;
|
||||
struct bintree tree;
|
||||
libretrodb_cursor_t cur;
|
||||
void * buff = NULL;
|
||||
uint64_t * buff_u64 = NULL;
|
||||
uint8_t field_size = 0;
|
||||
struct bintree tree;
|
||||
uint64_t item_loc = rarchdb_tell(db);
|
||||
uint64_t idx_header_offset;
|
||||
struct rarchdb_cursor cur;
|
||||
uint64_t item_loc = libretrodb_tell(db);
|
||||
|
||||
bintree_new(&tree, node_compare, &field_size);
|
||||
if (rarchdb_cursor_open(db, &cur, NULL) != 0) {
|
||||
if (libretrodb_cursor_open(db, &cur, NULL) != 0) {
|
||||
rv = -1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
key.type = RDT_STRING;
|
||||
key.string.len = strlen(field_name);
|
||||
// We know we aren't going to change it
|
||||
/* We know we aren't going to change it */
|
||||
key.string.buff = (char *) field_name;
|
||||
while (rarchdb_cursor_read_item(&cur, &item) == 0) {
|
||||
while (libretrodb_cursor_read_item(&cur, &item) == 0) {
|
||||
if (item.type != RDT_MAP) {
|
||||
rv = -EINVAL;
|
||||
printf("Only map keys are supported\n");
|
||||
@ -491,7 +478,7 @@ int rarchdb_create_index(
|
||||
}
|
||||
buff = NULL;
|
||||
rmsgpack_dom_value_free(&item);
|
||||
item_loc = rarchdb_tell(db);
|
||||
item_loc = libretrodb_tell(db);
|
||||
}
|
||||
|
||||
(void)rv;
|
||||
@ -503,7 +490,7 @@ int rarchdb_create_index(
|
||||
idx.name[49] = '\0';
|
||||
idx.key_size = field_size;
|
||||
idx.next = db->count * (field_size + sizeof(uint64_t));
|
||||
rarchdb_write_index_header(db->fd, &idx);
|
||||
libretrodb_write_index_header(db->fd, &idx);
|
||||
|
||||
nictx.db = db;
|
||||
nictx.idx = &idx;
|
||||
@ -514,7 +501,7 @@ clean:
|
||||
if (buff)
|
||||
free(buff);
|
||||
if (cur.is_valid) {
|
||||
rarchdb_cursor_close(&cur);
|
||||
libretrodb_cursor_close(&cur);
|
||||
}
|
||||
return 0;
|
||||
}
|
129
libretrodb/libretrodb.h
Normal file
129
libretrodb/libretrodb.h
Normal file
@ -0,0 +1,129 @@
|
||||
#ifndef __LIBRETRODB_H__
|
||||
#define __LIBRETRODB_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "rmsgpack_dom.h"
|
||||
|
||||
#define MAGIC_NUMBER "RARCHDB"
|
||||
|
||||
typedef struct libretrodb_query libretrodb_query_t;
|
||||
|
||||
typedef struct libretrodb
|
||||
{
|
||||
int fd;
|
||||
uint64_t root;
|
||||
uint64_t count;
|
||||
uint64_t first_index_offset;
|
||||
} libretrodb_t;
|
||||
|
||||
typedef struct libretrodb_index
|
||||
{
|
||||
char name[50];
|
||||
uint64_t key_size;
|
||||
uint64_t next;
|
||||
} libretrodb_index_t;
|
||||
|
||||
typedef struct libretrodb_metadata
|
||||
{
|
||||
uint64_t count;
|
||||
} libretrodb_metadata_t;
|
||||
|
||||
typedef struct libretrodb_header
|
||||
{
|
||||
char magic_number[sizeof(MAGIC_NUMBER)-1];
|
||||
uint64_t metadata_offset;
|
||||
} libretrodb_header_t;
|
||||
|
||||
typedef struct libretrodb_cursor
|
||||
{
|
||||
int is_valid;
|
||||
int fd;
|
||||
int eof;
|
||||
libretrodb_query_t * query;
|
||||
libretrodb_t * db;
|
||||
} libretrodb_cursor_t;
|
||||
|
||||
typedef int (* libretrodb_value_provider)(
|
||||
void * ctx,
|
||||
struct rmsgpack_dom_value * out
|
||||
);
|
||||
|
||||
int libretrodb_create(
|
||||
int fd,
|
||||
libretrodb_value_provider value_provider,
|
||||
void * ctx
|
||||
);
|
||||
|
||||
void libretrodb_close(libretrodb_t * db);
|
||||
|
||||
int libretrodb_open(
|
||||
const char * path,
|
||||
libretrodb_t * db
|
||||
);
|
||||
|
||||
int libretrodb_create_index(
|
||||
libretrodb_t * db,
|
||||
const char * name,
|
||||
const char * field_name
|
||||
);
|
||||
int libretrodb_find_entry(
|
||||
libretrodb_t * db,
|
||||
const char * index_name,
|
||||
const void * key,
|
||||
struct rmsgpack_dom_value * out
|
||||
);
|
||||
|
||||
/**
|
||||
* libretrodb_cursor_open:
|
||||
* @db : Handle to database.
|
||||
* @cursor : Handle to database cursor.
|
||||
* @q : Query to execute.
|
||||
*
|
||||
* Opens cursor to database based on query @q.
|
||||
*
|
||||
* Returns: 0 if successful, otherwise negative.
|
||||
**/
|
||||
int libretrodb_cursor_open(
|
||||
libretrodb_t *db,
|
||||
libretrodb_cursor_t *cursor,
|
||||
libretrodb_query_t *query
|
||||
);
|
||||
|
||||
/**
|
||||
* libretrodb_cursor_reset:
|
||||
* @cursor : Handle to database cursor.
|
||||
*
|
||||
* Resets cursor.
|
||||
*
|
||||
* Returns: ???.
|
||||
**/
|
||||
int libretrodb_cursor_reset(libretrodb_cursor_t * cursor);
|
||||
|
||||
/**
|
||||
* libretrodb_cursor_close:
|
||||
* @cursor : Handle to database cursor.
|
||||
*
|
||||
* Closes cursor and frees up allocated memory.
|
||||
**/
|
||||
void libretrodb_cursor_close(libretrodb_cursor_t * cursor);
|
||||
|
||||
void *libretrodb_query_compile(
|
||||
libretrodb_t * db,
|
||||
const char * query,
|
||||
size_t buff_len,
|
||||
const char ** error
|
||||
);
|
||||
|
||||
void libretrodb_query_free(void *q);
|
||||
|
||||
int libretrodb_cursor_read_item(
|
||||
libretrodb_cursor_t * cursor,
|
||||
struct rmsgpack_dom_value * out
|
||||
);
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
#ifndef __RARCHDB_MSGPACK_ENDIAN_H
|
||||
#define __RARCHDB_MSGPACK_ENDIAN_H
|
||||
#ifndef __LIBRETRODB_MSGPACK_ENDIAN_H
|
||||
#define __LIBRETRODB_MSGPACK_ENDIAN_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <retro_endianness.h>
|
@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rarchdb.h"
|
||||
#include "libretrodb.h"
|
||||
#include "rmsgpack_dom.h"
|
||||
|
||||
int main(
|
||||
@ -9,9 +9,12 @@ int main(
|
||||
char ** argv
|
||||
){
|
||||
int rv;
|
||||
struct rarchdb db;
|
||||
struct rarchdb_cursor cur;
|
||||
libretrodb_t db;
|
||||
libretrodb_cursor_t cur;
|
||||
libretrodb_query_t *q;
|
||||
struct rmsgpack_dom_value item;
|
||||
const char *command, *path, *query_exp, *error;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("Usage: %s <db file> <command> [extra args...]\n", argv[0]);
|
||||
printf("Available Commands:\n");
|
||||
@ -21,14 +24,14 @@ int main(
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char * command = argv[2];
|
||||
const char * path = argv[1];
|
||||
command = argv[2];
|
||||
path = argv[1];
|
||||
|
||||
if ((rv = rarchdb_open(path, &db)) != 0) {
|
||||
if ((rv = libretrodb_open(path, &db)) != 0) {
|
||||
printf("Could not open db file '%s': %s\n", path, strerror(-rv));
|
||||
return 1;
|
||||
} else if (strcmp(command, "list") == 0) {
|
||||
if ((rv = rarchdb_cursor_open(&db, &cur, NULL)) != 0) {
|
||||
if ((rv = libretrodb_cursor_open(&db, &cur, NULL)) != 0) {
|
||||
printf("Could not open cursor: %s\n", strerror(-rv));
|
||||
return 1;
|
||||
}
|
||||
@ -37,7 +40,7 @@ int main(
|
||||
printf("Usage: %s <db file> list\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
while (rarchdb_cursor_read_item(&cur, &item) == 0) {
|
||||
while (libretrodb_cursor_read_item(&cur, &item) == 0) {
|
||||
rmsgpack_dom_value_print(&item);
|
||||
printf("\n");
|
||||
rmsgpack_dom_value_free(&item);
|
||||
@ -47,20 +50,23 @@ int main(
|
||||
printf("Usage: %s <db file> find <query expression>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
const char * query_exp = argv[3];
|
||||
const char * error = NULL;
|
||||
rarchdb_query * q = rarchdb_query_compile(&db, query_exp, strlen(query_exp), &error);
|
||||
|
||||
query_exp = argv[3];
|
||||
error = NULL;
|
||||
q = libretrodb_query_compile(&db, query_exp, strlen(query_exp), &error);
|
||||
if (error) {
|
||||
printf("%s\n", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((rv = rarchdb_cursor_open(&db, &cur, q)) != 0) {
|
||||
if ((rv = libretrodb_cursor_open(&db, &cur, q)) != 0)
|
||||
{
|
||||
printf("Could not open cursor: %s\n", strerror(-rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (rarchdb_cursor_read_item(&cur, &item) == 0) {
|
||||
while (libretrodb_cursor_read_item(&cur, &item) == 0)
|
||||
{
|
||||
rmsgpack_dom_value_print(&item);
|
||||
printf("\n");
|
||||
rmsgpack_dom_value_free(&item);
|
||||
@ -76,10 +82,10 @@ int main(
|
||||
index_name = argv[3];
|
||||
field_name = argv[4];
|
||||
|
||||
rarchdb_create_index(&db, index_name, field_name);
|
||||
libretrodb_create_index(&db, index_name, field_name);
|
||||
} else {
|
||||
printf("Unkonwn command %s\n", argv[2]);
|
||||
return 1;
|
||||
}
|
||||
rarchdb_close(&db);
|
||||
libretrodb_close(&db);
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int rarchdb_lua_to_rmsgpack_value(
|
||||
int libretrodb_lua_to_rmsgpack_value(
|
||||
lua_State * L,
|
||||
int index,
|
||||
struct rmsgpack_dom_value * out
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "rmsgpack_dom.h"
|
||||
|
||||
int rarchdb_lua_to_rmsgpack_value(
|
||||
int libretrodb_lua_to_rmsgpack_value(
|
||||
lua_State * L,
|
||||
int index,
|
||||
struct rmsgpack_dom_value * out
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
#include "rarchdb.h"
|
||||
#include "libretrodb.h"
|
||||
#include "lua_common.h"
|
||||
|
||||
int master_key = 1;
|
||||
@ -62,7 +62,7 @@ static int value_provider(
|
||||
if (lua_isnil(L, -1)) {
|
||||
rv = 1;
|
||||
} else if (lua_istable(L, -1)) {
|
||||
rv = rarchdb_lua_to_rmsgpack_value(L, -1, out);
|
||||
rv = libretrodb_lua_to_rmsgpack_value(L, -1, out);
|
||||
} else {
|
||||
printf("function `get_value' must return a table or nil\n");
|
||||
}
|
||||
@ -108,7 +108,7 @@ int main(
|
||||
goto clean;
|
||||
}
|
||||
|
||||
rv = rarchdb_create(dst, &value_provider, L);
|
||||
rv = libretrodb_create(dst, &value_provider, L);
|
||||
clean:
|
||||
lua_close(L);
|
||||
if (dst != -1) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rarchdb.h"
|
||||
#include "libretrodb.h"
|
||||
|
||||
#include "rmsgpack_dom.h"
|
||||
#include <compat/fnmatch.h>
|
||||
@ -870,31 +870,30 @@ success:
|
||||
}
|
||||
|
||||
|
||||
void rarchdb_query_free(rarchdb_query * q) {
|
||||
void libretrodb_query_free(void *q)
|
||||
{
|
||||
unsigned i;
|
||||
struct query * real_q = (struct query*)q;
|
||||
|
||||
real_q->ref_count--;
|
||||
if (real_q->ref_count > 0) {
|
||||
if (real_q->ref_count > 0)
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < real_q->root.argc; i++) {
|
||||
for (i = 0; i < real_q->root.argc; i++)
|
||||
argument_free(&real_q->root.argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
rarchdb_query * rarchdb_query_compile(
|
||||
struct rarchdb * db,
|
||||
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) {
|
||||
if (!q)
|
||||
goto clean;
|
||||
}
|
||||
memset(q, 0, sizeof(struct query));
|
||||
q->ref_count = 1;
|
||||
buff.data = query;
|
||||
@ -914,9 +913,8 @@ rarchdb_query * rarchdb_query_compile(
|
||||
}
|
||||
|
||||
buff = expect_eof(buff, error);
|
||||
if (*error) {
|
||||
if (*error)
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (q->root.func == NULL) {
|
||||
raise_unexpected_eof(buff.offset, error);
|
||||
@ -924,20 +922,20 @@ rarchdb_query * rarchdb_query_compile(
|
||||
}
|
||||
goto success;
|
||||
clean:
|
||||
if (q) {
|
||||
rarchdb_query_free(q);
|
||||
}
|
||||
if (q)
|
||||
libretrodb_query_free(q);
|
||||
success:
|
||||
return q;
|
||||
}
|
||||
|
||||
void rarchdb_query_inc_ref(rarchdb_query * q) {
|
||||
void libretrodb_query_inc_ref(libretrodb_query_t *q)
|
||||
{
|
||||
struct query * rq = (struct query*)q;
|
||||
rq->ref_count += 1;
|
||||
}
|
||||
|
||||
int rarchdb_query_filter(
|
||||
rarchdb_query * q,
|
||||
int libretrodb_query_filter(
|
||||
libretrodb_query_t * q,
|
||||
struct rmsgpack_dom_value * v
|
||||
) {
|
||||
struct invocation inv = ((struct query *)q)->root;
|
||||
|
@ -1,12 +1,14 @@
|
||||
#ifndef __RARCHDB_QUERY_H__
|
||||
#define __RARCHDB_QUERY_H__
|
||||
#ifndef __LIBRETRODB_QUERY_H__
|
||||
#define __LIBRETRODB_QUERY_H__
|
||||
|
||||
#include "rarchdb.h"
|
||||
#include "libretrodb.h"
|
||||
|
||||
void rarchdb_query_inc_ref(rarchdb_query * q);
|
||||
void rarchdb_query_dec_ref(rarchdb_query * q);
|
||||
int rarchdb_query_filter(
|
||||
rarchdb_query * q,
|
||||
void libretrodb_query_inc_ref(libretrodb_query_t *q);
|
||||
|
||||
void libretrodb_query_dec_ref(libretrodb_query_t *q);
|
||||
|
||||
int libretrodb_query_filter(
|
||||
libretrodb_query_t *q,
|
||||
struct rmsgpack_dom_value * v
|
||||
);
|
||||
|
||||
|
@ -1,108 +0,0 @@
|
||||
#ifndef __RARCHDB_H__
|
||||
#define __RARCHDB_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "rmsgpack_dom.h"
|
||||
|
||||
typedef void rarchdb_query;
|
||||
|
||||
struct rarchdb
|
||||
{
|
||||
int fd;
|
||||
uint64_t root;
|
||||
uint64_t count;
|
||||
uint64_t first_index_offset;
|
||||
};
|
||||
|
||||
struct rarchdb_cursor
|
||||
{
|
||||
int is_valid;
|
||||
int fd;
|
||||
int eof;
|
||||
rarchdb_query * query;
|
||||
struct rarchdb * db;
|
||||
};
|
||||
|
||||
typedef int (* rarchdb_value_provider)(
|
||||
void * ctx,
|
||||
struct rmsgpack_dom_value * out
|
||||
);
|
||||
|
||||
int rarchdb_create(
|
||||
int fd,
|
||||
rarchdb_value_provider value_provider,
|
||||
void * ctx
|
||||
);
|
||||
|
||||
void rarchdb_close(struct rarchdb * db);
|
||||
|
||||
int rarchdb_open(
|
||||
const char * path,
|
||||
struct rarchdb * db
|
||||
);
|
||||
|
||||
int rarchdb_create_index(
|
||||
struct rarchdb * db,
|
||||
const char * name,
|
||||
const char * field_name
|
||||
);
|
||||
int rarchdb_find_entry(
|
||||
struct rarchdb * db,
|
||||
const char * index_name,
|
||||
const void * key,
|
||||
struct rmsgpack_dom_value * out
|
||||
);
|
||||
|
||||
/**
|
||||
* rarchdb_cursor_open:
|
||||
* @db : Handle to database.
|
||||
* @cursor : Handle to database cursor.
|
||||
* @q : Query to execute.
|
||||
*
|
||||
* Opens cursor to database based on query @q.
|
||||
*
|
||||
* Returns: 0 if successful, otherwise negative.
|
||||
**/
|
||||
int rarchdb_cursor_open(
|
||||
struct rarchdb * db,
|
||||
struct rarchdb_cursor * cursor,
|
||||
rarchdb_query * query
|
||||
);
|
||||
|
||||
/**
|
||||
* rarchdb_cursor_reset:
|
||||
* @cursor : Handle to database cursor.
|
||||
*
|
||||
* Resets cursor.
|
||||
*
|
||||
* Returns: ???.
|
||||
**/
|
||||
int rarchdb_cursor_reset(struct rarchdb_cursor * cursor);
|
||||
|
||||
/**
|
||||
* rarchdb_cursor_close:
|
||||
* @cursor : Handle to database cursor.
|
||||
*
|
||||
* Closes cursor and frees up allocated memory.
|
||||
**/
|
||||
void rarchdb_cursor_close(struct rarchdb_cursor * cursor);
|
||||
|
||||
rarchdb_query * rarchdb_query_compile(
|
||||
struct rarchdb * db,
|
||||
const char * query,
|
||||
size_t buff_len,
|
||||
const char ** error
|
||||
);
|
||||
void rarchdb_query_free(rarchdb_query * q);
|
||||
|
||||
int rarchdb_cursor_read_item(
|
||||
struct rarchdb_cursor * cursor,
|
||||
struct rmsgpack_dom_value * out
|
||||
);
|
||||
|
||||
#endif
|
@ -21,7 +21,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rarchdb_endian.h"
|
||||
#include "libretrodb_endian.h"
|
||||
|
||||
static const uint8_t MPF_FIXMAP = 0x80;
|
||||
static const uint8_t MPF_MAP16 = 0xde;
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#include "rarchdb.h"
|
||||
#include "libretrodb.h"
|
||||
#include "lua_common.h"
|
||||
|
||||
static int create_db (lua_State * L);
|
||||
@ -36,7 +36,7 @@ static const struct luaL_Reg cursor_mt [] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const struct luaL_Reg rarchdb_mt [] = {
|
||||
static const struct luaL_Reg libretrodb_mt [] = {
|
||||
{"__gc", db_close},
|
||||
{"list_all", db_cursor_open},
|
||||
{"query", db_query},
|
||||
@ -49,7 +49,7 @@ LUALIB_API int luaopen_testlib (lua_State * L) {
|
||||
lua_pushstring(L, "__index");
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, -3);
|
||||
luaL_openlib(L, NULL, rarchdb_mt, 0);
|
||||
luaL_openlib(L, NULL, libretrodb_mt, 0);
|
||||
|
||||
luaL_newmetatable(L, "RarchDB.Cursor");
|
||||
lua_pushstring(L, "__index");
|
||||
@ -61,13 +61,13 @@ LUALIB_API int luaopen_testlib (lua_State * L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct rarchdb_cursor * checkcursor(lua_State * L) {
|
||||
static libretrodb_cursor * checkcursor(lua_State * L) {
|
||||
void * ud = luaL_checkudata(L, 1, "RarchDB.Cursor");
|
||||
luaL_argcheck(L, ud != NULL, 1, "`RarchDB.Cursor' expected");
|
||||
return ud;
|
||||
}
|
||||
|
||||
static struct rarchdb * checkdb(lua_State * L) {
|
||||
static libretrodb * checkdb(lua_State * L) {
|
||||
void * ud = luaL_checkudata(L, 1, "RarchDB.DB");
|
||||
luaL_argcheck(L, ud != NULL, 1, "`RarchDB.DB' expected");
|
||||
return ud;
|
||||
@ -92,7 +92,7 @@ static int value_provider(
|
||||
if (lua_isnil(L, -1)) {
|
||||
rv = 1;
|
||||
} else if (lua_istable(L, -1)) {
|
||||
rv = rarchdb_lua_to_rmsgpack_value(L, -1, out);
|
||||
rv = libretrodb_lua_to_rmsgpack_value(L, -1, out);
|
||||
} else {
|
||||
printf("function `get_value' must return a table or nil\n");
|
||||
}
|
||||
@ -117,18 +117,18 @@ static int create_db (lua_State * L) {
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
rv = rarchdb_create(dst, &value_provider, L);
|
||||
rv = libretrodb_create(dst, &value_provider, L);
|
||||
close(dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int db_new (lua_State * L) {
|
||||
struct rarchdb * db = NULL;
|
||||
libretrodb_t * db = NULL;
|
||||
const char * db_file = NULL;
|
||||
int rv;
|
||||
db_file = luaL_checkstring(L, -1);
|
||||
db = lua_newuserdata(L, sizeof(struct rarchdb));
|
||||
if ((rv = rarchdb_open(db_file, db)) == 0) {
|
||||
db = lua_newuserdata(L, sizeof(libretrodb_t));
|
||||
if ((rv = libretrodb_open(db_file, db)) == 0) {
|
||||
luaL_getmetatable(L, "RarchDB.DB");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushnil(L);
|
||||
@ -141,18 +141,18 @@ static int db_new (lua_State * L) {
|
||||
}
|
||||
|
||||
static int db_close (lua_State * L) {
|
||||
struct rarchdb * db = checkdb(L);
|
||||
rarchdb_close(db);
|
||||
libretrodb_t *db = checkdb(L);
|
||||
libretrodb_close(db);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int db_query (lua_State * L) {
|
||||
int rv;
|
||||
struct rarchdb_cursor * cursor = NULL;
|
||||
struct rarchdb * db = checkdb(L);
|
||||
libretrodb_cursor_t *cursor = NULL;
|
||||
libretrodb_t *db = checkdb(L);
|
||||
const char * query = luaL_checkstring(L, -1);
|
||||
const char * error = NULL;
|
||||
rarchdb_query * q = rarchdb_query_compile(
|
||||
libretrodb_query_t *q = libretrodb_query_compile(
|
||||
db,
|
||||
query,
|
||||
strlen(query),
|
||||
@ -162,8 +162,8 @@ static int db_query (lua_State * L) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, error);
|
||||
} else {
|
||||
cursor = lua_newuserdata(L, sizeof(struct rarchdb));
|
||||
if ((rv = rarchdb_cursor_open(db, cursor, q)) == 0) {
|
||||
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);
|
||||
@ -172,16 +172,16 @@ static int db_query (lua_State * L) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, strerror(-rv));
|
||||
}
|
||||
rarchdb_query_free(q);
|
||||
libretrodb_query_free(q);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
static int db_cursor_open (lua_State * L) {
|
||||
int rv;
|
||||
struct rarchdb_cursor * cursor = NULL;
|
||||
struct rarchdb * db = checkdb(L);
|
||||
cursor = lua_newuserdata(L, sizeof(struct rarchdb));
|
||||
if ((rv = rarchdb_cursor_open(db, cursor, NULL)) == 0) {
|
||||
libretrodb_cursor_t *cursor = NULL;
|
||||
libretrodb_t *db = checkdb(L);
|
||||
cursor = lua_newuserdata(L, sizeof(libretrodb_t));
|
||||
if ((rv = libretrodb_cursor_open(db, cursor, NULL)) == 0) {
|
||||
luaL_getmetatable(L, "RarchDB.Cursor");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushnil(L);
|
||||
@ -193,8 +193,8 @@ static int db_cursor_open (lua_State * L) {
|
||||
return 2;
|
||||
}
|
||||
static int cursor_close (lua_State * L) {
|
||||
struct rarchdb_cursor * cursor = checkcursor(L);
|
||||
rarchdb_cursor_close(cursor);
|
||||
libretrodb_cursor_t *cursor = checkcursor(L);
|
||||
libretrodb_cursor_close(cursor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -272,9 +272,9 @@ static void push_rmsgpack_value(
|
||||
}
|
||||
|
||||
static int cursor_read (lua_State * L) {
|
||||
struct rarchdb_cursor * cursor = checkcursor(L);
|
||||
libretrodb_cursor_t *cursor = checkcursor(L);
|
||||
struct rmsgpack_dom_value value;
|
||||
if (rarchdb_cursor_read_item(cursor, &value) == 0) {
|
||||
if (libretrodb_cursor_read_item(cursor, &value) == 0) {
|
||||
push_rmsgpack_value(L, &value);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
@ -283,7 +283,7 @@ static int cursor_read (lua_State * L) {
|
||||
}
|
||||
|
||||
static int cursor_iter (lua_State * L) {
|
||||
struct rarchdb_cursor * cursor = checkcursor(L);
|
||||
libretrodb_cursor_t * cursor = checkcursor(L);
|
||||
luaL_getmetafield(L, -1, "read");
|
||||
lua_pushvalue(L, -2);
|
||||
return 2;
|
||||
|
@ -33,7 +33,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
#include "../libretrodb/rarchdb.h"
|
||||
#include "../libretrodb/libretrodb.h"
|
||||
#endif
|
||||
|
||||
#include "../input/input_remapping.h"
|
||||
@ -1596,8 +1596,8 @@ static int deferred_push_database_manager_list_deferred(void *data, void *userda
|
||||
{
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
int rv;
|
||||
struct rarchdb db;
|
||||
struct rarchdb_cursor cur;
|
||||
libretrodb_t db;
|
||||
libretrodb_cursor_t cur;
|
||||
struct rmsgpack_dom_value item;
|
||||
#endif
|
||||
unsigned i;
|
||||
@ -1611,13 +1611,13 @@ static int deferred_push_database_manager_list_deferred(void *data, void *userda
|
||||
|
||||
menu_list_clear(list);
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
if ((rv = rarchdb_open(path, &db)) != 0)
|
||||
if ((rv = libretrodb_open(path, &db)) != 0)
|
||||
return -1;
|
||||
|
||||
if ((rv = rarchdb_cursor_open(&db, &cur, NULL)) != 0)
|
||||
if ((rv = libretrodb_cursor_open(&db, &cur, NULL)) != 0)
|
||||
return -1;
|
||||
|
||||
while (rarchdb_cursor_read_item(&cur, &item) == 0)
|
||||
while (libretrodb_cursor_read_item(&cur, &item) == 0)
|
||||
{
|
||||
if (item.type != RDT_MAP)
|
||||
continue;
|
||||
@ -1636,8 +1636,8 @@ static int deferred_push_database_manager_list_deferred(void *data, void *userda
|
||||
}
|
||||
}
|
||||
|
||||
rarchdb_cursor_close(&cur);
|
||||
rarchdb_close(&db);
|
||||
libretrodb_cursor_close(&cur);
|
||||
libretrodb_close(&db);
|
||||
#endif
|
||||
menu_list_sort_on_alt(list);
|
||||
driver.menu->scroll_indices_size = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user