on master help sign in
tidying up the code
fa01173melissam
contribs/lib/SQLite3/._sqlite3api.c

Binary file not shown.

contribs/lib/SQLite3/sqlite3.tex+34−18
@@ -11,7 +11,7 @@
11 \begin{document}
11 \begin{document}
12 \section{Introduction}
12 \section{Introduction}
13\label{Introduction}
13\label{Introduction}
14−This document provides overview of how the library for SQLite works. The code base is written on top of the
14+This document provides overview on how the library for SQLite works. The code base is written on top of the
15SQLite3 C/C++ Interface.
15SQLite3 C/C++ Interface.
16This library supports some features of the low-level library, implemented in a higher level basis.
16This library supports some features of the low-level library, implemented in a higher level basis.
17The library allows making use of data types as queries. The aim of this library is to avoid
17The library allows making use of data types as queries. The aim of this library is to avoid
@@ -66,7 +66,7 @@ and returns the list as follows:
66\newline{(Just (1, VStr "data0")) ,(Just (2, VInt 1)) , (Just (3, VInt 2))}
66\newline{(Just (1, VStr "data0")) ,(Just (2, VInt 1)) , (Just (3, VInt 2))}
67
67
68The values in the list are binded to the statement using bindMulti function.
68The values in the list are binded to the statement using bindMulti function.
69−This function takes the statement pointer returned by prepare and the list returned by evalSQL,
69+This function takes the statement pointer returned by prepare and the list returned by evalSQL
70and binds the values by calling the appropriate functions.
70and binds the values by calling the appropriate functions.
71
71
72The function exec\_db\_v2 executes the statement.
72The function exec\_db\_v2 executes the statement.
@@ -75,7 +75,8 @@ around sqlite3\_prepare\_v2(), sqlite3\_step(), and sqlite3\_finalize(),
75without having to use a lot of code, though the use of this function is not recommended in this case.
75without having to use a lot of code, though the use of this function is not recommended in this case.
76
76
77The functions finalize\_db and close\_db must be called to clean up the open resources.
77The functions finalize\_db and close\_db must be called to clean up the open resources.
78−To print the result, the function toList\_v1 can be used which takes a DBPointer.
78+To print the result, the function toList\_v1 can be used which takes a DBPointer and returns
79+the resulting table.
79
80
80\subsection{More Examples}
81\subsection{More Examples}
81\label{More Examples}
82\label{More Examples}
@@ -88,18 +89,26 @@ Parsed as :
88SELECT data FROM (SELECT num data FROM tbl1 WHERE num = ?1)
89SELECT data FROM (SELECT num data FROM tbl1 WHERE num = ?1)
89
90
90Note that in this example, the inner query must include the same column as the outer one otherwise this query will not validate.
91Note that in this example, the inner query must include the same column as the outer one otherwise this query will not validate.
91−Use tricky examples of things that work and things that dont work
92
92
93−\section{Evaluating Queries}
94−\label{Evaluating Queries}
95\subsection{SQL Data Type}
93\subsection{SQL Data Type}
96\label{SQL Data Type}
94\label{SQL Data Type}
97The SQL Data Types describe the queries that are supported by the library.
95The SQL Data Types describe the queries that are supported by the library.
96+The implementation of these datatypes is similar to defining a grammar.
98Data type Value consists of Int, String and Float.
97Data type Value consists of Int, String and Float.
99The data type can be extended to further support queries.
98The data type can be extended to further support queries.
100The evaulator function makes use of smaller function to evaulate parts of the query.
99The evaulator function makes use of smaller function to evaulate parts of the query.
101−For instance given a SELECT qeury, it calls evalSQL to obtain the list of tables,
100+For instance given a SELECT qeury, it calls \emph{evalSQL} to obtain the list of tables,
102and clauseString to evaluate the rest of the expression which could include a WHERE clause or could be Empty.
101and clauseString to evaluate the rest of the expression which could include a WHERE clause or could be Empty.
102+
103+
104+\section{Evaluating Queries}
105+\label{Evaluating Queries}
106+The method used here is a divide and conquer manner which divides the query into smaller
107+parts and deals with each part and puts the results together to return a String representation
108+of the query and a list of values.
109+However this could result to a slow type checking process since it needs to go through all
110+the possibilities to type check. Maybe this can be improved?
111+
103\subsection{evalSQL Function}
112\subsection{evalSQL Function}
104\label{evalSQL Function}
113\label{evalSQL Function}
105This is a recursive evaluator which makes a call to itself.
114This is a recursive evaluator which makes a call to itself.
@@ -110,12 +119,13 @@ It returns the well-quoted String expression and a list of indexed values which
110\section{Pointers passed to Idris functions}
119\section{Pointers passed to Idris functions}
111\label{Pointers passed to Idris functions}
120\label{Pointers passed to Idris functions}
112
121
113−The library uses FFI. In order to make the pointers passed to functions more explicit,
122+The library uses FFI. In order to make the pointers passed to each function more explicit,
114−we have defined them as data types. For instance open\_db takes a String and returns a DBPointer and prepare\_db
123+we have defined them as data types. For instance open\_db takes a String and returns a DBPointer
124+(Database Pointer) and prepare\_db
115takes a DBPointer and returns a StmtPtr(Statemenet Pointer).
125takes a DBPointer and returns a StmtPtr(Statemenet Pointer).
116Error handling is done using the \emph {DB a} data type which
126Error handling is done using the \emph {DB a} data type which
117−is either \emph {IO String} which indicates an error or \emph{ IO a}.
127+is either \emph {IO String} indicating an error or \emph{ IO a}.
118−To test the functions in main, you need to use runDB which takes a \emph{ DB a} and returns IO a.
128+To test the functions in main, you need to use runDB :
119\begin{center}
129\begin{center}
120\centering runDB : DB a $\rightarrow$ IO a
130\centering runDB : DB a $\rightarrow$ IO a
121\end{center}
131\end{center}
@@ -123,11 +133,17 @@ More examples on how to use the functions can be found in \emph{testunit.idr}
123
133
124\section{Using the C Functions}
134\section{Using the C Functions}
125\label{Using the C Functions}
135\label{Using the C Functions}
126−
136+The library includes some wrapper functions such as get\_table
127−For example calling get\_table after prepare\_db could lead to
137+and exec\_db. Using these functions mixed with prepare, step or finalize
128−segmentation fault since get\_table calls sqlite3\_prepare etc
138+inappropriately could cause segmentation faults.
129−Functions such as exec\_db and get\_table are wrapper functions
130−and calling these before finalizing a prepared query could cause segmentation fault.
131−Perhaps these functions could be removed from the library if no longer required in the future.
139+Perhaps these functions could be removed from the library if no longer required in the future
132−
140+since the main purpose of this library is to make use of data types, or perhaps
141+these functionalities could be implemented internally without calling
142+the C Interface wrapper functions.
143+
144+\section{Further improving the library}
145+\label{Further improving the library}
146+There are many features that could be added to this library. These include adding more useful SQL Commands,
147+extending the SQL datatype to support more complex queries and possibly improving \emph{evalSQL}
148+for a faster performance.
133\end{document}
149\end{document}
contribs/lib/SQLite3/sqlite3api.c+2−66
@@ -17,7 +17,6 @@ static char sql_query_buffer[2000];
17// array used to store the string
17// array used to store the string
18//value obtain by get_val_text
18//value obtain by get_val_text
19unsigned char* array;
19unsigned char* array;
20−
21/*
20/*
22 open an SQLite database file as
21 open an SQLite database file as
23 specified by the filename argument.
22 specified by the filename argument.
@@ -38,7 +37,6 @@ void* sqlite3_open_idr(const char *filename){
38 return dbi;
37 return dbi;
39
38
40}
39}
41−
42/*
40/*
43 Frees the resource and returns 0 on success
41 Frees the resource and returns 0 on success
44 */
42 */
@@ -50,12 +48,10 @@ int sqlite3_close_idr(void* db){
50 free(dbi);
48 free(dbi);
51 return 0;
49 return 0;
52 }
50 }
53−
54 else {
51 else {
55 return res;
52 return res;
56 }
53 }
57}
54}
58−
59/*
55/*
60 SQLite wrapper around sqlite3_prepare_v2(),
56 SQLite wrapper around sqlite3_prepare_v2(),
61 sqlite3_step(), and sqlite3_finalize().
57 sqlite3_step(), and sqlite3_finalize().
@@ -64,11 +60,9 @@ int sqlite3_close_idr(void* db){
64 */
60 */
65int sqlite3_exec_idr(void* db, const char *sql)
61int sqlite3_exec_idr(void* db, const char *sql)
66{
62{
67−
68 DBinfo* dbi =(DBinfo*) db;
63 DBinfo* dbi =(DBinfo*) db;
69 char* err;
64 char* err;
70 int rc;
65 int rc;
71−
72 rc = sqlite3_exec(dbi->db_ptr,sql,NULL, NULL, &err);
66 rc = sqlite3_exec(dbi->db_ptr,sql,NULL, NULL, &err);
73 if (rc != SQLITE_OK && err != NULL) {
67 if (rc != SQLITE_OK && err != NULL) {
74 strncpy(dbi->buffer, err, sizeof(dbi->buffer));
68 strncpy(dbi->buffer, err, sizeof(dbi->buffer));
@@ -76,7 +70,6 @@ int sqlite3_exec_idr(void* db, const char *sql)
76 }
70 }
77 return rc;
71 return rc;
78}
72}
79−
80/*
73/*
81 Gets the error store in the buffer
74 Gets the error store in the buffer
82 in the struct. Some certain functions
75 in the struct. Some certain functions
@@ -86,15 +79,12 @@ char* sqlite3_get_error(void* db) {
86 DBinfo* dbi =(DBinfo*) db;
79 DBinfo* dbi =(DBinfo*) db;
87 return dbi->buffer;
80 return dbi->buffer;
88}
81}
89−
90−
91/*
82/*
92 Compiles the query into a byte-code program
83 Compiles the query into a byte-code program
93 Returns a pointer to the sqlite3_stmt pointer
84 Returns a pointer to the sqlite3_stmt pointer
94 and stores it in the struct.
85 and stores it in the struct.
95 */
86 */
96void* sqlite3_prepare_idr(void *db,const char *zSql){
87void* sqlite3_prepare_idr(void *db,const char *zSql){
97−
98 sqlite3_stmt* stmt;
88 sqlite3_stmt* stmt;
99 const char *tail;
89 const char *tail;
100
90
@@ -107,10 +97,8 @@ void* sqlite3_prepare_idr(void *db,const char *zSql){
107 if(rec != SQLITE_OK){
97 if(rec != SQLITE_OK){
108 return NULL;
98 return NULL;
109 }
99 }
110−
111 return dbi;
100 return dbi;
112}
101}
113−
114/*
102/*
115 Another wrapper interface that is preserved
103 Another wrapper interface that is preserved
116 for backwards compatibility.
104 for backwards compatibility.
@@ -118,7 +106,6 @@ void* sqlite3_prepare_idr(void *db,const char *zSql){
118 This was mainly used for testing within the
106 This was mainly used for testing within the
119 library.
107 library.
120 */
108 */
121−
122void* sqlite3_get_table_idr(void* db,
109void* sqlite3_get_table_idr(void* db,
123 const char *sql){
110 const char *sql){
124
111
@@ -127,9 +114,7 @@ void* sqlite3_get_table_idr(void* db,
127
114
128 Table* tbl = malloc(sizeof(Table));
115 Table* tbl = malloc(sizeof(Table));
129 tbl->database = dbi;
116 tbl->database = dbi;
130−
131 int res = sqlite3_get_table(dbi->db_ptr,sql,&tbl->table_data,&tbl->num_row,&tbl->num_col,&err);
117 int res = sqlite3_get_table(dbi->db_ptr,sql,&tbl->table_data,&tbl->num_row,&tbl->num_col,&err);
132−
133 int array_size = sizeof(&tbl->table_data);
118 int array_size = sizeof(&tbl->table_data);
134
119
135 if( res != SQLITE_OK && err != NULL){
120 if( res != SQLITE_OK && err != NULL){
@@ -137,16 +122,11 @@ void* sqlite3_get_table_idr(void* db,
137 sqlite3_free(err);
122 sqlite3_free(err);
138 return NULL;
123 return NULL;
139 }
124 }
140−
141 tbl -> data_size = array_size;
125 tbl -> data_size = array_size;
142− return tbl;
126+ return tbl;
143−
144}
127}
145
128
146−
147−
148/*
129/*
149−
150 This function executes queries.
130 This function executes queries.
151 This can be used after preparing a query
131 This can be used after preparing a query
152 In case of error or library misuse
132 In case of error or library misuse
@@ -171,7 +151,6 @@ int exec_db(void*p){
171 if(rc == SQLITE_ERROR && rc == SQLITE_MISUSE){
151 if(rc == SQLITE_ERROR && rc == SQLITE_MISUSE){
172 return 1;
152 return 1;
173 }
153 }
174−
175 row_counter =0;
154 row_counter =0;
176
155
177 while (rc == SQLITE_ROW) {
156 while (rc == SQLITE_ROW) {
@@ -184,7 +163,6 @@ int exec_db(void*p){
184 dbi->row_count = row_counter;
163 dbi->row_count = row_counter;
185 dbi->col_count = col;
164 dbi->col_count = col;
186 return rc;
165 return rc;
187−
188}
166}
189/*
167/*
190 Returns row number from DB Struct
168 Returns row number from DB Struct
@@ -195,12 +173,9 @@ int sqlite3_get_num_row_v2(void* p){
195 DBinfo* dbi =(DBinfo*) p;
173 DBinfo* dbi =(DBinfo*) p;
196 int row_number =dbi->row_count;
174 int row_number =dbi->row_count;
197 return row_number;
175 return row_number;
198−
199−
200}
176}
201
177
202/*
178/*
203−
204 Returns column number from DB Struct
179 Returns column number from DB Struct
205 */
180 */
206int sqlite3_get_num_col_v2(void* p){
181int sqlite3_get_num_col_v2(void* p){
@@ -208,11 +183,9 @@ int sqlite3_get_num_col_v2(void* p){
208 DBinfo* dbi =(DBinfo*) p;
183 DBinfo* dbi =(DBinfo*) p;
209 int col_number =dbi-> col_count;
184 int col_number =dbi-> col_count;
210 return col_number;
185 return col_number;
211−
212}
186}
213
187
214/*
188/*
215−
216 Another way of obtaining row number
189 Another way of obtaining row number
217 Thought this function gets the value
190 Thought this function gets the value
218 from Table struct. The value is stored
191 from Table struct. The value is stored
@@ -225,12 +198,9 @@ int sqlite3_get_num_row(void* p){
225 Table* tbl =(Table*) p;
198 Table* tbl =(Table*) p;
226 int row_number =tbl->num_row;
199 int row_number =tbl->num_row;
227 return row_number;
200 return row_number;
228−
229−
230}
201}
231
202
232/*
203/*
233−
234 Another way of obtaining column number
204 Another way of obtaining column number
235 Thought this function gets the value
205 Thought this function gets the value
236 from Table struct. The value is stored
206 from Table struct. The value is stored
@@ -238,13 +208,11 @@ int sqlite3_get_num_row(void* p){
238 Using this version is not recommended
208 Using this version is not recommended
239 unless used with get_table
209 unless used with get_table
240 */
210 */
241−
242int sqlite3_get_num_col(void* p){
211int sqlite3_get_num_col(void* p){
243
212
244 Table* tbl =(Table*) p;
213 Table* tbl =(Table*) p;
245 int col_number =tbl-> num_col;
214 int col_number =tbl-> num_col;
246− return col_number;
215+ return col_number;
247−
248}
216}
249
217
250/*
218/*
@@ -255,7 +223,6 @@ int sqlite3_get_num_col(void* p){
255 set the pointer to its initial state
223 set the pointer to its initial state
256 and then calls sqlite3_column_type
224 and then calls sqlite3_column_type
257 to get the type
225 to get the type
258−
259*/
226*/
260int sqlite3_get_data_type(void* p, int nRow, int nCol){
227int sqlite3_get_data_type(void* p, int nRow, int nCol){
261
228
@@ -277,24 +244,18 @@ int sqlite3_get_data_type(void* p, int nRow, int nCol){
277
244
278}
245}
279/*
246/*
280−
281 Obtains the integer value in a given column
247 Obtains the integer value in a given column
282*/
248*/
283
249
284int sqlite3_get_val_int(void* p, int nCol){
250int sqlite3_get_val_int(void* p, int nCol){
285
251
286−
287 DBinfo* dbi =(DBinfo*) p;
252 DBinfo* dbi =(DBinfo*) p;
288 int val, col;
253 int val, col;
289−
290 val =sqlite3_column_int(dbi->ppStmt, nCol);
254 val =sqlite3_column_int(dbi->ppStmt, nCol);
291 return val;
255 return val;
292−
293−
294}
256}
295
257
296/*
258/*
297−
298 Obtains the text value
259 Obtains the text value
299 Need to allocate memory to store the string
260 Need to allocate memory to store the string
300 Use GC_malloc since Boehm garbage collector
261 Use GC_malloc since Boehm garbage collector
@@ -306,16 +267,12 @@ const unsigned char* sqlite3_get_val_text(void* p,int nCol){
306 DBinfo* dbi =(DBinfo*) p;
267 DBinfo* dbi =(DBinfo*) p;
307 int rc,i, val, counter;
268 int rc,i, val, counter;
308 const unsigned char* text_val;
269 const unsigned char* text_val;
309−
310 array =(unsigned char *) GC_malloc(1000*sizeof(char));
270 array =(unsigned char *) GC_malloc(1000*sizeof(char));
311−
312 text_val =sqlite3_column_text(dbi->ppStmt, nCol);
271 text_val =sqlite3_column_text(dbi->ppStmt, nCol);
313 memcpy(array, text_val, strlen(text_val));
272 memcpy(array, text_val, strlen(text_val));
314−
315 return array;
273 return array;
316
274
317}
275}
318−
319float sqlite3_get_float(void* p, int nCol){
276float sqlite3_get_float(void* p, int nCol){
320
277
321 DBinfo* dbi =(DBinfo*) p;
278 DBinfo* dbi =(DBinfo*) p;
@@ -326,7 +283,6 @@ float sqlite3_get_float(void* p, int nCol){
326 return float_val;
283 return float_val;
327
284
328}
285}
329−
330/*
286/*
331 frees the pointer returned by get_table.
287 frees the pointer returned by get_table.
332 */
288 */
@@ -336,16 +292,12 @@ void sqlite3_free_table_idr(void* db){
336 sqlite3_free_table(tbl->table_data);
292 sqlite3_free_table(tbl->table_data);
337 free(tbl);
293 free(tbl);
338}
294}
339−
340−
341int sqlite3_step_idr(void* db){
295int sqlite3_step_idr(void* db){
342
296
343 DBinfo* dbi =(DBinfo*) db;
297 DBinfo* dbi =(DBinfo*) db;
344 int rc =sqlite3_step(dbi->ppStmt);
298 int rc =sqlite3_step(dbi->ppStmt);
345 return rc;
299 return rc;
346}
300}
347−
348−
349/*
301/*
350 Binds integer. This returns a pointer
302 Binds integer. This returns a pointer
351 because of the implementation of BindMulti
303 because of the implementation of BindMulti
@@ -375,7 +327,6 @@ void* sqlite3_bind_float_idr(void* p,int index, float val){
375 if(rc != SQLITE_OK){
327 if(rc != SQLITE_OK){
376 return NULL;
328 return NULL;
377 }
329 }
378−
379 return dbi;
330 return dbi;
380}
331}
381
332
@@ -401,10 +352,7 @@ void* sqlite3_bind_text_idr(void* p,const char* text, int index,int length){
401 }
352 }
402
353
403 return dbi;
354 return dbi;
404−
405}
355}
406−
407−
408/*
356/*
409 Used for testing column count function.
357 Used for testing column count function.
410 This function prepares query and by passing
358 This function prepares query and by passing
@@ -440,17 +388,13 @@ int sqlite3_column_count_idr(void* db, const char* tbl_name){
440 return rc;
388 return rc;
441}
389}
442
390
443−
444int sqlite3_data_count_idr(void* db){
391int sqlite3_data_count_idr(void* db){
445
392
446 DBinfo* dbi =(DBinfo*) db;
393 DBinfo* dbi =(DBinfo*) db;
447 int rc = sqlite3_data_count(dbi->ppStmt);
394 int rc = sqlite3_data_count(dbi->ppStmt);
448
395
449 return rc;
396 return rc;
450−
451}
397}
452−
453−
454/*
398/*
455 Must be called after prepare to clean up
399 Must be called after prepare to clean up
456 the resources.
400 the resources.
@@ -466,8 +410,6 @@ int sqlite3_complete_idr(const char *sql){
466
410
467 int rc = sqlite3_complete(sql);
411 int rc = sqlite3_complete(sql);
468 return rc;
412 return rc;
469−
470−
471}
413}
472
414
473/*
415/*
@@ -481,12 +423,10 @@ int sqlite3_reset_idr(void* db){
481 return rc;
423 return rc;
482
424
483}
425}
484−
485/*
426/*
486 The following routines may be used to
427 The following routines may be used to
487 obtain column related information.
428 obtain column related information.
488 */
429 */
489−
490const char *sqlite3_column_name_idr(void* db, int N){
430const char *sqlite3_column_name_idr(void* db, int N){
491
431
492 DBinfo* dbi=(DBinfo*) db;
432 DBinfo* dbi=(DBinfo*) db;
@@ -502,8 +442,6 @@ const char *sqlite3_column_decltype_idr(void* db,int n){
502 return dectype;
442 return dectype;
503
443
504}
444}
505−
506−
507int sqlite3_column_bytes_idr(void* db, int n){
445int sqlite3_column_bytes_idr(void* db, int n){
508
446
509 DBinfo* dbi=(DBinfo*) db;
447 DBinfo* dbi=(DBinfo*) db;
@@ -512,7 +450,6 @@ int sqlite3_column_bytes_idr(void* db, int n){
512
450
513
451
514}
452}
515−
516const void *sqlite3_column_blob_idr(void* db, int iCol){
453const void *sqlite3_column_blob_idr(void* db, int iCol){
517 DBinfo* dbi=(DBinfo*) db;
454 DBinfo* dbi=(DBinfo*) db;
518 const void* data =sqlite3_column_blob(dbi-> ppStmt, iCol);
455 const void* data =sqlite3_column_blob(dbi-> ppStmt, iCol);
@@ -590,7 +527,6 @@ int sqlite3_backup_pagecount_idr(void *backup){
590 return res;
527 return res;
591
528
592}
529}
593−
594/*
530/*
595 Get the length of string
531 Get the length of string
596 Need this in Idris since length will not
532 Need this in Idris since length will not