Advertisement
Guest User

easyDB by WeBuLtRa

a guest
Apr 26th, 2012
316
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.53 KB | None | 0 0
  1. --------------### easy Database (eDB) ###------------
  2. require"luasql.mysql";
  3. eDB = {};
  4. eDB.env = luasql.mysql();
  5.  
  6. --------------### GLOBALS ###------------
  7. eDB.Version = "1.0.0.1";
  8. eDB.ABOUT = "easyDB is a approach to improve the luasql.mysql functions making it easier for the end user";
  9. eDB.database = "";
  10. eDB.con = {user="", pwd="", host="localhost", port=3306};
  11.  
  12. --------------### End user set up functions ###------------
  13. eDB.connect = function(database, user, pwd, host, port)
  14.     database = database or "mysql";
  15.     eDB.db = eDB.env:connect(database, user, pwd, host, port);
  16.     if eDB.db then
  17.         eDB.con = {user=user, pwd=pwd, host=host, port=port};
  18.         eDB.database = "`"..database.."`";
  19.         return true
  20.     else
  21.         return nil, "Couldn't start database connection with localhost\r\nu:root without pwd";
  22.     end
  23. end
  24.  
  25. eDB.setDatabase = function(data, user, pwd, host, port)
  26.     if eDB.db then
  27.         eDB.db:close();
  28.     end
  29.     user = user or eDB.con.user;
  30.     pwd = pwd or eDB.con.pwd;
  31.     host = host or eDB.con.host;
  32.     port = port or eDB.con.port
  33.     eDB.db = eDB.env:connect(data, user, pwd, host, port);
  34.     eDB.database = "`"..data.."`";
  35. end
  36. --
  37. --------------### End user functions ###------------
  38. --
  39. eDB.execute = function(query)
  40.     if not eDB.db then return nil, "Please connect to a database first using eDB.connect()"; end
  41.     if type(query) == "string" then
  42.         return eDB.db:execute(query);
  43.     else
  44.         return nil, "Invalid query";
  45.     end
  46. end
  47.  
  48. eDB.fetch = function(c,l, k)
  49.     local l = l or {};
  50.     local k = (k==nil) and "a" or (k=="n") and "n" or "a";
  51.     return function (l)
  52.         return c:fetch(l, k)
  53.     end,l,c, true
  54. end
  55.  
  56. eDB.listDatabases = function()
  57.     return eDB.easy("show databases");
  58. end
  59.  
  60. eDB.listTables = function()
  61.     if eDB.database and eDB.database ~= "" then
  62.         return eDB.easy("show tables FROM "..eDB.database);
  63.     else
  64.         return nil, "Please select a valid database";
  65.     end
  66. end
  67.  
  68. eDB.listFields = function(tbl)
  69.     if not eDB.db then return nil, "Please connect to a database first using eDB.connect()"; end
  70.     tbl = tbl or "";
  71.     if eDB.database and eDB.database ~= "" then
  72.         if tbl ~= "" then
  73.             local t = {};
  74.             local cur, e = eDB.db:execute("show fields FROM "..eDB.database..".`"..tbl.."`");
  75.             if cur then
  76.                 for row in eDB.fetch(cur, {}, "n") do
  77.                     table.insert(t, {Field = row[1], Type = row[2], Null = row[3], Key = row[4], Default = row[5], Extra = row[6]});
  78.                 end
  79.                 cur:close();
  80.             end
  81.             return t, e;
  82.         else
  83.             return nil, "Please select a vaild table";
  84.         end
  85.     else
  86.         return nil, "You haven't selected a valid database.\nPlease use eDB.setDB()";
  87.     end
  88. end
  89. --
  90. --------------### Smart functions ###------------
  91. --
  92. eDB.finish = function()
  93.     if eDB.db then
  94.         eDB.db:close();
  95.     end
  96.     if eDB.env then
  97.         eDB.env:close();
  98.     end
  99. end
  100. eDB.getFieldById = function(tbname, field, id)
  101.     id = tonumber(id) or 1;
  102.     local c, e = eDB.db:execute("SELECT `"..field.."` FROM "..eDB.database..".`"..tbname.."` WHERE id = "..id);
  103.     if c then
  104.         local t = c:fetch({}, "n");
  105.         c:close();
  106.         return t[1] or "NULL";
  107.     else
  108.         return nil, e;
  109.     end
  110. end
  111. eDB.getLastInsertId = function()
  112.     local a, e = eDB.db:execute("SELECT LAST_INSERT_ID();");
  113.     if a then
  114.         local t = a:fetch({}, "n");
  115.         return t[1] or 0;
  116.     else
  117.         return nil, e;
  118.     end
  119. end
  120. eDB.insert = function(tbl, tblFields, auto_rollback,...)
  121.     if not eDB.db then return nil, "Please connect to a database first using eDB.connect()"; end
  122.     local next = arg[1];
  123.     if auto_rollback and not next then
  124.         eDB.db:execute("BEGIN;");
  125.     end
  126.     if (eDB.database == "") then return nil, "You haven't set a valid database" end
  127.     if type(tbl)=="string" then
  128.         local aff, err, ist = 0, nil, false;
  129.         if type(tblFields) == "table" then
  130.             local fields, values = "", "";
  131.             for x, y in pairs(tblFields) do
  132.                 if type(y) == "table" then
  133.                     ist = true;
  134.                     local a, e = eDB.insert(tbl, y, auto_rollback, true);
  135.                     if not a then
  136.                         err = (err==nil) and "Error executing query: "..e or err.."\r\nError executing query: "..e;
  137.                         if auto_rollback then
  138.                             return nil, err;
  139.                         else
  140.                             return aff, err;
  141.                         end
  142.                     else
  143.                         aff = aff + a;
  144.                     end
  145.                 else
  146.                     local tmp = (type(y) == "number") and y or "'"..eDB.realescape(y).."'";
  147.                     fields = (fields == "") and "`"..x.."`" or fields..", `"..x.."`";
  148.                     values = (values == "") and tmp or values..", "..tmp;
  149.                 end
  150.             end
  151.             if ist then
  152.                 if auto_rollback then
  153.                     eDB.db:execute("COMMIT;");
  154.                 end
  155.                 return aff, err;
  156.             else
  157.                 local query = string.format("INSERT INTO "..eDB.database..".`"..tbl.."`(%s) VALUES (%s);", fields, values);
  158.                 local a, e = eDB.db:execute(query);
  159.                 if not a then
  160.                     if auto_rollback then
  161.                         eDB.db:rollback();
  162.                     end
  163.                     return nil, e;
  164.                 else
  165.                     return a, query
  166.                 end
  167.             end
  168.         else
  169.             return nil, "Invalid second argument";
  170.         end
  171.     else
  172.         return nil, "Invalid first argument";
  173.     end
  174. end
  175. eDB.returnTable = function(query, ret)
  176.     if not eDB.db then return nil, "Please connect to a database first using eDB.connect()"; end
  177.     local tb = {};
  178.     local cur,e = eDB.db:execute(query);
  179.     if cur then
  180.         local n = cur:numrows();
  181.         if n == 0 then return nil, "Zero rows returned" end
  182.         for row in eDB.fetch(cur, {}, ret) do
  183.             --?
  184.             local t = {};
  185.             for k,v in pairs(row) do
  186.                 t[k] = v;
  187.             end
  188.             table.insert(tb, t);
  189.         end
  190.         cur:close();
  191.         return tb;
  192.     else
  193.         return nil, e;
  194.     end
  195. end
  196. eDB.find = function(kind, props)
  197.     if not eDB.db then return nil, "Please connect to a database first using eDB.connect()"; end
  198.     if not kind or not props or type(props) ~= "table" then return nil, "Second argument must be a table"; end
  199.     kind = kind:lower();
  200.     local kinds = {"all", "count", "first", "list"};
  201.     local properties = {};
  202.     properties.From = false;
  203.     properties.Fields = "*";
  204.     properties.Where = "";
  205.     properties.Limit = "";
  206.     properties.GroupBy = "";
  207.     properties.Order = "";
  208.     properties.ret = "a";
  209.     for k, v in pairs(properties) do
  210.         properties[k] = props[k] or v;
  211.     end
  212.     properties.ret = (properties.ret ~= nil) and (properties.ret == "a") and properties.ret or "n" or "n";
  213.  
  214.     kind = eDB.in_array(kind, kinds);
  215.     if not kind then return false; end
  216.     if not properties.From then
  217.         return nil, "Please submit a valid table to query";
  218.     end
  219.     properties.From = (type(properties.From) == "string") and properties.From or table.concat(properties.From, ",");
  220.     if (type(properties.Where) == "table") then
  221.         local s = "";
  222.         for k, v in pairs(properties.Where) do
  223.             local tmp = (type(v)=="number") and tostring(v) or v:lower();
  224.             if tmp:find("^not in") or tmp:find("^rlike") or tmp:find("^like") or tmp:find("^<>") or tmp:find("^!=") or tmp:find("^in") or tmp:find("^is") then
  225.                 s = (s=="") and "`"..k.."` "..v or s.." AND `"..k.."` "..v;
  226.             else
  227.                 s = (s=="") and "`"..k.."`='"..v.."'" or s.." AND `"..k.."`='"..v.."'";
  228.             end
  229.         end
  230.         properties.Where = s;
  231.     end
  232.     properties.Where = (properties.Where ~= "") and " WHERE "..properties.Where or "";
  233.     properties.GroupBy = (type(properties.GroupBy) == "string") and properties.GroupBy or table.concat(properties.GroupBy, ",");
  234.     properties.GroupBy = (properties.GroupBy ~= "") and " GROUP BY "..properties.GroupBy or "";
  235.  
  236.     properties.Order = (type(properties.Order) == "string") and properties.Order or table.concat(properties.Order, ",");
  237.     properties.Order = (properties.Order ~= "") and " ORDER BY "..properties.Order or "";
  238.  
  239.     properties.Limit = (properties.Limit ~= "") and " LIMIT "..properties.Limit or "";
  240.     local query = "SELECT ";
  241.     if kind == "all" then
  242.         properties.Fields = (type(properties.Fields) == "string") and properties.Fields:gsub("%s*,%s*", ",") or properties.Fields;
  243.         properties.Fields = (type(properties.Fields) == "string") and properties.Fields:gsub(",", "`,`") or table.concat(properties.Fields, "`, `");
  244.         properties.Fields = (properties.Fields~= "*") and "`"..properties.Fields.."`" or "*";
  245.         query = query..properties.Fields.." FROM "..eDB.database.."."..properties.From..properties.Where..properties.GroupBy..properties.Order..properties.Limit;
  246.         return eDB.returnTable(query, properties.ret);
  247.     elseif kind == "count" then
  248.         if (type(properties.Fields) == "string") then
  249.             properties.Fields = "count("..properties.Fields..")";
  250.         else
  251.             return nil, "properties.Fields can't be a table, must be a string";
  252.         end
  253.         query = query..properties.Fields.." FROM "..eDB.database.."."..properties.From..properties.Where..properties.GroupBy;
  254.         local a, e = eDB.returnTable(query, "n");
  255.         if a then
  256.             return a[1][1];
  257.         else
  258.             return a, e;
  259.         end
  260.     elseif kind == "first" then
  261.         properties.Fields = (type(properties.Fields) == "string") and properties.Fields or table.concat(properties.Fields, ", ");
  262.         query = query..properties.Fields.." FROM "..eDB.database.."."..properties.From..properties.Where;
  263.         local t, e = eDB.returnTable(query, properties.ret);
  264.         return (type(t) == "table") and t[1] or t, e;
  265.     else--list
  266.         if type(properties.Fields) == "string" and properties.Fields == "*" then
  267.             local fields, e = eDB.listFields(properties.From);
  268.             if fields then
  269.                 local a, b, c = "", "", "";
  270.                 for k, v in pairs(fields) do
  271.                     if v.Key == "PRI" then
  272.                         a = v.Field;
  273.                     elseif v.Field == "name" or v.Field == "title" then
  274.                         b = v.Field;
  275.                     elseif v.Type:find("varchar") then
  276.                         c = v.Field;
  277.                     end
  278.                     if a ~= "" and b ~= "" then break; end
  279.                     if k == #fields then
  280.                         if a ~= "" then
  281.                             if b == "" and c == "" then return false;
  282.                             elseif b == "" and c ~= "" then b = c; end
  283.                         else
  284.                             return nil, "Haven't found a primary key to index the list";
  285.                         end
  286.                     end
  287.                 end
  288.                 properties.Fields = a..", "..b;
  289.                 query = query..properties.Fields.." FROM "..eDB.database.."."..properties.From..properties.Where..properties.GroupBy..properties.Order..properties.Limit;
  290.                 return eDB.easyb(query);
  291.             else
  292.                 return fields, e;
  293.             end
  294.         elseif type(properties.Fields) == "string" then
  295.             local _, _, a, b = properties.Fields:find("(.+),(.+)");
  296.             if a and b then
  297.                 properties.Fields = a..", "..b;
  298.                 query = query..properties.Fields.." FROM "..eDB.database.."."..properties.From..properties.Where..properties.GroupBy..properties.Order..properties.Limit;
  299.                 return eDB.easyb(query);
  300.             else
  301.                 return nil, "Please submit a valid properties.Fields string like field1,field2";
  302.             end
  303.         elseif type(properties.Fields) == "table" then
  304.             if #properties.Fields == 2 then
  305.                 properties.Fields = table.concat(properties.Fields, ",");
  306.                 query = query..properties.Fields.." FROM "..eDB.database.."."..properties.From..properties.Where..properties.GroupBy..properties.Order..properties.Limit;
  307.                 return eDB.easyb(query);
  308.             else
  309.                 return nil, "Please submit a valid properties.Fields table with 2 elements";
  310.             end
  311.         end
  312.     end
  313. end
  314. --
  315. --------------### End user auxiliary functions ###------------
  316. --
  317. eDB.getDatabase = function()
  318.     return eDB.database:gsub("`", "");
  319. end
  320.  
  321. --
  322. eDB.in_array = function(str, tbl)
  323.     if type(str) == "string" and type(tbl) == "table" then
  324.         for x, v in pairs(tbl) do
  325.             if type(v) == "string" then
  326.                 if str:lower() == v:lower() then
  327.                     return str;
  328.                 end
  329.             end
  330.         end
  331.     end
  332.     return nil;
  333. end
  334.  
  335. --
  336. eDB.realescape = function(a)
  337.     return a:gsub("[^%w]", { ["'"] = "''"});
  338. end
  339.  
  340. --
  341. eDB.htmlentities = function(s)
  342.     return s:gsub("[^%w]", { ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;", ["'"] = "&apos;", ["="] = "&equals;",["/"]="&#47;", ["#"] = "&#35;" });
  343. end
  344. --
  345. --------------### Internal auxiliary functions ###------------
  346. --
  347. eDB.listChilds = function(t, tb)
  348.     tb = tb or {};
  349.     for x, y in pairs(t) do
  350.         table.insert(tb, y.id);
  351.         if y._subs then
  352.             eDB.listChilds(y._subs,tb);
  353.         end
  354.     end
  355.     table.sort(tb);
  356.     return tb;
  357. end
  358. --
  359. eDB.easy = function(query)
  360.     if not eDB.db then return nil, "Please connect to a database first using eDB.connect()"; end
  361.     if type(query) == "string" then
  362.         local t = {};
  363.         local cur = eDB.db:execute(query);
  364.         for row in eDB.fetch(cur, {}, "n") do
  365.             table.insert(t, row[1]);
  366.         end
  367.         cur:close();
  368.         return t;
  369.     else
  370.         return nil, "Invalid query: "..query;
  371.     end
  372. end
  373. --
  374. eDB.easyb = function(query)
  375.     if not eDB.db then return nil, "Please connect to a database first using eDB.connect()"; end
  376.     if type(query) == "string" then
  377.         local cur, e = eDB.db:execute(query);
  378.         if cur then
  379.             local n = cur:numrows();
  380.             if n == 0 then return false end
  381.             local tb = {};
  382.             for row in eDB.fetch(cur, {}, "n") do
  383.                 for k,v in pairs(row) do
  384.                     tb[row[1]] = row[2] or "NULL";
  385.                 end
  386.             end
  387.             cur:close();
  388.             return tb;
  389.         else
  390.             return cur, e;
  391.         end
  392.     else
  393.         return nil, "Invalid query: "..query;
  394.     end
  395. end
  396. ------------### by WeBuLtRa ###-----------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement