sqlite.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. #define HL_NAME(n) sqlite_##n
  2. #include <hl.h>
  3. #include <string.h>
  4. #include <sqlite3.h>
  5. /**
  6. <doc>
  7. <h1>SQLite</h1>
  8. <p>
  9. Sqlite is a small embeddable SQL database that store all its data into
  10. a single file. See http://sqlite.org for more details.
  11. </p>
  12. </doc>
  13. **/
  14. typedef struct _database sqlite_database;
  15. typedef struct _result sqlite_result;
  16. struct _database {
  17. void (*finalize)( sqlite_database * );
  18. sqlite3 *db;
  19. sqlite_result *last;
  20. };
  21. struct _result {
  22. void (*finalize)(sqlite_result * );
  23. sqlite_database *db;
  24. int ncols;
  25. int count;
  26. int *names; //hashed_names
  27. int *bools;
  28. int done;
  29. int first;
  30. sqlite3_stmt *r;
  31. };
  32. static void HL_NAME(error)( sqlite3 *db, bool close ) {
  33. hl_buffer *b = hl_alloc_buffer();
  34. hl_buffer_str(b, USTR("SQLite error: "));
  35. hl_buffer_str(b, sqlite3_errmsg16(db));
  36. if ( close )
  37. sqlite3_close(db);
  38. hl_error("%s",hl_buffer_content(b,NULL));
  39. }
  40. static void HL_NAME(finalize_request)(sqlite_result *r, bool exc ) {
  41. r->first = 0;
  42. r->done = 1;
  43. if( r->ncols == 0 )
  44. r->count = sqlite3_changes(r->db->db);
  45. if( sqlite3_finalize(r->r) != SQLITE_OK && exc )
  46. hl_error("SQLite error: Could not finalize request");
  47. r->r = NULL;
  48. r->db->last = NULL;
  49. r->db = NULL;
  50. free(r->names);
  51. free(r->bools);
  52. r->names = NULL;
  53. r->bools = NULL;
  54. }
  55. static void HL_NAME(finalize_result)(sqlite_result *r ) {
  56. if (r && r->db) HL_NAME(finalize_request)(r, false);
  57. }
  58. /**
  59. close : 'db -> void
  60. <doc>Closes the database.</doc>
  61. **/
  62. HL_PRIM void HL_NAME(close)( sqlite_database *db ) {
  63. if (db->last != NULL)
  64. HL_NAME(finalize_request)(db->last, false);
  65. if (sqlite3_close(db->db) != SQLITE_OK) {
  66. // No exception : we shouldn't alloc memory in a finalizer anyway
  67. }
  68. db->db = NULL;
  69. }
  70. static void HL_NAME(finalize_database)( sqlite_database *db ) {
  71. if (db && db->db) HL_NAME(close)(db);
  72. }
  73. /**
  74. connect : filename:string -> 'db
  75. <doc>Open or create the database stored in the specified file.</doc>
  76. **/
  77. HL_PRIM sqlite_database *HL_NAME(connect)( vbyte *filename ) {
  78. sqlite_database *db;
  79. sqlite3 *sqlite;
  80. if( sqlite3_open16(filename, &sqlite) != SQLITE_OK ) {
  81. HL_NAME(error)(sqlite, true);
  82. }
  83. db = (sqlite_database*)hl_gc_alloc_finalizer(sizeof(sqlite_database));
  84. db->finalize = HL_NAME(finalize_database);
  85. db->db = sqlite;
  86. db->last = NULL;
  87. return db;
  88. }
  89. /**
  90. last_insert_id : 'db -> int
  91. <doc>Returns the last inserted auto_increment id.</doc>
  92. **/
  93. HL_PRIM int HL_NAME(last_id)(sqlite_database *db ) {
  94. return (int)sqlite3_last_insert_rowid(db->db);
  95. }
  96. /**
  97. request : 'db -> sql:string -> 'result
  98. <doc>Executes the SQL request and returns its result</doc>
  99. **/
  100. HL_PRIM sqlite_result *HL_NAME(request)(sqlite_database *db, vbyte *sql ) {
  101. sqlite_result *r;
  102. const char *tl;
  103. int i,j;
  104. r = (sqlite_result*)hl_gc_alloc_finalizer(sizeof(sqlite_result));
  105. r->finalize = HL_NAME(finalize_result);
  106. r->db = NULL;
  107. if( sqlite3_prepare16_v2(db->db, sql, -1, &r->r, (const void**)&tl) != SQLITE_OK ) {
  108. HL_NAME(error)(db->db, false);
  109. }
  110. if( *tl ) {
  111. sqlite3_finalize(r->r);
  112. hl_error("SQLite error: Cannot execute several SQL requests at the same time");
  113. }
  114. r->db = db;
  115. r->ncols = sqlite3_column_count(r->r);
  116. r->names = (int*)malloc(sizeof(int)*r->ncols);
  117. r->bools = (int*)malloc(sizeof(int)*r->ncols);
  118. r->first = 1;
  119. r->done = 0;
  120. for(i=0;i<r->ncols;i++) {
  121. int id = hl_hash_gen((uchar*)sqlite3_column_name16(r->r,i), true);
  122. const char *dtype = sqlite3_column_decltype(r->r,i);
  123. for(j=0;j<i;j++)
  124. if( r->names[j] == id ) {
  125. if( strcmp(sqlite3_column_name16(r->r,i), sqlite3_column_name16(r->r,j)) == 0 ) {
  126. sqlite3_finalize(r->r);
  127. hl_buffer *b = hl_alloc_buffer();
  128. hl_buffer_str(b, USTR("SQLite error: Same field is two times in the request: "));
  129. hl_buffer_str(b, (uchar*)sql);
  130. hl_error("%s",hl_buffer_content(b, NULL));
  131. } else {
  132. hl_buffer *b = hl_alloc_buffer();
  133. hl_buffer_str(b, USTR("SQLite error: Same field ids for: "));
  134. hl_buffer_str(b, sqlite3_column_name16(r->r,i));
  135. hl_buffer_str(b, USTR(" and "));
  136. hl_buffer_str(b, sqlite3_column_name16(r->r,j));
  137. sqlite3_finalize(r->r);
  138. hl_error("%s",hl_buffer_content(b, NULL));
  139. }
  140. }
  141. r->names[i] = id;
  142. r->bools[i] = dtype?(strcmp(dtype,"BOOL") == 0):0;
  143. }
  144. // changes in an update/delete
  145. if( db->last != NULL )
  146. HL_NAME(finalize_request)(db->last, false);
  147. db->last = r;
  148. return db->last;
  149. }
  150. /**
  151. result_get_length : 'result -> int
  152. <doc>Returns the number of rows in the result or the number of rows changed by the request.</doc>
  153. **/
  154. HL_PRIM vdynamic *HL_NAME(result_get_length)( sqlite_result *r ) {
  155. if( r->ncols != 0 )
  156. return NULL;
  157. return hl_make_dyn(&r->count, &hlt_i32);
  158. }
  159. /**
  160. result_get_nfields : 'result -> int
  161. <doc>Returns the number of fields in the result.</doc>
  162. **/
  163. HL_PRIM int HL_NAME(result_get_nfields)( sqlite_result *r ) {
  164. return r->ncols;
  165. }
  166. /**
  167. result_get_fields : 'result -> array<string>
  168. <doc>Returns the array of field names in the result.</doc>
  169. **/
  170. HL_PRIM varray *HL_NAME(result_get_fields)( sqlite_result *r ) {
  171. varray *a = hl_alloc_array(&hlt_bytes, r->ncols);
  172. int i;
  173. for (i = 0; i < r->ncols; i++)
  174. {
  175. hl_aptr(a, vbyte*)[i] = (vbyte *)sqlite3_column_name16(r->r, i);
  176. }
  177. return a;
  178. }
  179. /**
  180. result_next : 'result -> object?
  181. <doc>Returns the next row in the result or [null] if no more result.</doc>
  182. **/
  183. HL_PRIM varray *HL_NAME(result_next)( sqlite_result *r ) {
  184. if( r->done )
  185. return NULL;
  186. switch( sqlite3_step(r->r) ) {
  187. case SQLITE_ROW:
  188. r->first = 0;
  189. varray *a = hl_alloc_array(&hlt_dyn, r->ncols);
  190. int i;
  191. for(i=0;i<r->ncols;i++)
  192. {
  193. vdynamic *v;
  194. switch( sqlite3_column_type(r->r,i) ) {
  195. case SQLITE_NULL:
  196. v = NULL;
  197. break;
  198. case SQLITE_INTEGER:
  199. {
  200. int vint = sqlite3_column_int(r->r, i);
  201. if (r->bools[i])
  202. v = hl_make_dyn(&vint, &hlt_bool);
  203. else
  204. v = hl_make_dyn(&vint, &hlt_i32);
  205. break;
  206. }
  207. case SQLITE_FLOAT:
  208. {
  209. double d = sqlite3_column_double(r->r, i);
  210. v = hl_make_dyn(&d, &hlt_f64);
  211. break;
  212. }
  213. case SQLITE_TEXT:
  214. {
  215. uchar *text16 = (uchar *)sqlite3_column_text16(r->r, i);
  216. vbyte *vb = hl_copy_bytes((vbyte *)text16, (int)(ustrlen(text16) + 1) * sizeof(uchar));
  217. v = hl_make_dyn(&vb, &hlt_bytes);
  218. break;
  219. }
  220. case SQLITE_BLOB:
  221. {
  222. int size = sqlite3_column_bytes(r->r, i);
  223. vbyte *blob = (vbyte *)sqlite3_column_blob(r->r, i);
  224. vbyte *vb = hl_copy_bytes(blob, size+1);
  225. varray *bytes_data = hl_alloc_array(&hlt_dyn, 2);
  226. hl_aptr(bytes_data, vdynamic*)[0] = hl_make_dyn(&vb, &hlt_bytes);
  227. hl_aptr(bytes_data, vdynamic*)[1] = hl_make_dyn(&size, &hlt_i32);
  228. v = hl_make_dyn(&bytes_data, &hlt_array);
  229. break;
  230. }
  231. default:
  232. hl_error("SQLite error: Unknown type #%d", sqlite3_column_type(r->r,i));
  233. }
  234. hl_aptr(a, vdynamic*)[i] = v;
  235. }
  236. return a;
  237. case SQLITE_DONE:
  238. HL_NAME(finalize_request)(r, true);
  239. return NULL;
  240. case SQLITE_BUSY:
  241. hl_error("SQLite error: Database is busy");
  242. case SQLITE_ERROR:
  243. HL_NAME(error)(r->db->db, false);
  244. default:
  245. return NULL;
  246. }
  247. return NULL;
  248. }
  249. /**
  250. result_get : 'result -> n:int -> string
  251. <doc>Return the [n]th field of the current result row.</doc>
  252. **/
  253. HL_PRIM vbyte *HL_NAME(result_get)( sqlite_result *r, int n ) {
  254. if (n < 0 || n >= r->ncols)
  255. return NULL;
  256. if( r->first )
  257. HL_NAME(result_next)(r);
  258. if( r->done )
  259. return NULL;
  260. return (vbyte*)sqlite3_column_text16(r->r, n);
  261. }
  262. /**
  263. result_get_int : 'result -> n:int -> int
  264. <doc>Return the [n]th field of the current result row as an integer.</doc>
  265. **/
  266. HL_PRIM vdynamic *HL_NAME(result_get_int)( sqlite_result *r, int n) {
  267. if (n < 0 || n >= r->ncols)
  268. return NULL;
  269. if( r->first )
  270. HL_NAME(result_next)(r);
  271. if( r->done )
  272. return NULL;
  273. int value = sqlite3_column_int(r->r, n);
  274. return hl_make_dyn(&value, &hlt_i32);
  275. }
  276. /**
  277. result_get_float : 'result -> n:int -> float
  278. <doc>Return the [n]th field of the current result row as a float.</doc>
  279. **/
  280. HL_PRIM vdynamic *HL_NAME(result_get_float)( sqlite_result *r, int n ) {
  281. if( n < 0 || n >= r->ncols )
  282. return NULL;
  283. if( r->first )
  284. HL_NAME(result_next)(r);
  285. if( r->done )
  286. return NULL;
  287. double value = sqlite3_column_double(r->r, n);
  288. return hl_make_dyn(&value, &hlt_f64);
  289. }
  290. #define _CONNECTION _ABSTRACT( sqlite_database )
  291. #define _RESULT _ABSTRACT( sqlite_result )
  292. DEFINE_PRIM(_CONNECTION, connect, _BYTES);
  293. DEFINE_PRIM(_VOID, close, _CONNECTION);
  294. DEFINE_PRIM(_RESULT, request, _CONNECTION _BYTES);
  295. DEFINE_PRIM(_I32, last_id, _CONNECTION);
  296. DEFINE_PRIM(_ARR, result_next, _RESULT);
  297. DEFINE_PRIM(_BYTES, result_get, _RESULT _I32);
  298. DEFINE_PRIM(_NULL(_I32), result_get_int, _RESULT _I32);
  299. DEFINE_PRIM(_NULL(_F64), result_get_float, _RESULT _I32);
  300. DEFINE_PRIM(_NULL(_I32), result_get_length, _RESULT);
  301. DEFINE_PRIM(_I32, result_get_nfields, _RESULT);
  302. DEFINE_PRIM(_ARR, result_get_fields, _RESULT);