lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


First off what a great mailing list:

> You do not need 'eval' at all.
Agreed, I need it in one place, I will explain later, but yeah evals are terrible for performance.

>I believe you want someting like this:
   function createLuaObjectColumn(n)
     local n = {}
     local n_Iel  = {}
     local n_Stbl = {}

     local function n_setter(tbl,k,v)
       if not n_Iel[k] and n_Stbl[k] then
         setIndex(n,k,v)
       else
         if v == nil then
           deleteIndex(n,k)
         else
           updateIndex(n,k,n_Stbl[k],v)
         end
       end
       rawset(n_Stbl,k,v)
     end
     setmetatable(n,{
       __index    = n_Stbl;
       __newindex = n_setter;
     })
     return n
   end
>I'm not sure what is the point of "a_Iel".
Just sloppy coding

>Also, the name 'a', is hardcoded in lines 31 and 32, you should be using 'n'.
Slop

> Also also, when you do need to use loadstring(), you should consider
using string.format() instead of all the string concatenation.
String concatenation is lame, so agreed and deprecated.

New Version:
NOTES: "ASQL" is just a cheap namespace (sloppy but getting better)
This designates an Index on the table "CUSTOMER", column "STATE"

Usage:
create_nested_table("ASQL","CUSTOMER","state")
luaobj_assign("ASQL","CUSTOMER","state","pk_1",'{name = \'RUSS\', age=35, state=20}')
indexLORfield("ASQL","CUSTOMER","state","pk_1","state");
print (ASQL["CUSTOMER"]["state"]["pk_1"].state)
->20
ASQL.CUSTOMER.state.pk_1.state=33;
-> updateIndex: rname: ASQL.CUSTOMER.state.pk_1 key: state old: 20 new: 33
print (ASQL["CUSTOMER"]["state"]["pk_1"].state)
->33

There can be any number of tables, w/ any number of columns, w/ many many primary-keys, each referencing an EVAL-ed piece of LUA (which can have many elements)

-- START CODE
function setIndex(rname, key, val)
  if (key == nil or val == nil) then return; end
  print ('setIndex: rname: ' .. rname .. ' key: ' .. key .. ' val: ' .. val);
end
function deleteIndex(rname, key)
  print ('deleteIndex: tbl: ' .. rname .. ' key: ' .. key);
end
function updateIndex(rname, key, old, new)
  print ('updateIndex: rname: ' .. rname .. ' key: ' .. key ..
                     ' old: '   .. old   .. ' new: ' .. new);
end

Stbl = {}; Iel  = {};

function ASQL_setter(rname, k, v)
  local name  = rname._name; --print('ASQL_setter: name: ' .. name);
  if (Iel[name][k] ~= nil) then
    if (Stbl[name][k] == nil) then setIndex   (name, k, v);
    else
      if (v == nil) then           deleteIndex(name ,k);
      else                         updateIndex(name, k, Stbl[name][k], v);
      end
    end
  end
  rawset(Stbl[name], k, v);
end

-- NOTE this MUST not be called from Lua (only From C)
function indexLORfield(asql, tbl, col, pk, el)
  local name = asql .. '.' .. tbl .. '.' .. col .. '.' .. pk;
  Iel [name][el] = true;
  --print ('indexLORfield: ' .. name .. ' el: ' .. el); dump(Iel);
end

-- LUAOBJ_ASSIGNMENT LUAOBJ_ASSIGNMENT LUAOBJ_ASSIGNMENT LUAOBJ_ASSIGNMENT
function create_nested_table(asql, tbl, col)
  if (_G[asql]           == nil) then _G[asql]           = {}; end
  if (_G[asql][tbl]      == nil) then _G[asql][tbl]      = {}; end
  if (_G[asql][tbl][col] == nil) then _G[asql][tbl][col] = {}; end
end

function luaobj_assign(asql, tbl, col, pk, luae) -- create Lua Object Row
  local name = asql .. '.' .. tbl .. '.' .. col .. '.' .. pk;
  Stbl[name] = {}; Iel[name] = {};
  _G[asql][tbl][col][pk] = {};
  local cmd  = 'Stbl[\'' .. name .. '\'] = ' .. luae .. '; '; --print(cmd);
  assert(loadstring(cmd))()
  _G[asql][tbl][col][pk]._name = name;
  setmetatable(_G[asql][tbl][col][pk],
               {__index=Stbl[name], __newindex=ASQL_setter});
end

-- END CODE

So this is ugly, but it is getting better, one EVAL (which is needed) and pretty straightforward logic w/ the goal of triggering index updates.

any hints to improve performance/readability/etc.. more than welcome, rip it apart :)

- jak

p.s the next I am gonna fix is "pk_1" which represents an INTEGER PrimaryKey and is just terribly inefficient (so it will be iterated away)