-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdatabase.ml
103 lines (95 loc) · 2.56 KB
/
database.ml
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
let dbh = ref None
let open_database () =
begin
dbh := Some (PGOCaml.connect ~host:!Config.db_host ~user:!Config.db_user
~password:!Config.db_password ~database:!Config.db_name ())
end;;
let close_database () =
begin
match !dbh with
| None -> ()
| Some h -> PGOCaml.close h
end;;
let create_tables () =
begin
match !dbh with
| None -> raise (Failure "database not opened")
| Some h ->
PGSQL(h) "CREATE TABLE words \
(id SERIAL PRIMARY KEY, \
word TEXT NOT NULL)";
PGSQL(h) "CREATE TABLE declensions \
(word_id INTEGER REFERENCES words(id) NOT NULL, \
case_nr INTEGER NOT NULL, \
number CHAR(1) NOT NULL, \
word TEXT NOT NULL)"
end;;
let find_word w =
begin
match !dbh with
| None -> raise (Failure "database not opened")
| Some h -> List.map Int32.to_int
(PGSQL(h) "SELECT id FROM words WHERE word = $w")
end;;
let add_word word sgl pll =
begin
match !dbh with
| None -> raise (Failure "database not opened")
| Some h ->
let ids = PGSQL(h) "INSERT INTO words (id, word) VALUES (DEFAULT, $word) \
RETURNING id" in
begin
match ids with
| [] -> raise (Failure "oopsie, empty list.")
| [id] -> List.iteri (fun i (c, w) ->
let c = Int32.of_int i in
PGSQL(h) "INSERT INTO declensions (word_id, case_nr, number, word) \
VALUES ($id, $c, 'S', $w)"
) sgl;
List.iteri (fun i (c, w) ->
let c = Int32.of_int i in
PGSQL(h) "INSERT INTO declensions (word_id, case_nr, number, word) \
VALUES ($id, $c, 'P', $w)"
) pll
| _ -> raise (Failure "oopsier, too many elements in list.")
end
end;;
let update_word i sgl pll =
begin
let id = Int32.of_int i in
match !dbh with
| None -> raise (Failure "database not opened")
| Some h ->
begin
List.iteri (fun i (c, w) ->
let c = Int32.of_int i in
PGSQL(h) "UPDATE declensions SET word = $w \
WHERE word_id = $id AND case_nr = $c AND number = 'S'"
) sgl;
List.iteri (fun i (c, w) ->
let c = Int32.of_int i in
PGSQL(h) "UPDATE declensions SET word = $w \
WHERE word_id = $id AND case_nr = $c AND number = 'P'"
) pll
end
end;;
let random_word () =
begin
match !dbh with
| None -> raise (Failure "database not opened")
| Some h ->
begin
List.hd (PGSQL(h) "SELECT id, word FROM words \
OFFSET floor(random() * (SELECT COUNT(*) FROM words)) LIMIT 1")
end
end;;
let find_answer case_nr number i =
begin
match !dbh with
| None -> raise (Failure "database not opened")
| Some h ->
begin
List.hd (PGSQL(h) "SELECT word FROM declensions \
WHERE case_nr = $case_nr AND number = $number AND word_id = $i")
end
end;;