aboutsummaryrefslogtreecommitdiff
path: root/lib/data.c
blob: afbbbb116e04e1880add4f47bad9704411f011ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "data.h"
#include "../lib/util.h"

const char *insert_into = "INSERT INTO words (LINE) VALUES($VVV);";
const char *select_words = "SELECT Id, Line FROM words WHERE line MATCH $VVV LIMIT $NNN;";
const char *create_table =  "CREATE VIRTUAL TABLE IF NOT EXISTS words USING fts4 (ID INTEGER PRIMARY KEY AUTOINCREMENT, LINE TEXT NOT NULL);";

Data* new_data(const char* con)
{
    Data* data = (Data*)malloc(sizeof(Data));

    int v = sqlite3_open(con, &(data->db));
    if (v != SQLITE_OK) {
        print_result_code(v);
        return NULL;
    }

    sqlite3_enable_load_extension(data->db, 1);
    v = sqlite3_load_extension(data->db, "ext/libsqlite3ext", "sqlite3_spellfix_init",0);
    if (v != SQLITE_OK) {
        print_result_code(v);
        return NULL;
    }

    return data;
}

void free_data(Data* data)
{
    sqlite3_close(data->db);
    free(data);
}

void insert(Data* data, char* line, int len)
{
    sqlite3_stmt *stmt;
    int r = sqlite3_prepare_v2(data->db, insert_into, -1, &stmt, NULL);

    if (r != SQLITE_OK) {
        printf("Error executing insert: ");
        print_result_code(r);
        printf("\n");
        return;
    }

    sqlite3_bind_text(stmt, 1, line, len, NULL);

    int c = sqlite3_step(stmt);
    if (c != SQLITE_DONE) {
        printf("Error executing insert: ");
        print_result_code(r);
        printf("\n");
    }

    sqlite3_finalize(stmt);
}

void bootstrap(Data* data)
{
    sqlite3_stmt *stmt;
    int r = sqlite3_prepare_v2(data->db, create_table, -1, &stmt, NULL);

    if (r != SQLITE_OK) {
        printf("Error preparing bootstrap: ");
        print_result_code(r);
        printf("\n");
        return;
    }

    int c = sqlite3_step(stmt);
    if (c != SQLITE_DONE) {
        printf("Error executing bootstrap: ");
        print_result_code(r);
        printf("\n");
    }

    sqlite3_finalize(stmt);
}

LIST* data_select(Data* data, char *sch, int len, int limit)
{
    sqlite3_stmt *stmt;
    int r = sqlite3_prepare_v2(data->db, select_words, -1, &stmt, NULL);

    if (r != SQLITE_OK) {
        printf("Error executing select: ");
        print_result_code(r);
        printf("\n");
        return NULL;
    }

    LIST *list = NULL;

    sqlite3_bind_text(stmt, 1, sch, len, NULL);
    sqlite3_bind_int(stmt, 2, limit);

    int m =  sqlite3_step(stmt);
    while(m == SQLITE_ROW) {
        Word *word = (Word*)malloc(sizeof(Word));

        int id = sqlite3_column_int(stmt, 0);
        const unsigned char *line = sqlite3_column_text(stmt, 1);
        unsigned char *line2 = malloc(sizeof(char*)+strlen((char*)line));
        memcpy(line2, line, strlen((char*)line));

        word->Id = id;
        word->Line = line2;
        list = list_add(list, word);

        m = sqlite3_step(stmt);
    }

    sqlite3_finalize(stmt);

    return list;
}

void print_result_code(int code)
{
    printf(sqlite3_errstr(code));
}