· 8 years ago · Apr 13, 2018, 09:20 AM
1dbs={};
2data_types={"number","string","boolean"};
3local curDB;
4
5 --------- Shows the sql error ---------
6function sql_error(msg)
7error(msg);
8return msg;
9end
10
11 --------- simple table.find function ---------
12function tabFind(tab,val)
13for i,v in pairs(tab) do
14if v==val then
15return i;
16end end
17return false;
18end
19
20 --------- converts from string to whatever it is ---------
21function converto(str)
22if tonumber(str)~=nil then
23return tonumber(str);
24elseif str:lower()=="true" then
25return true;
26elseif str:lower()=="false" then
27return false;
28elseif (str:sub(1,1)=="'" and str:sub(str:len())=="'") or (str:sub(1,1)=='"' and str:sub(str:len())=='"') then
29return str:sub(2,str:len()-1);
30else
31return nil;
32end end
33
34 --------- PHP print_r function, only used for testing ---------
35_G.print_r=function(tab)
36if type(tab)=="table" then
37for i,v in pairs(tab) do
38if type(v)=="table" then
39print("[" .. i .. "] => array");
40print("(");
41_G.print_r(v);
42print(")");
43else
44print("[" .. i .. "] => " .. v);
45end end end end
46
47 --------- PHP explode function ---------
48_G.explode=function(strang,pattern,limit)
49local pattern="(.-)([" .. string.format("%q",pattern) .. "])";
50local limit=limit and limit-1;
51local return_array={};
52results=string.gsub(strang,pattern,function(a)
53table.insert(return_array,a);
54return "";
55end, Limit);
56table.insert(return_array,results)
57return return_array;
58end
59
60
61 --------- the query function :D ---------
62_G["sql_query"]=function(text)
63--print_r(dbs);
64 local str_ary=_G.explode(text,"%s");
65 for i=#str_ary,1,-1 do
66 if str_ary[i]=="" then
67 table.remove(str_ary,i);
68 end end
69 local i=1;
70 local done=false;
71 repeat
72
73 --------- use for selecting a database ---------
74 if str_ary[i]:lower()=="use" then
75 if not dbs[str_ary[i+1]] then
76 sql_error("Database '" .. curDB .. "' does not exist.");
77 return false;
78 else
79 curDB=str_ary[i+1];
80 end
81 i=i+2;
82
83 --------- show for showing the database information ---------
84 elseif str_ary[i]:lower()=="show" then
85 if str_ary[i+1] and str_ary[i+1]:lower()=="databases" then
86 for i,v in pairs(dbs) do
87 print(i);
88 end
89 i=i+2;
90
91 --------- show for table collumns/properties ---------
92 elseif str_ary[i+1] and str_ary[i+1]:lower()=="collumns" then
93 if str_ary[i+2] and str_ary[i+2]:lower()=="from" then
94 if str_ary[i+3] and str_ary[i+3]:lower():find("%.") then
95 local a=str_ary[i+3]:lower():find("%.");
96 local dbsel=str_ary[i+3]:sub(1,a-1);
97 local tablsel=str_ary[i+3]:sub(a+1);
98 if dbs[dbsel] then
99 if dbs[dbsel][tablsel] then
100 _G.print_r(dbs[dbsel][tablsel]['collumns']);
101 i=i+4;
102 else
103 sql_error("Table '" .. tablsel .. "' does not exist.");
104 return false;
105 end
106 else
107 sql_error("Database '" .. dbsel .. "' does not exist.");
108 return false;
109 end
110 else
111 sql_error("poo");
112 return false;
113 end
114 else
115 sql_error("FROM is required to find the database and table.");
116 end
117
118 --------- show for the tables in the database ---------
119 elseif str_ary[i+1] and str_ary[i+1]:lower()=="tables" then
120 if str_ary[i+2] and str_ary[i+2]:lower()=="from" then
121 if str_ary[i+3] and dbs[str_ary[i+3]] then
122 for i,v in pairs(dbs[str_ary[i+3]]) do
123 print(i);
124 end
125 i=i+4;
126 elseif str_ary[i+3] then
127 sql_error("Database '" .. str_ary[i+3] .. "' does not exist.");
128 return false;
129 else
130 sql_error("Database not specified");
131 return false;
132 end
133 else
134 sql_error("Database not specified");
135 return false;
136 end end
137
138 --------- create for database ---------
139 elseif str_ary[i] and str_ary[i]:lower()=="create" then
140 if str_ary[i+1]:lower()=="database" then
141 if str_ary[i+2] then
142 if not dbs[str_ary[i+2]] then
143 dbs[str_ary[i+2]]={};
144 i=i+3;
145 else
146 sql_error("Database '" .. str_ary[i+2] .. "' already exists.");
147 return false;
148 end
149 else
150
151 --------- create for tables ---------
152 sql_error("Database name field is required.");
153 return false;
154 end
155 elseif str_ary[i+1]:lower()=="table" then
156 if str_ary[i+2] then
157 local table_name=str_ary[i+2];
158 if str_ary[i+3]:sub(1,1)=="(" then
159 if str_ary[i+3]:sub(str_ary[i+3]:len(),str_ary[i+3]:len())==")" then
160 sql_error("Datatype not defined.");
161 return false;
162 else
163 local g=0;
164 local strang=str_ary[i+3]:sub(2) .. " ";
165 repeat g=g+1; if str_ary[i+3+g] then strang=strang .. str_ary[i+3+g]; if str_ary[i+3+g]:sub(str_ary[i+3+g]:len())~="," then strang=strang .. " "; end end until not str_ary[i+3+g] or str_ary[i+3+g]:sub(str_ary[i+3+g]:len())==")"
166 if str_ary[i+3+g] then
167 local ito=_G.explode(strang:sub(1,strang:len()-2),",");
168 local new_table={['props']={},['collumns']={}};
169 for _,v in pairs(ito) do
170 local HA=v:find("%s");
171 if HA and tabFind(data_types,v:sub(HA+1):lower()) then
172 new_table['props'][tostring(v:sub(1,HA-1))]=v:sub(HA+1):lower();
173 elseif HA then
174 sql_error(v:sub(HA+1) .. " is not an acceptable data type.");
175 return false;
176 else
177 sql_error("No data type specified.");
178 return false;
179 end
180 end
181 if curDB and dbs[curDB] then
182 dbs[curDB][table_name]=new_table;
183 i=i+3+g;
184 else
185 sql_error("database '" .. curDB .. "' not found.");
186 return false;
187 end
188 else
189 sql_error("parameters were not closed.");
190 return false;
191 end
192 end
193 else
194 sql_error("table not named.");
195 end
196 else
197 sql_error("No field identified for the 'create'");
198 return false;
199 end
200 end
201--------- The insert command ---------
202elseif str_ary[i] and str_ary[i]:lower()=="insert" then
203if str_ary[i+1] and str_ary[i+1]:lower()=="into" then
204if str_ary[i+2] then
205if dbs[curDB] then
206if dbs[curDB][str_ary[i+2]] then
207local table_name=str_ary[i+2];
208local fields;
209local strang,c="",0;
210if str_ary[i+3] and str_ary[i+3]:sub(1,1)=="(" then
211strang=strang .. str_ary[i+3]:sub(2);
212c=3;
213else
214sql_error("The indexes must be defined.");
215return false;
216end
217repeat c=c+1; if str_ary[i+c] then strang=strang .. str_ary[i+c]; if str_ary[i+c]:sub(str_ary[i+c]:len())~="," then strang=strang .. " "; end end until not str_ary[i+c] or str_ary[i+c]:sub(str_ary[i+c]:len())==")"
218fields=_G.explode(strang:sub(1,strang:len()-2),',');
219local vals;
220if str_ary[i+c+1] and str_ary[i+1+c]:lower():sub(1,6)=="values" then
221local strang,g="",0;
222if str_ary[i+1+c]:sub(7,7)=="(" then
223strang=strang .. str_ary[i+1+c]:sub(8);
224g=1+c;
225elseif str_ary[i+2+c]:sub(1,1)==")" then
226strang=strang .. str_ary[i+2+c]:sub(2);
227g=2+c;
228end
229repeat g=g+1; if str_ary[i+g] then strang=strang .. str_ary[i+g]; if str_ary[i+g]:sub(str_ary[i+g]:len())~="," then strang=strang .. " "; end end until not str_ary[i+g] or str_ary[i+g]:sub(str_ary[i+g]:len())==")"
230vals=_G.explode(strang:sub(1,strang:len()-1),',');
231local new_index={};
232for i,v in pairs(fields) do
233if (dbs[curDB][table_name]['props'][v]) then
234local plwit=vals[i];
235if plwit:lower()=="false" or plwit:lower()=="true" then
236if dbs[curDB][table_name]['props'][v]=="boolean" then
237new_index[v]=plwit:lower();
238else
239sql_error("'" .. v .. "' is not a boolean.");
240return false;
241end
242elseif tonumber(plwit)~=nil then
243if dbs[curDB][table_name]['props'][v]=="number" then
244new_index[v]=tonumber(plwit);
245else
246sql_error("'" .. v .. "' is not a number.");
247return false;
248end
249elseif (plwit:sub(1,1)=="'" and plwit:sub(plwit:len(),plwit:len())=="'") or (plwit:sub(1,1)=='"' and plwit:sub(plwit:len(),plwit:len())=='"') then
250if dbs[curDB][table_name]['props'][v]=="string" then
251new_index[v]=plwit:sub(2,plwit:len()-1);
252else
253sql_error("'" .. v .. "' is not a string.");
254return false;
255end
256else
257sql_error("values must be either a string, boolean or number.");
258return false;
259end
260else
261sql_error("Could not find '" .. v .. "'");
262return false;
263end end
264table.insert(dbs[curDB][table_name]['collumns'],new_index);
265i=i+g;
266else
267sql_error("You must define the values to insert.");
268return false;
269end
270else
271sql_error("Table '" .. str_ary[i+2] .. "' not found.");
272return false;
273end
274else
275sql_error("Database '" .. curDB .. "' not found.");
276return false;
277end
278else
279sql_error("No table name given.");
280return false;
281end
282else
283sql_error("INTO required to find the table.");
284return false;
285end
286 --------- SELECT ---------
287elseif str_ary[i]:lower()=="select" then
288 if str_ary[i+1]:lower()=="from" then
289--this is when I realized that it's probably easier to do the errors first.
290 sql_error("No fields to select were given.");
291 return false;
292 else
293 local strang,g='',0;
294 repeat g=g+1; strang=strang .. str_ary[i+g]; until not str_ary[i+g+1] or str_ary[i+g+1]:lower()=="from"
295 if not str_ary[i+g+1] then
296 sql_error("FROM is required to find the database and table.");
297 return false;
298 end
299 local return_what=_G.explode(strang,',');
300 local data_base,table_name;
301 local return_data={};
302 if not str_ary[i+g+2] then
303 sql_error("No table specified.");
304 return false;
305 elseif str_ary[i+g+2]:find("%.") then
306 local h=str_ary[i+g+2]:find("%.");
307 data_base=str_ary[i+g+2]:sub(1,h-1);
308 table_name=str_ary[i+g+2]:sub(h+1);
309 elseif not curDB or not dbs[curDB] then
310 sql_error("No database defined.");
311 return false;
312 else
313 data_base=curDB;
314 table_name=str_ary[i+g+2];
315 end
316 if not dbs[data_base] then
317 sql_error("Database '" .. data_base .. "' not found.");
318 return false;
319 elseif not dbs[data_base][table_name] then
320 sql_error("Table '" .. table_name .. "' not found.");
321 end
322 if #return_what==1 and return_what[1]=="*" then return_what={}; for qwerty,_ in pairs(dbs[data_base][table_name]['props']) do table.insert(return_what,qwerty); end end
323 if str_ary[i+g+3] and str_ary[i+g+3]:lower()=="where" then
324 if not str_ary[i+g+4] then
325 sql_error("Nothing after the WHERE you derp.");
326 return false;
327 end
328 local strang='';
329 for q=g+5,#str_ary do
330 strang=strang .. str_ary[q] .. " ";
331 end
332--big thanks to ElectricAxel for help here
333 strang:gsub("(%p)(%p-)", function(a,b) print(a,b); if a == ">" or a=="=" or a == "<" and not b then
334 local nom=strang:find(a,1);
335 local ps0=strang:sub(1,nom-1);
336 local ps1=strang:sub(nom+1,strang:len()-1);
337 if dbs[data_base][table_name]['props'][ps0] then
338 if type(converto(ps1)):lower()==dbs[data_base][table_name]['props'][ps0] then
339 for t,y in pairs(dbs[data_base][table_name]['collumns']) do
340 local new_tab={};
341 for _,v in pairs(return_what) do
342 if y[v] then
343 new_tab[v]=y[v];
344 end end
345 return_data[t]=new_tab;
346 end
347 else
348 sql_error("Use the right type you derp.");
349 return false;
350 end
351 else
352 sql_error("'" .. ps0 .. "' not found.");
353 return false;
354 end
355 elseif a == "!" or a == ">" or a == "<" and b == "=" then
356
357 only_one_cause_I_suck=true;
358 local nom=strang:find(a,1);
359 local ps0=strang:sub(1,nom-1):gsub("%s","");
360 local ps1=strang:sub(nom+2):gsub("%s","");
361 if dbs[data_base][table_name]['props'][ps0] then
362 if type(converto(ps1)):lower()==dbs[data_base][table_name]['props'][ps0] then
363 for t,y in pairs(dbs[data_base][table_name]['collumns']) do
364 local comparer=a=="!" and (y[ps0]~=converto(ps1)) or a==">" and (y[ps0]>=converto(ps1)) or a=="<" and (y[ps0]<=converto(ps1));
365 if comparer then
366 local new_tab={};
367 for i,v in pairs(return_what) do
368 if y[v] then
369 new_tab[i]=y[v];
370 end end end
371 return_data[t]=new_tab;
372 end
373 else
374 sql_error("Use the right type you derp.");
375 return false;
376 end
377 else
378 sql_error("'" .. ps0 .. "' not found.");
379 return false;
380 end
381 end end,1
382 )
383return return_data;
384 else
385 if #return_what==1 and return_what[1]=="*" then
386 return dbs[data_base][table_name]['collumns'];
387 else
388 for t,y in pairs(dbs[data_base][table_name]['collumns']) do
389 local new_tab={};
390 for _,v in pairs(return_what) do
391 if y[v] then
392 new_tab[v]=y[v];
393 end end
394 return_data[t]=new_tab;
395 end
396 return return_data;
397 end end end
398else
399sql_error("Why u say stupid stuff?");
400return false;
401end
402until i>=#str_ary
403end