webmcp

changeset 376:4bcedf32b089

Allow direct (proxy) access to fields of JSON object in a special column (set in the model) (write access not implemented yet)
author jbe
date Sat Nov 14 17:07:03 2015 +0100 (2015-11-14)
parents fb98b17056e5
children ecafddf7ac93
files libraries/mondelefant/mondelefant.lua libraries/mondelefant/mondelefant_native.c
line diff
     1.1 --- a/libraries/mondelefant/mondelefant.lua	Sat Nov 14 15:44:53 2015 +0100
     1.2 +++ b/libraries/mondelefant/mondelefant.lua	Sat Nov 14 17:07:03 2015 +0100
     1.3 @@ -915,11 +915,22 @@
     1.4  
     1.5  Primary key of a database class (model). Defaults to "id".
     1.6  
     1.7 +If the primary key is a tuple, then a sequence (table with integer keys mapped to the column names) must be used. If the primary key is contained in a JSON document within a table column, then a special object with the following fields is expected: {json_doc = "column_name", key = "field_name_within_json_object", type = "postgresql_type"}.
     1.8 +
     1.9  --]]--
    1.10  class_prototype.primary_key = "id"
    1.11  --//--
    1.12  
    1.13  --[[--
    1.14 +<db_class>.document_column
    1.15 +
    1.16 +Optional column name to redirect key lookups to. This can be used to allow for an easier access to fields of a JSON document.
    1.17 +
    1.18 +--]]--
    1.19 +class_prototype.document_column = nil
    1.20 +--//--
    1.21 +
    1.22 +--[[--
    1.23  db_handle =               -- database connection handle used by this class
    1.24  <db_class>:get_db_conn()
    1.25  
     2.1 --- a/libraries/mondelefant/mondelefant_native.c	Sat Nov 14 15:44:53 2015 +0100
     2.2 +++ b/libraries/mondelefant/mondelefant_native.c	Sat Nov 14 17:07:03 2015 +0100
     2.3 @@ -1490,80 +1490,87 @@
     2.4    // different lookup for lists and objects:
     2.5    if (result_type && !strcmp(result_type, "object")) {  // object
     2.6      lua_settop(L, 3);
     2.7 -    // try inherited attributes, methods or getter functions:
     2.8 -    while (lua_toboolean(L, 3)) {
     2.9 -      lua_getfield(L, 3, "object");  // 4
    2.10 -      lua_pushvalue(L, 2);  // 5
    2.11 -      lua_gettable(L, 4);  // 5
    2.12 -      if (!lua_isnil(L, 5)) return 1;
    2.13 -      lua_settop(L, 3);
    2.14 -      lua_getfield(L, 3, "object_get");  // 4
    2.15 -      lua_pushvalue(L, 2);  // 5
    2.16 -      lua_gettable(L, 4);  // 5
    2.17 -      if (lua_toboolean(L, 5)) {
    2.18 -        lua_pushvalue(L, 1);  // 6
    2.19 -        lua_call(L, 1, 1);  // 5
    2.20 +    lua_pushnil(L);
    2.21 +    lua_insert(L, 3);  // optional document column name on stack position 3
    2.22 +    // try inherited attributes, methods or getter functions
    2.23 +    // (and determine optional document column, if existent):
    2.24 +    while (lua_toboolean(L, 4)) {  // class on stack position 4 (due to insert)
    2.25 +      lua_getfield(L, 4, "object");  // 5
    2.26 +      lua_pushvalue(L, 2);  // 6
    2.27 +      lua_gettable(L, 5);  // 6
    2.28 +      if (!lua_isnil(L, 6)) return 1;
    2.29 +      lua_settop(L, 4);
    2.30 +      lua_getfield(L, 4, "object_get");  // 5
    2.31 +      lua_pushvalue(L, 2);  // 6
    2.32 +      lua_gettable(L, 5);  // 6
    2.33 +      if (lua_toboolean(L, 6)) {
    2.34 +        lua_pushvalue(L, 1);  // 7
    2.35 +        lua_call(L, 1, 1);  // 6
    2.36          return 1;
    2.37        }
    2.38 -      lua_settop(L, 3);
    2.39 -      lua_pushliteral(L, "prototype");  // 4
    2.40 -      lua_rawget(L, 3);  // 4
    2.41 -      lua_replace(L, 3);
    2.42 +      lua_settop(L, 4);
    2.43 +      if (lua_isnil(L, 3)) {
    2.44 +        lua_getfield(L, 4, "document_column");  // 5
    2.45 +        lua_replace(L, 3);
    2.46 +      }
    2.47 +      lua_pushliteral(L, "prototype");  // 5
    2.48 +      lua_rawget(L, 4);  // 5
    2.49 +      lua_replace(L, 4);
    2.50      }
    2.51 -    lua_settop(L, 2);
    2.52 +    lua_settop(L, 3);
    2.53      // try primary keys of referenced objects:
    2.54      lua_pushcfunction(L,
    2.55        mondelefant_class_get_foreign_key_reference_name
    2.56 -    );  // 3
    2.57 -    lua_getfield(L, 1, "_class");  // 4
    2.58 -    lua_pushvalue(L, 2);  // 5
    2.59 -    lua_call(L, 2, 1);  // 3
    2.60 -    if (!lua_isnil(L, 3)) {
    2.61 -      // reference name at stack position 3
    2.62 -      lua_pushcfunction(L, mondelefant_class_get_reference);  // 4
    2.63 -      lua_getfield(L, 1, "_class");  // 5
    2.64 -      lua_pushvalue(L, 3);  // 6
    2.65 -      lua_call(L, 2, 1);  // reference info at stack position 4
    2.66 -      lua_getfield(L, 1, "_ref");  // 5
    2.67 -      lua_getfield(L, 4, "ref");  // 6
    2.68 -      lua_gettable(L, 5);  // 6
    2.69 -      if (!lua_isnil(L, 6)) {
    2.70 -        if (lua_toboolean(L, 6)) {
    2.71 -          lua_getfield(L, 4, "that_key");  // 7
    2.72 -          if (lua_isnil(L, 7)) {
    2.73 +    );  // 4
    2.74 +    lua_getfield(L, 1, "_class");  // 5
    2.75 +    lua_pushvalue(L, 2);  // 6
    2.76 +    lua_call(L, 2, 1);  // 4
    2.77 +    if (!lua_isnil(L, 4)) {
    2.78 +      // reference name at stack position 4
    2.79 +      lua_pushcfunction(L, mondelefant_class_get_reference);  // 5
    2.80 +      lua_getfield(L, 1, "_class");  // 6
    2.81 +      lua_pushvalue(L, 4);  // 7
    2.82 +      lua_call(L, 2, 1);  // reference info at stack position 5
    2.83 +      lua_getfield(L, 1, "_ref");  // 6
    2.84 +      lua_getfield(L, 4, "ref");  // 7
    2.85 +      lua_gettable(L, 6);  // 7
    2.86 +      if (!lua_isnil(L, 7)) {
    2.87 +        if (lua_toboolean(L, 7)) {
    2.88 +          lua_getfield(L, 5, "that_key");  // 8
    2.89 +          if (lua_isnil(L, 8)) {
    2.90              return luaL_error(L, "Missing 'that_key' entry in model reference.");
    2.91            }
    2.92 -          lua_gettable(L, 6);  // 7
    2.93 +          lua_gettable(L, 7);  // 8
    2.94          } else {
    2.95            lua_pushnil(L);
    2.96          }
    2.97          return 1;
    2.98        }
    2.99      }
   2.100 -    lua_settop(L, 2);
   2.101 +    lua_settop(L, 3);
   2.102      // try normal data field info:
   2.103 -    lua_getfield(L, 1, "_data");  // 3
   2.104 -    lua_pushvalue(L, 2);  // 4
   2.105 -    lua_gettable(L, 3);  // 4
   2.106 -    if (!lua_isnil(L, 4)) return 1;
   2.107 -    lua_settop(L, 2);
   2.108 +    lua_getfield(L, 1, "_data");  // 4
   2.109 +    lua_pushvalue(L, 2);  // 5
   2.110 +    lua_gettable(L, 4);  // 5
   2.111 +    if (!lua_isnil(L, 5)) return 1;
   2.112 +    lua_settop(L, 3);  // TODO: keep _data table on stack
   2.113      // try cached referenced object (or cached NULL reference):
   2.114 -    lua_getfield(L, 1, "_ref");  // 3
   2.115 -    lua_pushvalue(L, 2);  // 4
   2.116 -    lua_gettable(L, 3);  // 4
   2.117 -    if (lua_isboolean(L, 4) && !lua_toboolean(L, 4)) {
   2.118 +    lua_getfield(L, 1, "_ref");  // 4
   2.119 +    lua_pushvalue(L, 2);  // 5
   2.120 +    lua_gettable(L, 4);  // 5
   2.121 +    if (lua_isboolean(L, 5) && !lua_toboolean(L, 5)) {
   2.122        lua_pushnil(L);
   2.123        return 1;
   2.124 -    } else if (!lua_isnil(L, 4)) {
   2.125 +    } else if (!lua_isnil(L, 5)) {
   2.126        return 1;
   2.127      }
   2.128 -    lua_settop(L, 2);
   2.129 +    lua_settop(L, 3);
   2.130      // try to load a referenced object:
   2.131 -    lua_pushcfunction(L, mondelefant_class_get_reference);  // 3
   2.132 -    lua_getfield(L, 1, "_class");  // 4
   2.133 -    lua_pushvalue(L, 2);  // 5
   2.134 -    lua_call(L, 2, 1);  // 3
   2.135 -    if (!lua_isnil(L, 3)) {
   2.136 +    lua_pushcfunction(L, mondelefant_class_get_reference);  // 4
   2.137 +    lua_getfield(L, 1, "_class");  // 5
   2.138 +    lua_pushvalue(L, 2);  // 6
   2.139 +    lua_call(L, 2, 1);  // 4
   2.140 +    if (!lua_isnil(L, 4)) {
   2.141        lua_settop(L, 2);
   2.142        lua_getfield(L, 1, "load");  // 3
   2.143        lua_pushvalue(L, 1);  // 4 (self)
   2.144 @@ -1576,6 +1583,18 @@
   2.145        if (lua_isboolean(L, 4) && !lua_toboolean(L, 4)) lua_pushnil(L);  // TODO: use special object instead of false
   2.146        return 1;
   2.147      }
   2.148 +    lua_settop(L, 3);
   2.149 +    // try proxy access to document in special column:
   2.150 +    if (lua_toboolean(L, 3)) {
   2.151 +      lua_getfield(L, 1, "_data");  // 4  TODO: keep on stack from earlier
   2.152 +      lua_insert(L, 3);  // column name to stack position 4
   2.153 +      lua_gettable(L, 3);  // 4
   2.154 +      if (!lua_isnil(L, 4)) {
   2.155 +        lua_pushvalue(L, 2);  // 5
   2.156 +        lua_gettable(L, 4);  // 5
   2.157 +        if (!lua_isnil(L, 5)) return 1;
   2.158 +      }
   2.159 +    }
   2.160      return 0;
   2.161    } else if (result_type && !strcmp(result_type, "list")) {  // list
   2.162      lua_settop(L, 3);

Impressum / About Us