1diff --git a/CMakeLists.txt b/CMakeLists.txt
2index 2614aa6f52b569feba19c53168c92e37ffaa32d3..c34734d2daf984075b1bed87f236c2ac33e5ded2 100644
3--- a/CMakeLists.txt
4+++ b/CMakeLists.txt
5@@ -7,5 +7,5 @@ add_executable(dict ${src})
6
7 target_compile_options(dict PRIVATE -Wall -Wextra -Wpedantic -Werror)
8 target_include_directories(dict PUBLIC "${PROJECT_BINARY_DIR}")
9-target_link_libraries(dict sqlite3)
10+target_link_libraries(dict sqlite3 ncursesw)
11
12diff --git a/data.c b/data.c
13index 5a9a103daf2dd02f9b494385a08cbbe4a8e316ea..777dcdf58b260a0ecf8c50fb56132b34d0a6c35d 100644
14--- a/data.c
15+++ b/data.c
16@@ -25,7 +25,7 @@ sqlite3_close(data->db);
17 free(data);
18 }
19
20-void insert(Data* data, char* line) {
21+void insert(Data* data, char* line, int len) {
22 sqlite3_stmt *stmt;
23 int r = sqlite3_prepare_v2(data->db, insert_into, -1, &stmt, NULL);
24
25@@ -37,7 +37,7 @@ return;
26 }
27
28 // binds the paremets to the statement, in this case the line;
29- sqlite3_bind_text(stmt, 1, line, -1, NULL);
30+ sqlite3_bind_text(stmt, 1, line, len, NULL);
31
32 int c = sqlite3_step(stmt);
33 if (c != SQLITE_DONE) {
34@@ -45,6 +45,8 @@ printf("Error executing insert: ");
35 print_result_code(r);
36 printf("\n");
37 }
38+
39+ sqlite3_finalize(stmt);
40 }
41
42 void bootstrap(Data* data) {
43@@ -64,6 +66,8 @@ printf("Error executing bootstrap: ");
44 print_result_code(r);
45 printf("\n");
46 }
47+
48+ sqlite3_finalize(stmt);
49 }
50
51 LIST* select(Data* data) {
52diff --git a/data.h b/data.h
53index db8aedc2a5e9ea62ef2f577718b9dbf8418c9a4c..393f8308c1ccf9032745260ee3ef84b9d5af3462 100644
54--- a/data.h
55+++ b/data.h
56@@ -34,7 +34,7 @@
57 /*
58 * insert line into database.
59 */
60-void insert(Data*, char*);
61+void insert(Data*, char*, int);
62
63 /*
64 * Select all words.
65diff --git a/main.c b/main.c
66index 720871ca2071734484ce7c6feb3b9ae706e2c4a1..dae1f2aa50de122aa0d00c8cfec74b3f939a5bfc 100644
67--- a/main.c
68+++ b/main.c
69@@ -1,20 +1,101 @@
70+#include <locale.h>
71 #include <stdio.h>
72 #include <sqlite3.h>
73-
74+#include <ncurses.h>
75 #include "data.h"
76
77+#define BUF_SIZE 100
78+
79+unsigned int count_lines(FILE* file);
80+int load_or_save_db(sqlite3 *pInMemory, const char *zFilename, int isSave);
81+
82 int main() {
83 Data *data = new_data(":memory:");
84
85 bootstrap(data);
86- for (int x = 0; x < 10000; x++)
87- insert(data, "LINE X");
88
89- LIST *list = select(data);
90+ setlocale(LC_ALL, "");
91+ initscr();
92
93- for (unsigned int x = 0; x < list->size; x++)
94- printf("This is a line: %s\n", ((Word*)list->list[x])->Line);
95+ int maxx=getmaxx(stdscr);
96
97- list_free(list);
98+ FILE *f = fopen("dict.txt", "r");
99+ unsigned int lines = count_lines(f);
100+ fseek(f, 0, SEEK_SET);
101+
102+ char * line = NULL;
103+ size_t len = 0;
104+ ssize_t read;
105+ int count = 0;
106+ while ((read = getline(&line, &len, f)) != -1) {
107+ if (line[0] == '#' || line[0] == '\n')
108+ continue;
109+
110+ insert(data, line, read-1);
111+ count ++;
112+ move(0,0);
113+ float total = ((float)count/(float)lines);
114+ printw("%03.0f%% ", total*100);
115+ for (int x = 0; x < ((maxx-4)*total); x++) {
116+ printw("█");
117+ }
118+ move(1,0);
119+ printw("%d/%d",count,lines);
120+ refresh();
121+ }
122+
123+ move(2,0);
124+ printw("Saving db...");
125+ refresh();
126+ load_or_save_db(data->db, "backup.db", 1);
127+
128+ clear();
129+ refresh();
130 return 0;
131 }
132+
133+int load_or_save_db(sqlite3 *pInMemory, const char *zFilename, int isSave){
134+ int rc; /* Function return code */
135+ sqlite3 *pFile; /* Database connection opened on zFilename */
136+ sqlite3_backup *pBackup; /* Backup object used to copy data */
137+ sqlite3 *pTo; /* Database to copy to (pFile or pInMemory) */
138+ sqlite3 *pFrom; /* Database to copy from (pFile or pInMemory) */
139+
140+ rc = sqlite3_open(zFilename, &pFile);
141+ if( rc==SQLITE_OK ){
142+ pFrom = (isSave ? pInMemory : pFile);
143+ pTo = (isSave ? pFile : pInMemory);
144+
145+ pBackup = sqlite3_backup_init(pTo, "main", pFrom, "main");
146+ if( pBackup ){
147+ (void)sqlite3_backup_step(pBackup, -1);
148+ (void)sqlite3_backup_finish(pBackup);
149+ }
150+ rc = sqlite3_errcode(pTo);
151+ }
152+
153+ (void)sqlite3_close(pFile);
154+ return rc;
155+}
156+
157+unsigned int count_lines(FILE* file)
158+{
159+ char buf[BUF_SIZE];
160+ unsigned int counter = 0;
161+ for(;;)
162+ {
163+ size_t res = fread(buf, 1, BUF_SIZE, file);
164+ if (ferror(file))
165+ return -1;
166+
167+ size_t i;
168+ for(i = 0; i < res; i++)
169+ if (buf[i] == '\n')
170+ counter++;
171+
172+ if (feof(file))
173+ break;
174+ }
175+
176+ return counter;
177+}