dict @ fc26d6542276e17f3206a00b996162397d875e93

feat: Initial commit

Add initial code form dealing with sqlite.
  1diff --git a/.gitignore b/.gitignore
  2new file mode 100644
  3index 0000000000000000000000000000000000000000..567609b1234a9b8806c5a05da6c866e480aa148d
  4--- /dev/null
  5+++ b/.gitignore
  6@@ -0,0 +1 @@
  7+build/
  8diff --git a/CMakeLists.txt b/CMakeLists.txt
  9new file mode 100644
 10index 0000000000000000000000000000000000000000..2614aa6f52b569feba19c53168c92e37ffaa32d3
 11--- /dev/null
 12+++ b/CMakeLists.txt
 13@@ -0,0 +1,11 @@
 14+cmake_minimum_required(VERSION 3.26)
 15+
 16+project(dict VERSION 0.1 LANGUAGES C)
 17+
 18+file(GLOB src CONFIGURE_DEPENDS "*.h" "*.c")
 19+add_executable(dict ${src})
 20+
 21+target_compile_options(dict PRIVATE -Wall -Wextra -Wpedantic -Werror)
 22+target_include_directories(dict PUBLIC "${PROJECT_BINARY_DIR}")
 23+target_link_libraries(dict sqlite3)
 24+
 25diff --git a/data.c b/data.c
 26new file mode 100644
 27index 0000000000000000000000000000000000000000..5a9a103daf2dd02f9b494385a08cbbe4a8e316ea
 28--- /dev/null
 29+++ b/data.c
 30@@ -0,0 +1,183 @@
 31+#include <stdlib.h>
 32+#include <stdio.h>
 33+
 34+#include "data.h"
 35+
 36+const char *insert_into = "INSERT INTO words (LINE) VALUES($VVV);";
 37+const char *select_words = "SELECT Id, Line FROM words LIMIT 10;";
 38+const char *create_table =  "CREATE TABLE IF NOT EXISTS words (ID INTEGER PRIMARY KEY AUTOINCREMENT, LINE TEXT NOT NULL);";
 39+
 40+Data* new_data(const char* con) {
 41+    Data* data = (Data*)malloc(sizeof(Data));
 42+
 43+    int v = sqlite3_open(con, &(data->db));
 44+    if (v == SQLITE_OK) {
 45+        return data;
 46+    }
 47+
 48+    print_result_code(v);
 49+    return NULL;
 50+}
 51+
 52+
 53+void free_data(Data* data) {
 54+    sqlite3_close(data->db);
 55+    free(data);
 56+}
 57+
 58+void insert(Data* data, char* line) {
 59+    sqlite3_stmt *stmt; 
 60+    int r = sqlite3_prepare_v2(data->db, insert_into, -1, &stmt, NULL);
 61+
 62+    if (r != SQLITE_OK) {
 63+        printf("Error executing insert: ");
 64+        print_result_code(r);
 65+        printf("\n");
 66+        return;
 67+    }
 68+
 69+    // binds the paremets to the statement, in this case the line;
 70+    sqlite3_bind_text(stmt, 1, line, -1, NULL);
 71+
 72+    int c = sqlite3_step(stmt);
 73+    if (c != SQLITE_DONE) {
 74+        printf("Error executing insert: ");
 75+        print_result_code(r);
 76+        printf("\n");
 77+    }
 78+}
 79+
 80+void bootstrap(Data* data) {
 81+    sqlite3_stmt *stmt; 
 82+    int r = sqlite3_prepare_v2(data->db, create_table, -1, &stmt, NULL);
 83+
 84+    if (r != SQLITE_OK) {
 85+        printf("Error preparing bootstrap: ");
 86+        print_result_code(r);
 87+        printf("\n");
 88+        return;
 89+    }
 90+
 91+    int c = sqlite3_step(stmt);
 92+    if (c != SQLITE_DONE) {
 93+        printf("Error executing bootstrap: ");
 94+        print_result_code(r);
 95+        printf("\n");
 96+    }
 97+}
 98+
 99+LIST* select(Data* data) {
100+    sqlite3_stmt *stmt; 
101+    int r = sqlite3_prepare_v2(data->db, select_words, -1, &stmt, NULL);
102+
103+    if (r != SQLITE_OK) {
104+        printf("Error executing select: ");
105+        print_result_code(r);
106+        printf("\n");
107+        return NULL;
108+    }
109+
110+    LIST *list = NULL;
111+
112+    int m =  sqlite3_step(stmt);
113+    while(m == SQLITE_ROW) {
114+        Word *word = (Word*)malloc(sizeof(Word));
115+
116+        int id = sqlite3_column_int(stmt, 0);
117+        const unsigned char *line = sqlite3_column_text(stmt, 1);
118+
119+        word->Id = id;
120+        word->Line = line;
121+        list = list_add(list, word);
122+
123+        m = sqlite3_step(stmt);
124+    }
125+
126+    sqlite3_finalize(stmt);
127+
128+    return list;
129+}
130+
131+void print_result_code(int code) {
132+    switch(code) {
133+        // Primary result code
134+        case SQLITE_ABORT:
135+            printf("SQLITE_ABORT");
136+            break;
137+        case SQLITE_AUTH:
138+            printf("SQLITE_AUTH");
139+            break;
140+        case SQLITE_BUSY:
141+            printf("SQLITE_BUSY");
142+            break;
143+        case SQLITE_CANTOPEN:
144+            printf("SQLITE_CANTOPEN");
145+            break;
146+        case SQLITE_CONSTRAINT:
147+            printf("SQLITE_CONSTRAINT");
148+            break;
149+        case SQLITE_CORRUPT:
150+            printf("SQLITE_CORRUPT");
151+            break;
152+        case SQLITE_DONE:
153+            printf("SQLITE_DONE");
154+            break;
155+        case SQLITE_EMPTY:
156+            printf("SQLITE_EMPTY");
157+            break;
158+        case SQLITE_ERROR:
159+            printf("SQLITE_ERROR");
160+            break;
161+        case SQLITE_FORMAT:
162+            printf("SQLITE_FORMAT");
163+            break;
164+        case SQLITE_INTERNAL:
165+            printf("SQLITE_INTERNAL");
166+            break;
167+        case SQLITE_INTERRUPT:
168+            printf("SQLITE_INTERRUPT");
169+            break;
170+        case SQLITE_IOERR:
171+            printf("SQLITE_IOERR");
172+            break;
173+        case SQLITE_LOCKED:
174+            printf("SQLITE_LOCKED");
175+            break;
176+        case SQLITE_MISMATCH:
177+            printf("SQLITE_MISMATCH");
178+            break;
179+        case SQLITE_MISUSE:
180+            printf("SQLITE_MISUSE");
181+            break;
182+        case SQLITE_NOLFS:
183+            printf("SQLITE_NOLFS");
184+            break;
185+        case SQLITE_NOMEM:
186+            printf("SQLITE_NOMEM");
187+            break;
188+        case SQLITE_NOTADB:
189+            printf("SQLITE_NOTADB");
190+            break;
191+        case SQLITE_NOTFOUND:
192+            printf("SQLITE_NOTFOUND");
193+            break;
194+        case SQLITE_NOTICE:
195+            printf("SQLITE_NOTICE");
196+            break;
197+        case SQLITE_OK:
198+            printf("SQLITE_OK");
199+            break;
200+        case SQLITE_PERM:
201+            printf("SQLITE_PERM");
202+            break;
203+        case SQLITE_SCHEMA:
204+            printf("SQLITE_SCHEMA");
205+            break;
206+        case SQLITE_TOOBIG:
207+            printf("SQLITE_TOOBIG");
208+            break;
209+        case SQLITE_WARNING:
210+            printf("SQLITE_WARNING");
211+            break;
212+    }
213+}
214diff --git a/data.h b/data.h
215new file mode 100644
216index 0000000000000000000000000000000000000000..db8aedc2a5e9ea62ef2f577718b9dbf8418c9a4c
217--- /dev/null
218+++ b/data.h
219@@ -0,0 +1,47 @@
220+#pragma once
221+#include <sqlite3.h>
222+#include "list.h"
223+
224+/*
225+ * This word into the dictionary
226+ */
227+typedef struct word {
228+    int Id;
229+    const unsigned char *Line;
230+} Word;
231+
232+/*
233+ * This is database connection.
234+ */
235+typedef struct data {
236+    sqlite3 *db;
237+} Data;
238+
239+
240+/*
241+ * create a new data struct from sqlite filename.
242+ */
243+Data* new_data(const char*);
244+
245+
246+void free_data(Data*);
247+
248+/*
249+ * Create the tables.
250+ */
251+void bootstrap(Data*);
252+
253+/*
254+ * insert line into database.
255+ */
256+void insert(Data*, char*);
257+
258+/*
259+ * Select all words.
260+ */
261+LIST* select(Data*);
262+
263+/*
264+ * Print result code from sqlite.
265+ */
266+void print_result_code(int error);
267diff --git a/list.c b/list.c
268new file mode 100644
269index 0000000000000000000000000000000000000000..a40dd576db2dcc385a4bb2f4fb8f6f4e99102793
270--- /dev/null
271+++ b/list.c
272@@ -0,0 +1,44 @@
273+#include "list.h"
274+#include <stdlib.h>
275+
276+LIST* list_add(LIST* list, void* item)
277+{
278+
279+    if (list == NULL)
280+    {
281+        list = (LIST*)malloc(sizeof(LIST));
282+        list->size = 0;
283+        list->list = (void**)malloc(sizeof(0));
284+
285+    }
286+
287+    list->size ++;
288+    void** new_list = (void**)reallocarray(list->list, list->size, sizeof(void*));
289+
290+    new_list[list->size-1] = item;
291+    list->list = new_list;
292+
293+    return list;
294+
295+}
296+
297+LIST* list_remove(LIST* list, unsigned int pos)
298+{
299+    for(unsigned int i = pos; i < list->size - 1; i++)
300+        list->list[i] = list->list[i + 1];
301+
302+    list->size--;
303+
304+    void** new_list = reallocarray(list->list, list->size, sizeof(void*));
305+    list->list = new_list;
306+
307+    return list;
308+}
309+
310+void list_free(LIST* list) {
311+    for (unsigned int x = 0; x < list->size; x++) 
312+        free(list->list[x]);
313+
314+    free(list->list);
315+    free(list);
316+}
317diff --git a/list.h b/list.h
318new file mode 100644
319index 0000000000000000000000000000000000000000..e33bf017753ff3c93db620c320e024cd2b18ec8a
320--- /dev/null
321+++ b/list.h
322@@ -0,0 +1,27 @@
323+#pragma once
324+#include <stdlib.h>
325+
326+#define LIST_SIZE_FACTOR 1.5
327+struct list {
328+    unsigned int size;
329+    unsigned int allocated_size;
330+    void** list;
331+};
332+
333+typedef struct list LIST;
334+
335+/**
336+* Add an item to a list
337+* @list: array list structure.
338+* @item: item to be added to the list.
339+*/
340+LIST* list_add(LIST* list, void* item);
341+
342+/**
343+* Remove an item from a given list
344+* @list: array list structure.
345+* @pos: position of item to be removed.
346+*/
347+LIST* list_remove(LIST* list, unsigned int pos);
348+
349+void list_free(LIST* list);
350diff --git a/main.c b/main.c
351new file mode 100644
352index 0000000000000000000000000000000000000000..720871ca2071734484ce7c6feb3b9ae706e2c4a1
353--- /dev/null
354+++ b/main.c
355@@ -0,0 +1,20 @@
356+#include <stdio.h>
357+#include <sqlite3.h>
358+
359+#include "data.h"
360+
361+int main() {
362+    Data *data = new_data(":memory:");
363+
364+    bootstrap(data);
365+    for (int x = 0; x < 10000; x++)
366+        insert(data, "LINE X");
367+
368+    LIST *list = select(data);
369+
370+    for (unsigned int x = 0; x < list->size; x++) 
371+        printf("This is a line: %s\n", ((Word*)list->list[x])->Line);
372+
373+    list_free(list);
374+    return 0;
375+}