· last year · Jan 21, 2024, 03:50 PM
1#if !defined MAX_DB_HANDLE
2 #define MAX_DB_HANDLE 10
3#endif
4#define MAX_QUERY_STRING 3072
5#define MAX_WHERE_STRING 128
6#define MAX_TABLE_NAME 50
7#define MAX_COLUMN_NAME 50
8#define MAX_COLUMN_VALUE_STRING 256
9#define MAX_COLUMN_VALUE_INT 20
10#define MAX_COLUMN_VALUE_FLOAT 128
11#define INVALID_DB_HANDLE -1
12
13enum E_DB_HANDLE_DATA
14{
15 _Table[MAX_TABLE_NAME],
16 _Where[MAX_WHERE_STRING],
17 _Value1[MAX_QUERY_STRING],
18 _Value2[MAX_QUERY_STRING],
19 _Query[MAX_QUERY_STRING],
20 _Elapsed
21}
22static __QueryData[MAX_DB_HANDLE][E_DB_HANDLE_DATA];
23
24static DB:__dbHandle[MAX_DB_HANDLE] = {DB:INVALID_DB_HANDLE, ...};
25
26forward OnDbExecuteQuery(DB:handle, sql[], bool:error, elapsed);
27
28stock DBResult:hook_db_query(DB:db, const query[], bool:use_result)
29{
30 new tick = GetTickCount();
31
32 new DBResult:result = db_query(db, query);
33 if(!use_result)
34 db_free_result(result);
35
36 CallLocalFunction("OnDbExecuteQuery", "isbi", _:db, query, (result < DBResult:1), (GetTickCount() - tick));
37 return result;
38}
39#if defined _ALS_db_query
40 #undef db_query
41#else
42 #define _ALS_db_query
43#endif
44#define db_query hook_db_query
45
46// --- COMMAND HANDLER ---
47
48stock db_query_handle(DB:handle, bool:force_handle = true)
49{
50 new idx = GetFreeDbHandleSlot();
51 if(force_handle)
52 {
53 new bool:wait_handle = false;
54 new wait_handle_tick = GetTickCount();
55 while(idx == -1)
56 {
57 wait_handle = true;
58 idx = GetFreeDbHandleSlot();
59 }
60
61 if(wait_handle)
62 printf("\n\n[E_DB WARN] Waiting for create new db handle (%ims)\n\n", GetTickCount() - wait_handle_tick);
63 }
64
65 if(idx == -1)
66 {
67 print("\n\n[E_DB ERROR] Error to create new db handle (%ims)\n\n");
68 return INVALID_DB_HANDLE;
69 }
70
71 __dbHandle[idx] = handle;
72 __QueryData[idx][_Elapsed] = GetTickCount();
73 return idx;
74}
75
76// --- TABLE CREATE ---
77
78stock db_create_table(handle, const name[])
79{
80 if(!IsValidDbHandle(handle) || !strlen(name))
81 {
82 ClearCashHandle(handle);
83 return false;
84 }
85
86 strcat(__QueryData[handle][_Value1], "CREATE TABLE IF NOT EXISTS ");
87 strcat(__QueryData[handle][_Value1], name);
88 return true;
89}
90
91stock db_add_column(handle, const name[], const datatype[])
92{
93 if(!IsValidDbHandle(handle) || !strlen(name) || !strlen(datatype))
94 {
95 ClearCashHandle(handle);
96 return false;
97 }
98
99 strcat(__QueryData[handle][_Value2], name);
100 strcat(__QueryData[handle][_Value2], " ");
101 strcat(__QueryData[handle][_Value2], datatype);
102 strcat(__QueryData[handle][_Value2], ",");
103 return true;
104}
105
106stock DBResult:db_execute_create_table(handle, bool:use_result = false, bool:debug_query = false)
107{
108 if(!IsValidDbHandle(handle) || !strlen(__QueryData[handle][_Value1]) || !strlen(__QueryData[handle][_Value2]))
109 {
110 ClearCashHandle(handle);
111 return DBResult:0;
112 }
113
114 strcat(__QueryData[handle][_Query], __QueryData[handle][_Value1]);
115 strcat(__QueryData[handle][_Query], " (");
116 strdel(__QueryData[handle][_Value2], strlen(__QueryData[handle][_Value2]) - 1, strlen(__QueryData[handle][_Value2]));
117 strcat(__QueryData[handle][_Query], __QueryData[handle][_Value2]);
118 strcat(__QueryData[handle][_Query], ");");
119
120 new DBResult:result = db_query(__dbHandle[handle], __QueryData[handle][_Query], use_result);
121 if(!use_result)
122 db_free_result(result);
123
124 if(debug_query)
125 printf(__QueryData[handle][_Query]);
126
127 ClearCashHandle(handle);
128 return result;
129}
130
131// --- TABLE DEFINE ---
132
133stock db_set_table(handle, const table[], bool:use_backticks = true)
134{
135 if(!IsValidDbHandle(handle) || !strlen(table))
136 {
137 ClearCashHandle(handle);
138 return false;
139 }
140
141 __QueryData[handle][_Table][0] = '\0';
142 if(use_backticks)
143 strcat(__QueryData[handle][_Table], "`");
144 strcat(__QueryData[handle][_Table], table);
145 if(use_backticks)
146 strcat(__QueryData[handle][_Table], "`");
147 return true;
148}
149
150// --- WHERE CLAUSE ---
151
152#pragma unused __temp@WhereClause
153
154new __temp@WhereClause[MAX_WHERE_STRING];
155#define db_set_where_clause_ex(%0,%1,%2)\
156 format(__temp@WhereClause, sizeof __temp@WhereClause, %1, %2),\
157 db_set_where_clause(%0, __temp@WhereClause)
158
159stock db_set_where_clause(handle, const where[])
160{
161 if(__dbHandle[handle] == DB:INVALID_DB_HANDLE || !strlen(where))
162 {
163 ClearCashHandle(handle);
164 return false;
165 }
166
167 strcat(__QueryData[handle][_Where], where);
168 return true;
169}
170
171// --- DELETE COMMAND ---
172
173stock DBResult:db_execute_delete(handle, bool:use_result = false, bool:debug_query = false)
174{
175 if(!IsValidDbHandle(handle) || !strlen(__QueryData[handle][_Table]))
176 {
177 ClearCashHandle(handle);
178 return DBResult:0;
179 }
180
181 strcat(__QueryData[handle][_Query], "DELETE FROM ");
182 strcat(__QueryData[handle][_Query], __QueryData[handle][_Table]);
183 if(__QueryData[handle][_Where][0] != '\0')
184 {
185 strcat(__QueryData[handle][_Query], " WHERE ");
186 strcat(__QueryData[handle][_Query], __QueryData[handle][_Where]);
187 }
188 strcat(__QueryData[handle][_Query], ";");
189
190 new DBResult:result = db_query(__dbHandle[handle], __QueryData[handle][_Query], use_result);
191
192 if(debug_query)
193 printf(__QueryData[handle][_Query]);
194
195 if(!use_result)
196 db_free_result(result);
197 ClearCashHandle(handle);
198 return result;
199}
200
201// --- SELECT COMMAND ---
202
203stock db_add_select(handle, const column[], const as[] = "", bool:use_backticks = true)
204{
205 if(!IsValidDbHandle(handle) || !strlen(column))
206 {
207 ClearCashHandle(handle);
208 return false;
209 }
210
211 if(use_backticks)
212 strcat(__QueryData[handle][_Value1], "`");
213 strcat(__QueryData[handle][_Value1], column);
214 if(use_backticks)
215 strcat(__QueryData[handle][_Value1], "`");
216
217 if(as[0] != '\0')
218 {
219 strcat(__QueryData[handle][_Value1], " AS ");
220 strcat(__QueryData[handle][_Value1], "`");
221 strcat(__QueryData[handle][_Value1], as);
222 strcat(__QueryData[handle][_Value1], "`");
223 }
224 strcat(__QueryData[handle][_Value1], ",");
225 return true;
226}
227
228stock DBResult:db_execute_select(handle, bool:use_result = false, bool:debug_query = false)
229{
230 if(!IsValidDbHandle(handle) || !strlen(__QueryData[handle][_Value1]) || !strlen(__QueryData[handle][_Table]))
231 {
232 ClearCashHandle(handle);
233 return DBResult:0;
234 }
235
236 strdel(__QueryData[handle][_Value1], strlen(__QueryData[handle][_Value1]) - 1, strlen(__QueryData[handle][_Value1]));
237
238 strcat(__QueryData[handle][_Query], "SELECT ");
239 strcat(__QueryData[handle][_Query], __QueryData[handle][_Value1]);
240 strcat(__QueryData[handle][_Query], " FROM ");
241 strcat(__QueryData[handle][_Query], __QueryData[handle][_Table]);
242 if(__QueryData[handle][_Where][0] != '\0')
243 {
244 strcat(__QueryData[handle][_Query], " WHERE ");
245 strcat(__QueryData[handle][_Query], __QueryData[handle][_Where]);
246 }
247 strcat(__QueryData[handle][_Query], ";");
248
249 new DBResult:result = db_query(__dbHandle[handle], __QueryData[handle][_Query], use_result);
250 if(!use_result)
251 db_free_result(result);
252
253 if(debug_query)
254 printf(__QueryData[handle][_Query]);
255
256 ClearCashHandle(handle);
257 return result;
258}
259
260// --- UPDATE COMMAND ---
261
262stock db_update_string(handle, const column[], const value[], bool:use_backticks = true)
263{
264 if(!IsValidDbHandle(handle) || !strlen(column))
265 {
266 ClearCashHandle(handle);
267 return false;
268 }
269
270 if(use_backticks)
271 strcat(__QueryData[handle][_Value1], "`");
272 strcat(__QueryData[handle][_Value1], column);
273 if(use_backticks)
274 strcat(__QueryData[handle][_Value1], "`");
275 strcat(__QueryData[handle][_Value1], "=");
276 strcat(__QueryData[handle][_Value1], "'");
277 strcat(__QueryData[handle][_Value1], value);
278 strcat(__QueryData[handle][_Value1], "'");
279 strcat(__QueryData[handle][_Value1], ",");
280 return true;
281}
282
283stock db_update_int(handle, const column[], value, bool:use_backticks = true)
284{
285 if(!IsValidDbHandle(handle) || !strlen(column))
286 {
287 ClearCashHandle(handle);
288 return false;
289 }
290
291 new valueStr[MAX_COLUMN_VALUE_INT];
292 valstr(valueStr, value);
293
294 if(use_backticks)
295 strcat(__QueryData[handle][_Value1], "`");
296 strcat(__QueryData[handle][_Value1], column);
297 if(use_backticks)
298 strcat(__QueryData[handle][_Value1], "`");
299 strcat(__QueryData[handle][_Value1], "=");
300 strcat(__QueryData[handle][_Value1], valueStr);
301 strcat(__QueryData[handle][_Value1], ",");
302 return true;
303}
304
305stock db_update_float(handle, const column[], Float:value, bool:use_backticks = true)
306{
307 if(!IsValidDbHandle(handle) || !strlen(column))
308 {
309 ClearCashHandle(handle);
310 return false;
311 }
312
313 new valueStr[MAX_COLUMN_VALUE_FLOAT];
314 format(valueStr, sizeof valueStr, "%f", value);
315
316 if(use_backticks)
317 strcat(__QueryData[handle][_Value1], "`");
318 strcat(__QueryData[handle][_Value1], column);
319 if(use_backticks)
320 strcat(__QueryData[handle][_Value1], "`");
321 strcat(__QueryData[handle][_Value1], "=");
322 strcat(__QueryData[handle][_Value1], valueStr);
323 strcat(__QueryData[handle][_Value1], ",");
324 return true;
325}
326
327stock DBResult:db_execute_update(handle, bool:use_result = false, bool:debug_query = false)
328{
329 if(!IsValidDbHandle(handle) || !strlen(__QueryData[handle][_Value1]) || !strlen(__QueryData[handle][_Table]))
330 {
331 ClearCashHandle(handle);
332 return DBResult:0;
333 }
334
335 strdel(__QueryData[handle][_Value1], strlen(__QueryData[handle][_Value1]) - 1, strlen(__QueryData[handle][_Value1]));
336
337 strcat(__QueryData[handle][_Query], "UPDATE ");
338 strcat(__QueryData[handle][_Query], __QueryData[handle][_Table]);
339 strcat(__QueryData[handle][_Query], " SET ");
340 strcat(__QueryData[handle][_Query], __QueryData[handle][_Value1]);
341 if(__QueryData[handle][_Where][0] != '\0')
342 {
343 strcat(__QueryData[handle][_Query], " WHERE ");
344 strcat(__QueryData[handle][_Query], __QueryData[handle][_Where]);
345 }
346 strcat(__QueryData[handle][_Query], ";");
347
348 new DBResult:result = db_query(__dbHandle[handle], __QueryData[handle][_Query], use_result);
349 if(!use_result)
350 db_free_result(result);
351
352 if(debug_query)
353 printf(__QueryData[handle][_Query]);
354
355 ClearCashHandle(handle);
356 return result;
357}
358
359// --- INSERT COMMAND ---
360
361stock db_insert_string(handle, const column[], const value[], bool:use_backticks = true)
362{
363 if(!IsValidDbHandle(handle) || !strlen(column))
364 {
365 ClearCashHandle(handle);
366 return false;
367 }
368
369 if(use_backticks)
370 strcat(__QueryData[handle][_Value1], "`");
371 strcat(__QueryData[handle][_Value1], column);
372 if(use_backticks)
373 strcat(__QueryData[handle][_Value1], "`");
374 strcat(__QueryData[handle][_Value1], ",");
375 strcat(__QueryData[handle][_Value2], "'");
376 strcat(__QueryData[handle][_Value2], value);
377 strcat(__QueryData[handle][_Value2], "'");
378 strcat(__QueryData[handle][_Value2], ",");
379 return true;
380}
381
382stock db_insert_int(handle, const column[], value, bool:use_backticks = true)
383{
384 if(!IsValidDbHandle(handle) || !strlen(column))
385 {
386 ClearCashHandle(handle);
387 return false;
388 }
389
390 new valueStr[MAX_COLUMN_VALUE_INT];
391 valstr(valueStr, value);
392
393 if(use_backticks)
394 strcat(__QueryData[handle][_Value1], "`");
395 strcat(__QueryData[handle][_Value1], column);
396 if(use_backticks)
397 strcat(__QueryData[handle][_Value1], "`");
398 strcat(__QueryData[handle][_Value1], ",");
399 strcat(__QueryData[handle][_Value2], valueStr);
400 strcat(__QueryData[handle][_Value2], ",");
401 return true;
402}
403
404stock db_insert_float(handle, const column[], Float:value, bool:use_backticks = true)
405{
406 if(!IsValidDbHandle(handle) || !strlen(column))
407 {
408 ClearCashHandle(handle);
409 return false;
410 }
411
412 new valueStr[MAX_COLUMN_VALUE_FLOAT];
413 format(valueStr, sizeof valueStr, "%f", value);
414
415 if(use_backticks)
416 strcat(__QueryData[handle][_Value1], "`");
417 strcat(__QueryData[handle][_Value1], column);
418 if(use_backticks)
419 strcat(__QueryData[handle][_Value1], "`");
420 strcat(__QueryData[handle][_Value1], ",");
421 strcat(__QueryData[handle][_Value2], valueStr);
422 strcat(__QueryData[handle][_Value2], ",");
423 return true;
424}
425
426stock DBResult:db_execute_insert(handle, bool:use_result = false, bool:debug_query = false)
427{
428 if(!IsValidDbHandle(handle) || !strlen(__QueryData[handle][_Value1]) || !strlen(__QueryData[handle][_Value2]) || !strlen(__QueryData[handle][_Table]))
429 {
430 ClearCashHandle(handle);
431 return DBResult:0;
432 }
433
434 strdel(__QueryData[handle][_Value1], strlen(__QueryData[handle][_Value1]) - 1, strlen(__QueryData[handle][_Value1]));
435 strdel(__QueryData[handle][_Value2], strlen(__QueryData[handle][_Value2]) - 1, strlen(__QueryData[handle][_Value2]));
436
437 strcat(__QueryData[handle][_Query], "INSERT INTO ");
438 strcat(__QueryData[handle][_Query], __QueryData[handle][_Table]);
439 strcat(__QueryData[handle][_Query], " (");
440 strcat(__QueryData[handle][_Query], __QueryData[handle][_Value1]);
441 strcat(__QueryData[handle][_Query], ") ");
442 strcat(__QueryData[handle][_Query], "VALUES");
443 strcat(__QueryData[handle][_Query], " (");
444 strcat(__QueryData[handle][_Query], __QueryData[handle][_Value2]);
445 strcat(__QueryData[handle][_Query], ");");
446
447 new DBResult:result = db_query(__dbHandle[handle], __QueryData[handle][_Query], use_result);
448 if(!use_result)
449 db_free_result(result);
450
451 if(debug_query)
452 printf(__QueryData[handle][_Query]);
453
454 ClearCashHandle(handle);
455 return result;
456}
457
458stock IsValidDbHandle(handle)
459{
460 if(handle < 0 || handle >= MAX_DB_HANDLE)
461 return false;
462
463 if(__dbHandle[handle] == DB:INVALID_DB_HANDLE)
464 return false;
465 return true;
466}
467
468// --- INTERNAL ---
469
470static stock ClearCashHandle(handle)
471{
472 if(!IsValidDbHandle(handle))
473 return false;
474
475 __QueryData[handle][_Table][0] = '\0';
476 __QueryData[handle][_Value1][0] = '\0';
477 __QueryData[handle][_Value2][0] = '\0';
478 __QueryData[handle][_Query][0] = '\0';
479 __QueryData[handle][_Where][0] = '\0';
480 __QueryData[handle][_Elapsed] = 0;
481 __dbHandle[handle] = DB:INVALID_DB_HANDLE;
482 return true;
483}
484
485static stock GetFreeDbHandleSlot()
486{
487 for(new i = 0; i < MAX_DB_HANDLE; i ++)
488 {
489 if(__dbHandle[i] == DB:-1)
490 return i;
491 }
492 return INVALID_DB_HANDLE;
493}