123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- #include "lua_lsup.h"
- #include "stackdump.h"
- #define check_graph(L) \
- *(LSUP_Graph **)luaL_checkudata(L, 1, "LSUP.Graph")
- static LSUP_Graph **allocate_graph (lua_State *L)
- {
- LSUP_Graph **gp = lua_newuserdatauv (L, sizeof (*gp), 1);
- luaL_getmetatable (L, "LSUP.Graph");
- lua_setmetatable (L, -2);
- return gp;
- }
- static int l_graph_new (lua_State *L)
- {
- const LSUP_StoreType store_type = lua_tointeger (L, 1);
- const char *uri_str = lua_tostring (L, 2);
- LSUP_Graph **gp = allocate_graph (L);
- LSUP_Store *store = NULL;
- if (store_type) {
- const LSUP_StoreInt *sif = LSUP_store_int (store_type);
- if (UNLIKELY (!sif)) return luaL_error (
- L, "No interface defined for store type: %d.", store_type);
- // TODO Move store creation fn and handle into a separate module.
- store = LSUP_store_new (store_type, NULL, 0);
- // Set up the store if a function for that is defined.
- if (sif->setup_fn) {
- if (sif->setup_fn(NULL, false) < LSUP_OK)
- return luaL_error (L, "Error initializing back end store.");
- }
- }
- // TODO Make store ID, nsm and initial size accessible.
- *gp = LSUP_graph_new (store, uri_str, NULL);
- LUA_NLCHECK (*gp, "Error creating graph.");
- return 1;
- }
- /*
- * Class methods.
- */
- static int l_graph_gc (lua_State *L)
- {
- LSUP_Graph *gr = check_graph (L);
- if (gr) LSUP_graph_free (gr);
- return 0;
- }
- static int l_graph_to_string (lua_State *L)
- {
- const LSUP_Graph *gr = check_graph (L);
- lua_pushfstring (
- L, "LSUP.Graph @%p <%s>: %d triples",
- gr, LSUP_graph_uri (gr)->data, LSUP_graph_size (gr));
- return 1;
- }
- static int l_graph_len (lua_State *L)
- {
- const LSUP_Graph *gr = check_graph (L);
- lua_pushinteger (L, LSUP_graph_size (gr));
- return 1;
- }
- static int l_graph_copy (lua_State *L)
- {
- const LSUP_Graph *src = check_graph (L);
- LSUP_Graph *dest = *(LSUP_Graph **)luaL_checkudata(L, 2, "LSUP.Graph");
- LUA_PCHECK (LSUP_graph_copy (src, dest), "Error copying graph");
- return 1;
- }
- static int l_graph_copy_contents (lua_State *L)
- {
- const LSUP_Graph *src = check_graph (L);
- LSUP_Graph *dest = *(LSUP_Graph **)luaL_checkudata (L, 2, "LSUP.Graph");
- const LSUP_Term *s, *p, *o;
- if lua_isnoneornil (L, 3) s = NULL;
- else s = *(LSUP_Term **)luaL_checkudata (L, 3, "LSUP.Term");
- if lua_isnoneornil (L, 4) p = NULL;
- else p = *(LSUP_Term **)luaL_checkudata (L, 4, "LSUP.Term");
- if lua_isnoneornil (L, 5) o = NULL;
- else o = *(LSUP_Term **)luaL_checkudata (L, 5, "LSUP.Term");
- LUA_PCHECK (LSUP_graph_copy_contents (
- src, dest, s, p, o), "Error copying graph.");
- return 1;
- }
- static int l_graph_equals (lua_State *L)
- {
- const LSUP_Graph *gr1 = check_graph (L);
- const LSUP_Graph *gr2 =
- *(LSUP_Graph **)luaL_checkudata (L, 2, "LSUP.Graph");
- LOG_DEBUG ("Comparing graphs %p %p", gr1, gr2);
- int eq_rc = LSUP_graph_equals (gr1, gr2);
- lua_pushboolean (L, eq_rc);
- return 1;
- }
- static int l_graph_contains (lua_State *L)
- {
- const LSUP_Graph *gr = check_graph (L);
- const LSUP_Triple *spo =
- *(LSUP_Triple **)luaL_checkudata (L, 2, "LSUP.Triple");
- lua_pushboolean (L, LSUP_graph_contains (gr, spo));
- return 1;
- }
- static int l_graph_add (lua_State *L)
- {
- LSUP_Graph *gr = check_graph (L);
- LOG_DEBUG ("Triples type: %s", lua_typename (L, lua_type (L, 2)));
- int rc;
- LSUP_rc lsup_rc;
- size_t i = 0, ct = 0;
- LSUP_GraphIterator *it = LSUP_graph_add_init (gr);
- while ((rc = lua_rawgeti (L, 2, ++i)) != LUA_TNIL) {
- //LOG_DEBUG ("Triple type: %s", lua_typename (L, rc));
- const LSUP_Triple *spo =
- *(LSUP_Triple **)luaL_checkudata (L, -1, "LSUP.Triple");
- LOG_DEBUG (
- "Got triple %d: {%s %s %s}\n",
- i, spo->s->data, spo->p->data, spo->o->data);
- lsup_rc = LSUP_graph_add_iter (it, spo);
- if (lsup_rc < LSUP_OK) break;
- if (lsup_rc == LSUP_OK) ct++;
- };
- LSUP_graph_add_done (it);
- lua_pushinteger (L, ct);
- if (UNLIKELY (lsup_rc < LSUP_OK)) return luaL_error (
- L, "Error adding triple at position %d: %s",
- i, LSUP_strerror (lsup_rc));
- else return 1;
- }
- static int l_graph_iter_next (lua_State *L)
- {
- LSUP_GraphIterator *it =
- *(LSUP_GraphIterator **)lua_touserdata (L, lua_upvalueindex (1));
- LSUP_Triple **spo_p = lua_newuserdatauv (L, sizeof (*spo_p), 1);
- luaL_getmetatable (L, "LSUP.Triple");
- lua_setmetatable (L, -2);
- LSUP_rc rc = LSUP_graph_iter_next (it, spo_p);
- if (rc == LSUP_END) {
- LSUP_graph_iter_free (it);
- lua_pushnil (L);
- lua_pushstring (L, "End of lookup results.");
- return 2;
- }
- LUA_PCHECK (rc, "Error retrieving a lookup result.");
- return 1;
- }
- static int l_graph_lookup (lua_State *L)
- {
- const LSUP_Graph *gr = check_graph (L);
- const LSUP_Term *s, *p, *o;
- if lua_isnoneornil (L, 2) s = NULL;
- else s = *(LSUP_Term **)luaL_checkudata (L, 2, "LSUP.Term");
- if lua_isnoneornil (L, 3) p = NULL;
- else p = *(LSUP_Term **)luaL_checkudata (L, 3, "LSUP.Term");
- if lua_isnoneornil (L, 4) o = NULL;
- else o = *(LSUP_Term **)luaL_checkudata (L, 4, "LSUP.Term");
- LSUP_GraphIterator **it_p =
- (LSUP_GraphIterator **)lua_newuserdata (L, sizeof *it_p);
- *it_p = NULL;
- luaL_getmetatable (L, "LSUP.GraphIterator");
- lua_setmetatable (L, -2);
- size_t ct;
- *it_p = LSUP_graph_lookup (gr, s, p, o, &ct);
- LUA_NLCHECK (*it_p, "Error creating graph iterator.");
- LOG_DEBUG ("Found triples: %d", ct);
- lua_pushcclosure (L, l_graph_iter_next, 1);
- return 1;
- }
- static int l_graph_connections (lua_State *L)
- {
- const LSUP_Graph *gr = check_graph (L);
- return 1;
- }
- static int l_graph_term_set (lua_State *L)
- {
- const LSUP_Graph *gr = check_graph (L);
- return 1;
- }
- static int l_graph_unique_terms (lua_State *L)
- {
- const LSUP_Graph *gr = check_graph (L);
- return 1;
- }
- /*
- * Library setup.
- */
- static const luaL_Reg graph_lib_fn [] = {
- {"new", l_graph_new},
- {NULL}
- };
- /*
- static const luaL_Reg graph_getters [] = {
- {"uri", l_graph_get_uri},
- {"namespace", l_graph_get_nsm},
- {NULL}
- };
- */
- /*
- static const luaL_Reg graph_setters [] = {
- {"uri", l_graph_set_uri},
- {NULL}
- };
- */
- static const luaL_Reg graph_lib_meth [] = {
- {"__eq", l_graph_equals},
- {"__gc", l_graph_gc},
- //{"__index", get_attr},
- //{"__newindex", set_attr},
- {"__tostring", l_graph_to_string},
- {"__len", l_graph_len},
- {"copy", l_graph_copy},
- {"copy_contents", l_graph_copy_contents},
- {"contains", l_graph_contains},
- {"add", l_graph_add},
- {"lookup", l_graph_lookup},
- {"connections", l_graph_connections},
- {"term_set", l_graph_term_set},
- {"unique_terms", l_graph_unique_terms},
- //{"to_n3", l_graph_to_n3},
- {NULL}
- };
- int luaopen_lsup_graph (lua_State *L)
- {
- LSUP_init(); // This is idempotent: no problem calling it multiple times.
- luaL_newmetatable (L, "LSUP.Graph");
- lua_pushvalue (L, -1);
- lua_setfield (L, -2, "__index");
- luaL_setfuncs (L, graph_lib_meth, 0);
- luaL_newmetatable (L, "LSUP.GraphIterator");
- /*
- // Getters table.
- lua_newtable (L);
- for (int i = 0; graph_getters[i].name != NULL; i++) {
- lua_pushcfunction (L, graph_getters[i].func);
- lua_setfield (L, -2, graph_getters[i].name);
- }
- // Set getters table as a value for the Graph metatable.
- lua_setfield (L, -2, "getters");
- */
- luaL_newlib (L, graph_lib_fn);
- return 1;
- }
|