Christian Fraß commited on 2021-03-03 00:27:18
Zeige 29 geänderte Dateien mit 1468 Einfügungen und 0 Löschungen.
... | ... |
@@ -0,0 +1,258 @@ |
1 |
+// import {int} from './types'; |
|
2 |
+ |
|
3 |
+ |
|
4 |
+namespace helpers.database |
|
5 |
+{ |
|
6 |
+ |
|
7 |
+ /** |
|
8 |
+ */ |
|
9 |
+ type type_query = { |
|
10 |
+ sql_template : string; |
|
11 |
+ arguments : {[name : string] : any}; |
|
12 |
+ }; |
|
13 |
+ |
|
14 |
+ |
|
15 |
+ /** |
|
16 |
+ */ |
|
17 |
+ function resolve_path |
|
18 |
+ ( |
|
19 |
+ path_raw : string |
|
20 |
+ ) : string |
|
21 |
+ { |
|
22 |
+ return ("sql/" + path_raw.replace(new RegExp("\\.", "g"), "/") + ".sql"); |
|
23 |
+ } |
|
24 |
+ |
|
25 |
+ |
|
26 |
+ /** |
|
27 |
+ */ |
|
28 |
+ function fix_query |
|
29 |
+ ( |
|
30 |
+ query : type_query, |
|
31 |
+ ) : type_query |
|
32 |
+ { |
|
33 |
+ return { |
|
34 |
+ "sql_template": query.sql_template.replace |
|
35 |
+ ( |
|
36 |
+ new RegExp(":([0-9a-zA-Z_-]+)", "g"), |
|
37 |
+ "$$$1" |
|
38 |
+ ), |
|
39 |
+ "arguments": ( |
|
40 |
+ () => |
|
41 |
+ { |
|
42 |
+ let arguments_ : {[name : string] : any} = {}; |
|
43 |
+ Object.keys(query.arguments).forEach |
|
44 |
+ ( |
|
45 |
+ (name) => {arguments_["$" + name] = query.arguments[name];} |
|
46 |
+ ); |
|
47 |
+ return arguments_; |
|
48 |
+ } |
|
49 |
+ ) (), |
|
50 |
+ }; |
|
51 |
+ } |
|
52 |
+ |
|
53 |
+ |
|
54 |
+ /** |
|
55 |
+ */ |
|
56 |
+ function query_do_free_ |
|
57 |
+ ( |
|
58 |
+ query : type_query |
|
59 |
+ ) : Promise<void> |
|
60 |
+ { |
|
61 |
+ const nm_sqlite3 = require("sqlite3"); |
|
62 |
+ const query_fixed : type_query = fix_query(query); |
|
63 |
+ // console.info("---\n" + query_fixed.sql_template + "\n" + JSON.stringify(query_fixed.arguments) + "\n---\n"); |
|
64 |
+ return ( |
|
65 |
+ new Promise<void> |
|
66 |
+ ( |
|
67 |
+ (resolve, reject) => |
|
68 |
+ { |
|
69 |
+ const database/* : nm_sqlite3.Database*/ = new nm_sqlite3.Database("concepts.sqlite"); |
|
70 |
+ database.run |
|
71 |
+ ( |
|
72 |
+ query_fixed.sql_template, |
|
73 |
+ query_fixed.arguments, |
|
74 |
+ function (error) |
|
75 |
+ { |
|
76 |
+ if (error) |
|
77 |
+ { |
|
78 |
+ reject(error); |
|
79 |
+ } |
|
80 |
+ else |
|
81 |
+ { |
|
82 |
+ resolve(undefined); |
|
83 |
+ } |
|
84 |
+ } |
|
85 |
+ ); |
|
86 |
+ database.close(); |
|
87 |
+ } |
|
88 |
+ ) |
|
89 |
+ ); |
|
90 |
+ } |
|
91 |
+ |
|
92 |
+ |
|
93 |
+ /** |
|
94 |
+ */ |
|
95 |
+ function query_get_free_ |
|
96 |
+ ( |
|
97 |
+ query : type_query |
|
98 |
+ ) : Promise<Array<type_row>> |
|
99 |
+ { |
|
100 |
+ const nm_sqlite3 = require("sqlite3"); |
|
101 |
+ const query_fixed : type_query = fix_query(query); |
|
102 |
+ // console.info("---\n" + query_fixed.sql_template + "\n" + JSON.stringify(query_fixed.arguments) + "\n---\n"); |
|
103 |
+ return ( |
|
104 |
+ new Promise<Array<type_row>> |
|
105 |
+ ( |
|
106 |
+ (resolve, reject) => |
|
107 |
+ { |
|
108 |
+ const database/* : nm_sqlite3.Database*/ = new nm_sqlite3.Database("concepts.sqlite"); |
|
109 |
+ database.all |
|
110 |
+ ( |
|
111 |
+ query_fixed.sql_template, |
|
112 |
+ query_fixed.arguments, |
|
113 |
+ function (error, rows) |
|
114 |
+ { |
|
115 |
+ // console.info({error,rows}); |
|
116 |
+ if (error) |
|
117 |
+ { |
|
118 |
+ reject(error); |
|
119 |
+ } |
|
120 |
+ else |
|
121 |
+ { |
|
122 |
+ resolve(rows); |
|
123 |
+ } |
|
124 |
+ } |
|
125 |
+ ); |
|
126 |
+ database.close(); |
|
127 |
+ } |
|
128 |
+ ) |
|
129 |
+ ); |
|
130 |
+ } |
|
131 |
+ |
|
132 |
+ |
|
133 |
+ /** |
|
134 |
+ */ |
|
135 |
+ function query_put_free_ |
|
136 |
+ ( |
|
137 |
+ query : type_query |
|
138 |
+ ) : Promise<int> |
|
139 |
+ { |
|
140 |
+ const nm_sqlite3 = require("sqlite3"); |
|
141 |
+ const query_fixed : type_query = fix_query(query); |
|
142 |
+ // console.info("---\n" + query_fixed.sql_template + "\n" + JSON.stringify(query_fixed.arguments) + "\n---\n"); |
|
143 |
+ return ( |
|
144 |
+ new Promise<int> |
|
145 |
+ ( |
|
146 |
+ (resolve, reject) => |
|
147 |
+ { |
|
148 |
+ const database/* : nm_sqlite3.Database*/ = new nm_sqlite3.Database("concepts.sqlite"); |
|
149 |
+ database.run |
|
150 |
+ ( |
|
151 |
+ query_fixed.sql_template, |
|
152 |
+ query_fixed.arguments, |
|
153 |
+ function (error) |
|
154 |
+ { |
|
155 |
+ if (error) |
|
156 |
+ { |
|
157 |
+ reject(error); |
|
158 |
+ } |
|
159 |
+ else |
|
160 |
+ { |
|
161 |
+ resolve(this.lastID); |
|
162 |
+ } |
|
163 |
+ } |
|
164 |
+ ); |
|
165 |
+ database.close(); |
|
166 |
+ } |
|
167 |
+ ) |
|
168 |
+ ); |
|
169 |
+ } |
|
170 |
+ |
|
171 |
+ |
|
172 |
+ /** |
|
173 |
+ */ |
|
174 |
+ export function query_do_free |
|
175 |
+ ( |
|
176 |
+ sql_template : string, |
|
177 |
+ arguments_ : {[name : string] : any} = {} |
|
178 |
+ ) : Promise<void> |
|
179 |
+ { |
|
180 |
+ return query_do_free_({"sql_template": sql_template, "arguments": arguments_}); |
|
181 |
+ } |
|
182 |
+ |
|
183 |
+ |
|
184 |
+ /** |
|
185 |
+ */ |
|
186 |
+ export function query_get_free |
|
187 |
+ ( |
|
188 |
+ sql_template : string, |
|
189 |
+ arguments_ : {[name : string] : any} = {} |
|
190 |
+ ) : Promise<Array<type_row>> |
|
191 |
+ { |
|
192 |
+ return query_get_free_({"sql_template": sql_template, "arguments": arguments_}); |
|
193 |
+ } |
|
194 |
+ |
|
195 |
+ |
|
196 |
+ /** |
|
197 |
+ */ |
|
198 |
+ export function query_put_free |
|
199 |
+ ( |
|
200 |
+ sql_template : string, |
|
201 |
+ arguments_ : {[name : string] : any} = {} |
|
202 |
+ ) : Promise<int> |
|
203 |
+ { |
|
204 |
+ return query_put_free_({"sql_template": sql_template, "arguments": arguments_}); |
|
205 |
+ } |
|
206 |
+ |
|
207 |
+ |
|
208 |
+ /** |
|
209 |
+ */ |
|
210 |
+ export function query_do_named |
|
211 |
+ ( |
|
212 |
+ name : string, |
|
213 |
+ arguments_ : {[name : string] : any} = {} |
|
214 |
+ ) : Promise<void> |
|
215 |
+ { |
|
216 |
+ return query_do_free |
|
217 |
+ ( |
|
218 |
+ helpers.file.read(resolve_path(name)), |
|
219 |
+ arguments_ |
|
220 |
+ ); |
|
221 |
+ } |
|
222 |
+ |
|
223 |
+ |
|
224 |
+ /** |
|
225 |
+ */ |
|
226 |
+ export function query_get_named |
|
227 |
+ ( |
|
228 |
+ name : string, |
|
229 |
+ arguments_ : {[name : string] : any} = {} |
|
230 |
+ ) : Promise<Array<type_row>> |
|
231 |
+ { |
|
232 |
+ return query_get_free |
|
233 |
+ ( |
|
234 |
+ helpers.file.read(resolve_path(name)), |
|
235 |
+ arguments_ |
|
236 |
+ ); |
|
237 |
+ } |
|
238 |
+ |
|
239 |
+ |
|
240 |
+ /** |
|
241 |
+ */ |
|
242 |
+ export function query_put_named |
|
243 |
+ ( |
|
244 |
+ name : string, |
|
245 |
+ arguments_ : {[name : string] : any} = {} |
|
246 |
+ ) : Promise<int> |
|
247 |
+ { |
|
248 |
+ return query_put_free |
|
249 |
+ ( |
|
250 |
+ helpers.file.read(resolve_path(name)), |
|
251 |
+ arguments_ |
|
252 |
+ ); |
|
253 |
+ } |
|
254 |
+ |
|
255 |
+} |
|
256 |
+ |
|
257 |
+ |
|
258 |
+ |
... | ... |
@@ -0,0 +1,18 @@ |
1 |
+namespace helpers.file |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ /** |
|
5 |
+ */ |
|
6 |
+ export function read |
|
7 |
+ ( |
|
8 |
+ path : string |
|
9 |
+ ) : string |
|
10 |
+ { |
|
11 |
+ const nm_fs = require("fs"); |
|
12 |
+ const buffer : Buffer = nm_fs.readFileSync(path); |
|
13 |
+ const content : string = buffer.toString(); |
|
14 |
+ return content; |
|
15 |
+ } |
|
16 |
+ |
|
17 |
+} |
|
18 |
+ |
... | ... |
@@ -0,0 +1,33 @@ |
1 |
+namespace helpers.misc |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ /** |
|
5 |
+ */ |
|
6 |
+ export function stdin |
|
7 |
+ ( |
|
8 |
+ ) : Promise<string> |
|
9 |
+ { |
|
10 |
+ return ( |
|
11 |
+ new Promise<string> |
|
12 |
+ ( |
|
13 |
+ (resolve, reject) => |
|
14 |
+ { |
|
15 |
+ const readline = require("readline"); |
|
16 |
+ const reader = readline.createInterface |
|
17 |
+ ( |
|
18 |
+ { |
|
19 |
+ "input": process.stdin, |
|
20 |
+ "output": process.stdout, |
|
21 |
+ "terminal": false |
|
22 |
+ } |
|
23 |
+ ); |
|
24 |
+ let lines : Array<string> = []; |
|
25 |
+ reader.on("line", (line) => lines.push(line)); |
|
26 |
+ reader.on("close", () => resolve(lines.join("\n"))); |
|
27 |
+ } |
|
28 |
+ ) |
|
29 |
+ ); |
|
30 |
+ } |
|
31 |
+ |
|
32 |
+} |
|
33 |
+ |
... | ... |
@@ -0,0 +1,24 @@ |
1 |
+namespace helpers |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ /** |
|
5 |
+ */ |
|
6 |
+ export type repository<type_key, type_value> = |
|
7 |
+ ( |
|
8 |
+ helpers.module |
|
9 |
+ & |
|
10 |
+ helpers.storage<type_key, type_value> |
|
11 |
+ ); |
|
12 |
+ |
|
13 |
+ |
|
14 |
+ /** |
|
15 |
+ */ |
|
16 |
+ export type repository_sqltable = |
|
17 |
+ ( |
|
18 |
+ helpers.module |
|
19 |
+ & |
|
20 |
+ helpers.storage_sqltable |
|
21 |
+ ); |
|
22 |
+ |
|
23 |
+} |
|
24 |
+ |
... | ... |
@@ -0,0 +1,27 @@ |
1 |
+namespace helpers |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ /** |
|
5 |
+ */ |
|
6 |
+ export type storage<type_key, type_value> = |
|
7 |
+ { |
|
8 |
+ create : (value : type_value)=>Promise<type_key>; |
|
9 |
+ update : (key : type_key, value : type_value)=>Promise<void>; |
|
10 |
+ delete : (key : type_key)=>Promise<void>; |
|
11 |
+ read : (key : type_key)=>Promise<type_value>; |
|
12 |
+ }; |
|
13 |
+ |
|
14 |
+ |
|
15 |
+ /** |
|
16 |
+ */ |
|
17 |
+ export type storage_sqltable = ( |
|
18 |
+ storage<int, type_row> |
|
19 |
+ & |
|
20 |
+ { |
|
21 |
+ purge : (column : string, value : any)=>Promise<void>; |
|
22 |
+ take : (column : string, value : any)=>Promise<Array<type_row>>; |
|
23 |
+ } |
|
24 |
+ ); |
|
25 |
+ |
|
26 |
+} |
|
27 |
+ |
... | ... |
@@ -0,0 +1,24 @@ |
1 |
+namespace helpers.string |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ /** |
|
5 |
+ */ |
|
6 |
+ export function coin |
|
7 |
+ ( |
|
8 |
+ template : string, |
|
9 |
+ arguments_ : {[key : string] : string}, |
|
10 |
+ open : string = "{{", |
|
11 |
+ close : string = "}}" |
|
12 |
+ ) : string |
|
13 |
+ { |
|
14 |
+ let result : string = template; |
|
15 |
+ for (let [key, value] of Object.entries(arguments_)) |
|
16 |
+ { |
|
17 |
+ const pattern : string = (open + key + close); |
|
18 |
+ result = result.replace(new RegExp(pattern, "g"), value); |
|
19 |
+ } |
|
20 |
+ return result; |
|
21 |
+ } |
|
22 |
+ |
|
23 |
+} |
|
24 |
+ |
... | ... |
@@ -0,0 +1,95 @@ |
1 |
+#!/usr/bin/env node |
|
2 |
+ |
|
3 |
+/* |
|
4 |
+import {repositories.language} from './repository-language'; |
|
5 |
+import {repositories.type} from './repository-type'; |
|
6 |
+import {repositories.tag} from './repository-tag'; |
|
7 |
+import {repositories.concept} from './repository-concept'; |
|
8 |
+ */ |
|
9 |
+ |
|
10 |
+ |
|
11 |
+/** |
|
12 |
+ */ |
|
13 |
+async function main(args : Array<string>) : Promise<void> |
|
14 |
+{ |
|
15 |
+ const command : string = args.shift(); |
|
16 |
+ switch (command) |
|
17 |
+ { |
|
18 |
+ case "setup": |
|
19 |
+ { |
|
20 |
+ await repositories.language.setup() |
|
21 |
+ await repositories.type.setup() |
|
22 |
+ await repositories.tag.setup() |
|
23 |
+ await repositories.concept.setup() |
|
24 |
+ process.exit(0); |
|
25 |
+ break; |
|
26 |
+ } |
|
27 |
+ case "feed": |
|
28 |
+ { |
|
29 |
+ const content : string = await helpers.misc.stdin(); |
|
30 |
+ const data : any = JSON.parse(content); |
|
31 |
+ const concept_thing : any = data; |
|
32 |
+ const concept_id : int = await services.concept.suck(concept_thing); |
|
33 |
+ console.info(concept_id); |
|
34 |
+ process.exit(0); |
|
35 |
+ break; |
|
36 |
+ } |
|
37 |
+ case "translate": |
|
38 |
+ { |
|
39 |
+ const language_from : string = args.shift(); |
|
40 |
+ const language_to : string = args.shift(); |
|
41 |
+ const part : string = args.shift(); |
|
42 |
+ const result = await services.concept.get_translations |
|
43 |
+ ( |
|
44 |
+ language_from, |
|
45 |
+ language_to, |
|
46 |
+ part |
|
47 |
+ ); |
|
48 |
+ result.forEach |
|
49 |
+ ( |
|
50 |
+ (entry) => |
|
51 |
+ { |
|
52 |
+ console.info |
|
53 |
+ ( |
|
54 |
+ helpers.string.coin |
|
55 |
+ ( |
|
56 |
+ "[{{language_from}}] {{value_from}} ~ [{{language_to}}] {{value_to}}", |
|
57 |
+ { |
|
58 |
+ "language_from": language_from, |
|
59 |
+ "value_from": entry["value_from"], |
|
60 |
+ "language_to": language_to, |
|
61 |
+ "value_to": entry["value_to"], |
|
62 |
+ } |
|
63 |
+ ) |
|
64 |
+ ); |
|
65 |
+ } |
|
66 |
+ ); |
|
67 |
+ process.exit(0); |
|
68 |
+ break; |
|
69 |
+ } |
|
70 |
+ case "export": |
|
71 |
+ { |
|
72 |
+ const result : Array<any> = await services.concept.export_(); |
|
73 |
+ console.info(JSON.stringify(result, undefined, "\t")); |
|
74 |
+ process.exit(0); |
|
75 |
+ break; |
|
76 |
+ } |
|
77 |
+ case "show": |
|
78 |
+ { |
|
79 |
+ const concept_id = parseInt(args.shift()); |
|
80 |
+ const concept_entity : entities.concept = await services.concept.get(concept_id); |
|
81 |
+ console.info(JSON.stringify(concept_entity, undefined, "\t")); |
|
82 |
+ break; |
|
83 |
+ } |
|
84 |
+ default: |
|
85 |
+ { |
|
86 |
+ console.error("unhandled command: " + command); |
|
87 |
+ process.exit(1); |
|
88 |
+ break; |
|
89 |
+ } |
|
90 |
+ } |
|
91 |
+} |
|
92 |
+ |
|
93 |
+ |
|
94 |
+main(process.argv.slice(2)); |
|
95 |
+ |
... | ... |
@@ -0,0 +1,78 @@ |
1 |
+namespace repositories |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ export var concept_core : helpers.repository_sqltable = |
|
5 |
+ { |
|
6 |
+ "setup": function () |
|
7 |
+ { |
|
8 |
+ return helpers.database.query_do_named("concept.setup-core"); |
|
9 |
+ }, |
|
10 |
+ "teardown": function () |
|
11 |
+ { |
|
12 |
+ throw (new Error("not implemented")); |
|
13 |
+ }, |
|
14 |
+ "create": function (row) |
|
15 |
+ { |
|
16 |
+ return helpers.database.query_put_free |
|
17 |
+ ( |
|
18 |
+ "INSERT INTO concepts(type_id, description) VALUES (:type_id, :description);", |
|
19 |
+ { |
|
20 |
+ "type_id": row["type_id"], |
|
21 |
+ "description": row["description"], |
|
22 |
+ } |
|
23 |
+ ); |
|
24 |
+ }, |
|
25 |
+ "update": function (concept_id, row) |
|
26 |
+ { |
|
27 |
+ return helpers.database.query_do_free |
|
28 |
+ ( |
|
29 |
+ "UPDATE concepts SET type_id = :type_id, description = :description WHERE (id = :id)", |
|
30 |
+ { |
|
31 |
+ "id": concept_id, |
|
32 |
+ "type_id": row["type_id"], |
|
33 |
+ "description": row["description"], |
|
34 |
+ } |
|
35 |
+ ); |
|
36 |
+ }, |
|
37 |
+ "delete": function (concept_id) |
|
38 |
+ { |
|
39 |
+ return helpers.database.query_do_free |
|
40 |
+ ( |
|
41 |
+ "DELETE FROM concepts WHERE (id = :id)", |
|
42 |
+ { |
|
43 |
+ "id": concept_id, |
|
44 |
+ } |
|
45 |
+ ); |
|
46 |
+ }, |
|
47 |
+ "read": function (concept_id) |
|
48 |
+ { |
|
49 |
+ return ( |
|
50 |
+ helpers.database.query_get_free |
|
51 |
+ ( |
|
52 |
+ "SELECT type_id,description FROM concepts WHERE (id = :id)", |
|
53 |
+ { |
|
54 |
+ "id": concept_id, |
|
55 |
+ } |
|
56 |
+ ) |
|
57 |
+ .then |
|
58 |
+ ( |
|
59 |
+ (rows) => ( |
|
60 |
+ (rows.length === 1) |
|
61 |
+ ? Promise.resolve<type_row>(rows[0]) |
|
62 |
+ : Promise.reject<type_row>(new Error("not found")) |
|
63 |
+ ) |
|
64 |
+ ) |
|
65 |
+ ); |
|
66 |
+ }, |
|
67 |
+ "purge": async function (column, value) |
|
68 |
+ { |
|
69 |
+ throw (new Error("not implemented")); |
|
70 |
+ }, |
|
71 |
+ "take": async function (column, value) |
|
72 |
+ { |
|
73 |
+ throw (new Error("not implemented")); |
|
74 |
+ }, |
|
75 |
+ }; |
|
76 |
+ |
|
77 |
+} |
|
78 |
+ |
... | ... |
@@ -0,0 +1,92 @@ |
1 |
+namespace repositories |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ /** |
|
5 |
+ */ |
|
6 |
+ export var concept_tags : helpers.repository_sqltable = |
|
7 |
+ { |
|
8 |
+ "setup": function () |
|
9 |
+ { |
|
10 |
+ return helpers.database.query_do_named("concept.setup-tags"); |
|
11 |
+ }, |
|
12 |
+ "teardown": function () |
|
13 |
+ { |
|
14 |
+ throw (new Error("not implemented")); |
|
15 |
+ }, |
|
16 |
+ "create": function (row) |
|
17 |
+ { |
|
18 |
+ return helpers.database.query_put_free |
|
19 |
+ ( |
|
20 |
+ "INSERT INTO concept_tags(concept_id, tag_id) VALUES (:concept_id, :tag_id);", |
|
21 |
+ { |
|
22 |
+ "concept_id": row["concept_id"], |
|
23 |
+ "tag_id": row["tag_id"], |
|
24 |
+ } |
|
25 |
+ ); |
|
26 |
+ }, |
|
27 |
+ "update": function (concept_tag_id, row) |
|
28 |
+ { |
|
29 |
+ return helpers.database.query_do_free |
|
30 |
+ ( |
|
31 |
+ "UPDATE concept_tags SET concept_id = :concept_id, tag_id = :tag_id WHERE (id = :id)", |
|
32 |
+ { |
|
33 |
+ "id": concept_tag_id, |
|
34 |
+ "concept_id": row["concept_id"], |
|
35 |
+ "tag_id": row["tag_id"], |
|
36 |
+ } |
|
37 |
+ ); |
|
38 |
+ }, |
|
39 |
+ "delete": function (concept_tag_id) |
|
40 |
+ { |
|
41 |
+ return helpers.database.query_do_free |
|
42 |
+ ( |
|
43 |
+ "DELETE FROM concept_tags WHERE (id = :id)", |
|
44 |
+ { |
|
45 |
+ "id": concept_tag_id, |
|
46 |
+ } |
|
47 |
+ ); |
|
48 |
+ }, |
|
49 |
+ "read": async function (concept_tag_id) |
|
50 |
+ { |
|
51 |
+ return ( |
|
52 |
+ helpers.database.query_get_free |
|
53 |
+ ( |
|
54 |
+ "SELECT concept_id,tag_id FROM concept_tags WHERE (id = :id)", |
|
55 |
+ { |
|
56 |
+ "id": concept_tag_id, |
|
57 |
+ } |
|
58 |
+ ) |
|
59 |
+ .then |
|
60 |
+ ( |
|
61 |
+ (rows) => ( |
|
62 |
+ (rows.length === 1) |
|
63 |
+ ? Promise.resolve<type_row>(rows[0]) |
|
64 |
+ : Promise.reject<type_row>(new Error("not found")) |
|
65 |
+ ) |
|
66 |
+ ) |
|
67 |
+ ); |
|
68 |
+ }, |
|
69 |
+ "purge": async function (column, value) |
|
70 |
+ { |
|
71 |
+ return helpers.database.query_do_free |
|
72 |
+ ( |
|
73 |
+ "DELETE FROM concept_tags WHERE (" + column + " = :value)", |
|
74 |
+ { |
|
75 |
+ "value": value, |
|
76 |
+ } |
|
77 |
+ ); |
|
78 |
+ }, |
|
79 |
+ "take": async function (column, value) |
|
80 |
+ { |
|
81 |
+ return await helpers.database.query_get_free |
|
82 |
+ ( |
|
83 |
+ "SELECT concept_id,tag_id FROM concept_tags WHERE (" + column + " = :value)", |
|
84 |
+ { |
|
85 |
+ "value": value, |
|
86 |
+ } |
|
87 |
+ ); |
|
88 |
+ }, |
|
89 |
+ }; |
|
90 |
+ |
|
91 |
+} |
|
92 |
+ |
... | ... |
@@ -0,0 +1,94 @@ |
1 |
+namespace repositories |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ /** |
|
5 |
+ */ |
|
6 |
+ export var concept_translations : helpers.repository_sqltable = |
|
7 |
+ { |
|
8 |
+ "setup": function () |
|
9 |
+ { |
|
10 |
+ return helpers.database.query_do_named("concept.setup-translations"); |
|
11 |
+ }, |
|
12 |
+ "teardown": function () |
|
13 |
+ { |
|
14 |
+ throw (new Error("not implemented")); |
|
15 |
+ }, |
|
16 |
+ "create": function (row) |
|
17 |
+ { |
|
18 |
+ return helpers.database.query_put_free |
|
19 |
+ ( |
|
20 |
+ "INSERT INTO concept_translations(concept_id, language_id, value) VALUES (:concept_id, :language_id, :value);", |
|
21 |
+ { |
|
22 |
+ "concept_id": row["concept_id"], |
|
23 |
+ "language_id": row["language_id"], |
|
24 |
+ "value": row["value"], |
|
25 |
+ } |
|
26 |
+ ); |
|
27 |
+ }, |
|
28 |
+ "update": function (concept_translation_id, row) |
|
29 |
+ { |
|
30 |
+ return helpers.database.query_do_free |
|
31 |
+ ( |
|
32 |
+ "UPDATE concept_translations SET concept_id = :concept_id, language_id = :language_id, value = :value WHERE (id = :id)", |
|
33 |
+ { |
|
34 |
+ "id": concept_translation_id, |
|
35 |
+ "concept_id": row["concept_id"], |
|
36 |
+ "language_id": row["language_id"], |
|
37 |
+ "value": row["value"], |
|
38 |
+ } |
|
39 |
+ ); |
|
40 |
+ }, |
|
41 |
+ "delete": function (concept_translation_id) |
|
42 |
+ { |
|
43 |
+ return helpers.database.query_do_free |
|
44 |
+ ( |
|
45 |
+ "DELETE FROM concept_translations WHERE (id = :id)", |
|
46 |
+ { |
|
47 |
+ "id": concept_translation_id, |
|
48 |
+ } |
|
49 |
+ ); |
|
50 |
+ }, |
|
51 |
+ "read": async function (concept_translation_id) |
|
52 |
+ { |
|
53 |
+ return ( |
|
54 |
+ helpers.database.query_get_free |
|
55 |
+ ( |
|
56 |
+ "SELECT concept_id,language_id,value FROM concept_translations WHERE (id = :id)", |
|
57 |
+ { |
|
58 |
+ "id": concept_translation_id, |
|
59 |
+ } |
|
60 |
+ ) |
|
61 |
+ .then |
|
62 |
+ ( |
|
63 |
+ (rows) => ( |
|
64 |
+ (rows.length === 1) |
|
65 |
+ ? Promise.resolve<type_row>(rows[0]) |
|
66 |
+ : Promise.reject<type_row>(new Error("not found")) |
|
67 |
+ ) |
|
68 |
+ ) |
|
69 |
+ ); |
|
70 |
+ }, |
|
71 |
+ "purge": async function (column, value) |
|
72 |
+ { |
|
73 |
+ return helpers.database.query_do_free |
|
74 |
+ ( |
|
75 |
+ "DELETE FROM concept_translations WHERE (" + column + " = :value)", |
|
76 |
+ { |
|
77 |
+ "value": value, |
|
78 |
+ } |
|
79 |
+ ); |
|
80 |
+ }, |
|
81 |
+ "take": async function (column, value) |
|
82 |
+ { |
|
83 |
+ return await helpers.database.query_get_free |
|
84 |
+ ( |
|
85 |
+ "SELECT concept_id,language_id,value FROM concept_translations WHERE (" + column + " = :value)", |
|
86 |
+ { |
|
87 |
+ "value": value, |
|
88 |
+ } |
|
89 |
+ ); |
|
90 |
+ }, |
|
91 |
+ }; |
|
92 |
+ |
|
93 |
+} |
|
94 |
+ |
... | ... |
@@ -0,0 +1,90 @@ |
1 |
+namespace repositories |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ /** |
|
5 |
+ */ |
|
6 |
+ export var concept : ( |
|
7 |
+ helpers.repository<int, entities.concept> |
|
8 |
+ & |
|
9 |
+ { |
|
10 |
+ get_translations : (language_from : string, language_to : string, part : string)=>Promise<Array<type_row>>; |
|
11 |
+ export : ()=>Promise<Array<type_row>>; |
|
12 |
+ } |
|
13 |
+ ) = |
|
14 |
+ { |
|
15 |
+ "setup": async function () |
|
16 |
+ { |
|
17 |
+ await repositories.concept_core.setup(); |
|
18 |
+ await repositories.concept_tags.setup(); |
|
19 |
+ await repositories.concept_translations.setup(); |
|
20 |
+ return Promise.resolve<void>(undefined); |
|
21 |
+ }, |
|
22 |
+ "teardown": async function () |
|
23 |
+ { |
|
24 |
+ await repositories.concept_translations.teardown(); |
|
25 |
+ await repositories.concept_tags.teardown(); |
|
26 |
+ await repositories.concept_core.teardown(); |
|
27 |
+ return Promise.resolve<void>(undefined); |
|
28 |
+ }, |
|
29 |
+ "create": async function (concept_entity) |
|
30 |
+ { |
|
31 |
+ const row_core : type_row = {"type_id": concept_entity.type_id, "description": concept_entity.description}; |
|
32 |
+ const concept_id : int = await repositories.concept_core.create(row_core); |
|
33 |
+ for await (let tag_id of concept_entity.tags) |
|
34 |
+ { |
|
35 |
+ const row_tag : type_row = {"concept_id": concept_id, "tag_id": tag_id}; |
|
36 |
+ const concept_tag_id : int = await repositories.concept_tags.create(row_tag); |
|
37 |
+ } |
|
38 |
+ for await (let {"language_id": language_id, "value": value} of concept_entity.translations) |
|
39 |
+ { |
|
40 |
+ const row_translations : type_row = {"concept_id": concept_id, "language_id": language_id, "value": value}; |
|
41 |
+ const concept_translations_id : int = await repositories.concept_translations.create(row_translations); |
|
42 |
+ } |
|
43 |
+ return Promise.resolve<int>(concept_id); |
|
44 |
+ }, |
|
45 |
+ "update": function (concept_id, concept_entity) |
|
46 |
+ { |
|
47 |
+ throw (new Error("not implemented")); |
|
48 |
+ }, |
|
49 |
+ "delete": async function (concept_id) |
|
50 |
+ { |
|
51 |
+ await repositories.concept_translations.purge("concept_id", concept_id); |
|
52 |
+ await repositories.concept_tags.purge("concept_id", concept_id); |
|
53 |
+ await repositories.concept_core.delete(concept_id); |
|
54 |
+ return Promise.resolve<void>(undefined); |
|
55 |
+ }, |
|
56 |
+ "read": async function (concept_id) |
|
57 |
+ { |
|
58 |
+ const row_core : type_row = await repositories.concept_core.read(concept_id);; |
|
59 |
+ const rows_tags : Array<type_row> = await repositories.concept_tags.take("concept_id", concept_id); |
|
60 |
+ const rows_translations : Array<type_row> = await repositories.concept_translations.take("concept_id", concept_id); |
|
61 |
+ const concept_entity : entities.concept = |
|
62 |
+ { |
|
63 |
+ "type_id": row_core["type_id"], |
|
64 |
+ "description": row_core["description"], |
|
65 |
+ "tags": rows_tags.map(row_tag => row_tag["tag_id"]), |
|
66 |
+ "translations": rows_translations.map(row_translation => ({"language_id": row_translation["language_id"], "value": row_translation["value"]})), |
|
67 |
+ }; |
|
68 |
+ return Promise.resolve<entities.concept>(concept_entity); |
|
69 |
+ }, |
|
70 |
+ "get_translations": function (language_from : string, language_to : string, part : string) : Promise<Array<type_row>> |
|
71 |
+ { |
|
72 |
+ return helpers.database.query_get_named |
|
73 |
+ ( |
|
74 |
+ "concept.get_translations", |
|
75 |
+ { |
|
76 |
+ "language_value_from": language_from, |
|
77 |
+ "language_value_to": language_to, |
|
78 |
+ "part": part.replace(new RegExp("-", "g"), "%"), |
|
79 |
+ } |
|
80 |
+ ); |
|
81 |
+ }, |
|
82 |
+ "export": function () : Promise<Array<type_row>> |
|
83 |
+ { |
|
84 |
+ return helpers.database.query_get_named("concept.export"); |
|
85 |
+ }, |
|
86 |
+ }; |
|
87 |
+ |
|
88 |
+} |
|
89 |
+ |
|
90 |
+ |
... | ... |
@@ -0,0 +1,97 @@ |
1 |
+namespace repositories |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ export var language : helpers.repository_sqltable & {identify : (value : string)=>Promise<int>;} = |
|
5 |
+ { |
|
6 |
+ "setup": async function () |
|
7 |
+ { |
|
8 |
+ await helpers.database.query_put_named("language.setup"); |
|
9 |
+ return Promise.resolve<void>(undefined); |
|
10 |
+ }, |
|
11 |
+ "teardown": function () |
|
12 |
+ { |
|
13 |
+ return Promise.reject(new Error("not implemented")); |
|
14 |
+ }, |
|
15 |
+ "create": function (row) |
|
16 |
+ { |
|
17 |
+ return helpers.database.query_put_free |
|
18 |
+ ( |
|
19 |
+ "INSERT INTO languages(value) VALUES (:value);", |
|
20 |
+ { |
|
21 |
+ "value": row["value"], |
|
22 |
+ } |
|
23 |
+ ); |
|
24 |
+ }, |
|
25 |
+ "update": function (language_id, row) |
|
26 |
+ { |
|
27 |
+ return helpers.database.query_do_free |
|
28 |
+ ( |
|
29 |
+ "UPDATE languages SET value = :vaule WHERE (id = :id);", |
|
30 |
+ { |
|
31 |
+ "id": language_id, |
|
32 |
+ "value": row["value"], |
|
33 |
+ } |
|
34 |
+ ); |
|
35 |
+ }, |
|
36 |
+ "delete": function (language_id) |
|
37 |
+ { |
|
38 |
+ return helpers.database.query_do_free |
|
39 |
+ ( |
|
40 |
+ "DELETE FROM languages WHERE (id = :id);", |
|
41 |
+ { |
|
42 |
+ "id": language_id, |
|
43 |
+ } |
|
44 |
+ ); |
|
45 |
+ }, |
|
46 |
+ "read": function (language_id) |
|
47 |
+ { |
|
48 |
+ return ( |
|
49 |
+ helpers.database.query_get_free |
|
50 |
+ ( |
|
51 |
+ "SELECT value FROM languages WHERE (id = :id);", |
|
52 |
+ { |
|
53 |
+ "id": language_id, |
|
54 |
+ } |
|
55 |
+ ) |
|
56 |
+ .then |
|
57 |
+ ( |
|
58 |
+ (rows) => ( |
|
59 |
+ (rows.length === 1) |
|
60 |
+ ? Promise.resolve<type_row>(rows[0]) |
|
61 |
+ : Promise.reject<type_row>(new Error("not found")) |
|
62 |
+ ) |
|
63 |
+ ) |
|
64 |
+ ); |
|
65 |
+ }, |
|
66 |
+ "purge": function (column, value) |
|
67 |
+ { |
|
68 |
+ return Promise.reject(new Error("not implemented")); |
|
69 |
+ }, |
|
70 |
+ "take": function (column, value) |
|
71 |
+ { |
|
72 |
+ return Promise.reject(new Error("not implemented")); |
|
73 |
+ }, |
|
74 |
+ "identify": function (value : string) : Promise<int> |
|
75 |
+ { |
|
76 |
+ return ( |
|
77 |
+ helpers.database.query_get_free |
|
78 |
+ ( |
|
79 |
+ "SELECT id FROM languages WHERE (value = :value);", |
|
80 |
+ { |
|
81 |
+ "value": value, |
|
82 |
+ } |
|
83 |
+ ) |
|
84 |
+ .then |
|
85 |
+ ( |
|
86 |
+ (rows) => ( |
|
87 |
+ (rows.length === 1) |
|
88 |
+ ? Promise.resolve<int>(rows[0]["id"]) |
|
89 |
+ : Promise.reject<int>() |
|
90 |
+ ) |
|
91 |
+ ) |
|
92 |
+ ); |
|
93 |
+ }, |
|
94 |
+ }; |
|
95 |
+ |
|
96 |
+} |
|
97 |
+ |
... | ... |
@@ -0,0 +1,97 @@ |
1 |
+namespace repositories |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ export var tag : helpers.repository_sqltable & {identify : (value : string)=>Promise<int>;} = |
|
5 |
+ { |
|
6 |
+ "setup": async function () |
|
7 |
+ { |
|
8 |
+ await helpers.database.query_put_named("tag.setup"); |
|
9 |
+ return Promise.resolve<void>(undefined); |
|
10 |
+ }, |
|
11 |
+ "teardown": function () |
|
12 |
+ { |
|
13 |
+ return Promise.reject(new Error("not implemented")); |
|
14 |
+ }, |
|
15 |
+ "create": function (row) |
|
16 |
+ { |
|
17 |
+ return helpers.database.query_put_free |
|
18 |
+ ( |
|
19 |
+ "INSERT INTO tags(value) VALUES (:value);", |
|
20 |
+ { |
|
21 |
+ "value": row["value"], |
|
22 |
+ } |
|
23 |
+ ); |
|
24 |
+ }, |
|
25 |
+ "update": function (tag_id, row) |
|
26 |
+ { |
|
27 |
+ return helpers.database.query_do_free |
|
28 |
+ ( |
|
29 |
+ "UPDATE tags SET value = :vaule WHERE (id = :id);", |
|
30 |
+ { |
|
31 |
+ "id": tag_id, |
|
32 |
+ "value": row["value"], |
|
33 |
+ } |
|
34 |
+ ); |
|
35 |
+ }, |
|
36 |
+ "delete": function (tag_id) |
|
37 |
+ { |
|
38 |
+ return helpers.database.query_do_free |
|
39 |
+ ( |
|
40 |
+ "DELETE FROM tags WHERE (id = :id);", |
|
41 |
+ { |
|
42 |
+ "id": tag_id, |
|
43 |
+ } |
|
44 |
+ ); |
|
45 |
+ }, |
|
46 |
+ "read": function (tag_id) |
|
47 |
+ { |
|
48 |
+ return ( |
|
49 |
+ helpers.database.query_get_free |
|
50 |
+ ( |
|
51 |
+ "SELECT value FROM tags WHERE (id = :id);", |
|
52 |
+ { |
|
53 |
+ "id": tag_id, |
|
54 |
+ } |
|
55 |
+ ) |
|
56 |
+ .then |
|
57 |
+ ( |
|
58 |
+ (rows) => ( |
|
59 |
+ (rows.length === 1) |
|
60 |
+ ? Promise.resolve<type_row>(rows[0]) |
|
61 |
+ : Promise.reject<type_row>(new Error("not found")) |
|
62 |
+ ) |
|
63 |
+ ) |
|
64 |
+ ); |
|
65 |
+ }, |
|
66 |
+ "purge": function (column, value) |
|
67 |
+ { |
|
68 |
+ return Promise.reject(new Error("not implemented")); |
|
69 |
+ }, |
|
70 |
+ "take": function (column, value) |
|
71 |
+ { |
|
72 |
+ return Promise.reject(new Error("not implemented")); |
|
73 |
+ }, |
|
74 |
+ "identify": function (value : string) : Promise<int> |
|
75 |
+ { |
|
76 |
+ return ( |
|
77 |
+ helpers.database.query_get_free |
|
78 |
+ ( |
|
79 |
+ "SELECT id FROM tags WHERE (value = :value);", |
|
80 |
+ { |
|
81 |
+ "value": value, |
|
82 |
+ } |
|
83 |
+ ) |
|
84 |
+ .then |
|
85 |
+ ( |
|
86 |
+ (rows) => ( |
|
87 |
+ (rows.length === 1) |
|
88 |
+ ? Promise.resolve<int>(rows[0]["id"]) |
|
89 |
+ : Promise.reject<int>() |
|
90 |
+ ) |
|
91 |
+ ) |
|
92 |
+ ); |
|
93 |
+ }, |
|
94 |
+ }; |
|
95 |
+ |
|
96 |
+} |
|
97 |
+ |
... | ... |
@@ -0,0 +1,97 @@ |
1 |
+namespace repositories |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ export var type : helpers.repository_sqltable & {identify : (value : string)=>Promise<int>;} = |
|
5 |
+ { |
|
6 |
+ "setup": async function () |
|
7 |
+ { |
|
8 |
+ await helpers.database.query_put_named("type.setup"); |
|
9 |
+ return Promise.resolve<void>(undefined); |
|
10 |
+ }, |
|
11 |
+ "teardown": function () |
|
12 |
+ { |
|
13 |
+ return Promise.reject(new Error("not implemented")); |
|
14 |
+ }, |
|
15 |
+ "create": function (row) |
|
16 |
+ { |
|
17 |
+ return helpers.database.query_put_free |
|
18 |
+ ( |
|
19 |
+ "INSERT INTO types(value) VALUES (:value);", |
|
20 |
+ { |
|
21 |
+ "value": row["value"], |
|
22 |
+ } |
|
23 |
+ ); |
|
24 |
+ }, |
|
25 |
+ "update": function (type_id, row) |
|
26 |
+ { |
|
27 |
+ return helpers.database.query_do_free |
|
28 |
+ ( |
|
29 |
+ "UPDATE types SET value = :vaule WHERE (id = :id);", |
|
30 |
+ { |
|
31 |
+ "id": type_id, |
|
32 |
+ "value": row["value"], |
|
33 |
+ } |
|
34 |
+ ); |
|
35 |
+ }, |
|
36 |
+ "delete": function (type_id) |
|
37 |
+ { |
|
38 |
+ return helpers.database.query_do_free |
|
39 |
+ ( |
|
40 |
+ "DELETE FROM types WHERE (id = :id);", |
|
41 |
+ { |
|
42 |
+ "id": type_id, |
|
43 |
+ } |
|
44 |
+ ); |
|
45 |
+ }, |
|
46 |
+ "read": function (type_id) |
|
47 |
+ { |
|
48 |
+ return ( |
|
49 |
+ helpers.database.query_get_free |
|
50 |
+ ( |
|
51 |
+ "SELECT value FROM types WHERE (id = :id);", |
|
52 |
+ { |
|
53 |
+ "id": type_id, |
|
54 |
+ } |
|
55 |
+ ) |
|
56 |
+ .then |
|
57 |
+ ( |
|
58 |
+ (rows) => ( |
|
59 |
+ (rows.length === 1) |
|
60 |
+ ? Promise.resolve<type_row>(rows[0]) |
|
61 |
+ : Promise.reject<type_row>(new Error("not found")) |
|
62 |
+ ) |
|
63 |
+ ) |
|
64 |
+ ); |
|
65 |
+ }, |
|
66 |
+ "purge": function (column, value) |
|
67 |
+ { |
|
68 |
+ return Promise.reject(new Error("not implemented")); |
|
69 |
+ }, |
|
70 |
+ "take": function (column, value) |
|
71 |
+ { |
|
72 |
+ return Promise.reject(new Error("not implemented")); |
|
73 |
+ }, |
|
74 |
+ "identify": function (value : string) : Promise<int> |
|
75 |
+ { |
|
76 |
+ return ( |
|
77 |
+ helpers.database.query_get_free |
|
78 |
+ ( |
|
79 |
+ "SELECT id FROM types WHERE (value = :value);", |
|
80 |
+ { |
|
81 |
+ "value": value, |
|
82 |
+ } |
|
83 |
+ ) |
|
84 |
+ .then |
|
85 |
+ ( |
|
86 |
+ (rows) => ( |
|
87 |
+ (rows.length === 1) |
|
88 |
+ ? Promise.resolve<int>(rows[0]["id"]) |
|
89 |
+ : Promise.reject<int>() |
|
90 |
+ ) |
|
91 |
+ ) |
|
92 |
+ ); |
|
93 |
+ }, |
|
94 |
+ }; |
|
95 |
+ |
|
96 |
+} |
|
97 |
+ |
... | ... |
@@ -0,0 +1,134 @@ |
1 |
+namespace services.concept |
|
2 |
+{ |
|
3 |
+ |
|
4 |
+ /** |
|
5 |
+ */ |
|
6 |
+ export function get |
|
7 |
+ ( |
|
8 |
+ concept_id : int |
|
9 |
+ ) : Promise<entities.concept> |
|
10 |
+ { |
|
11 |
+ return repositories.concept.read(concept_id); |
|
12 |
+ } |
|
13 |
+ |
|
14 |
+ |
|
15 |
+ /** |
|
16 |
+ */ |
|
17 |
+ export async function suck |
|
18 |
+ ( |
|
19 |
+ concept_thing : any |
|
20 |
+ ) : Promise<int> |
|
21 |
+ { |
|
22 |
+ const type_id : int = await services.type.give(concept_thing["type"]); |
|
23 |
+ const concept_id : int = await repositories.concept_core.create |
|
24 |
+ ( |
|
25 |
+ { |
|
26 |
+ "type_id": type_id, |
|
27 |
+ "description": concept_thing["description"], |
|
28 |
+ } |
|
29 |
+ ); |
|
30 |
+ await concept_thing["tags"].map |
|
31 |
+ ( |
|
32 |
+ async (tag_value) => |
|
33 |
+ { |
|
34 |
+ const tag_id : int = await services.tag.give(tag_value); |
|
35 |
+ const concept_tag_id : int = await repositories.concept_tags.create |
|
36 |
+ ( |
|
37 |
+ { |
|
38 |
+ "concept_id": concept_id, |
|
39 |
+ "tag_id": tag_id, |
|
40 |
+ } |
|
41 |
+ ); |
|
42 |
+ return concept_tag_id; |
|
43 |
+ } |
|
44 |
+ ); |
|
45 |
+ await Object.keys(concept_thing["translations"]).map |
|
46 |
+ ( |
|
47 |
+ async (language_value) => |
|
48 |
+ { |
|
49 |
+ const language_id : int = await services.language.give(language_value); |
|
50 |
+ const concept_translation_ids = await concept_thing["translations"][language_value].map |
|
51 |
+ ( |
|
52 |
+ async (translation_value) => |
|
53 |
+ { |
|
54 |
+ const concept_translation_id : int = await repositories.concept_translations.create |
|
55 |
+ ( |
|
56 |
+ { |
|
57 |
+ "concept_id": concept_id, |
|
58 |
+ "language_id": language_id, |
|
59 |
+ "value": translation_value, |
|
60 |
+ } |
|
61 |
+ ); |
|
62 |
+ } |
|
63 |
+ ); |
|
64 |
+ } |
|
65 |
+ ); |
|
66 |
+ return concept_id; |
|
67 |
+ } |
|
68 |
+ |
|
69 |
+ |
|
70 |
+ /** |
|
71 |
+ */ |
|
72 |
+ export function get_translations |
|
73 |
+ ( |
|
74 |
+ language_from : string, |
|
75 |
+ language_to : string, |
|
76 |
+ part : string |
|
77 |
+ ) : Promise<Array<type_row>> |
|
78 |
+ { |
|
79 |
+ return repositories.concept.get_translations |
|
80 |
+ ( |
|
81 |
+ language_from, |
|
82 |
+ language_to, |
|
83 |
+ part |
|
84 |
+ ); |
|
85 |
+ } |
|
86 |
+ |
|
87 |
+ |
|
88 |
+ /** |
|
89 |
+ */ |
|
90 |
+ export async function export_ |
|
91 |
+ ( |
|
92 |
+ ) : Promise<Array<{id : int; type : string; description : string; tags : Array<string>; translations : {[language : string] : Array<string>}}>> |
|
93 |
+ { |
|
94 |
+ const parse_tags = function (tags_raw : string) : Array<string> |
|
95 |
+ { |
|
96 |
+ return ( |
|
97 |
+ (tags_raw === null) |
|
98 |
+ ? [] |
|
99 |
+ : tags_raw.split(",") |
|
100 |
+ ); |
|
101 |
+ }; |
|
102 |
+ const parse_translations = function (translations_raw : string) : {[language : string] : Array<string>} |
|
103 |
+ { |
|
104 |
+ let result : {[language : string] : Array<string>} = {}; |
|
105 |
+ const parts : Array<string> = translations_raw.split(",") |
|
106 |
+ parts.forEach |
|
107 |
+ ( |
|
108 |
+ (part) => |
|
109 |
+ { |
|
110 |
+ const [language, value] : Array<string> = part.split(":", 2); |
|
111 |
+ if (! result.hasOwnProperty(language)) result[language] = []; |
|
112 |
+ result[language].push(value); |
|
113 |
+ } |
|
114 |
+ ); |
|
115 |
+ return result; |
|
116 |
+ }; |
|
117 |
+ const rows : Array<type_row> = await repositories.concept.export(); |
|
118 |
+ return Promise.resolve<any>( |
|
119 |
+ rows.map |
|
120 |
+ ( |
|
121 |
+ (row) => ( |
|
122 |
+ { |
|
123 |
+ "id": row["id"], |
|
124 |
+ "type": row["type"], |
|
125 |
+ "description": row["description"], |
|
126 |
+ "tags": parse_tags(row["tags"]), |
|
127 |
+ "translations": parse_translations(row["translations"]), |
|
128 |
+ }) |
|
129 |
+ ) |
|
130 |
+ ) |
|
131 |
+ } |
|
132 |
+ |
|
133 |
+} |
|
134 |
+ |
... | ... |
@@ -0,0 +1,16 @@ |
1 |
+SELECT |
|
2 |
+ x1.id AS id, |
|
3 |
+ MIN(x2.value) AS type, |
|
4 |
+ GROUP_CONCAT(DISTINCT x4.value) AS tags, |
|
5 |
+ GROUP_CONCAT(x6.value || ':' || x5.value) AS translations |
|
6 |
+FROM |
|
7 |
+ concepts AS x1 |
|
8 |
+ LEFT OUTER JOIN types AS x2 ON (x1.type_id = x2.id) |
|
9 |
+ LEFT OUTER JOIN concept_tags AS x3 ON (x1.id = x3.concept_id) |
|
10 |
+ LEFT OUTER JOIN tags AS x4 ON (x3.tag_id = x4.id) |
|
11 |
+ LEFT OUTER JOIN concept_translations AS x5 ON (x1.id = x5.concept_id) |
|
12 |
+ LEFT OUTER JOIN languages AS x6 ON (x5.language_id = x6.id) |
|
13 |
+GROUP BY |
|
14 |
+ x1.id |
|
15 |
+; |
|
16 |
+ |
... | ... |
@@ -0,0 +1,16 @@ |
1 |
+SELECT |
|
2 |
+ x.concept_id AS concept_id, |
|
3 |
+ x.value AS value_from, |
|
4 |
+ y.value AS value_to |
|
5 |
+FROM |
|
6 |
+ concept_translations AS x INNER JOIN concept_translations AS y ON (x.concept_id = y.concept_id) |
|
7 |
+WHERE |
|
8 |
+ ( |
|
9 |
+ (x.language_id = (SELECT id FROM languages WHERE (value = :language_value_from))) |
|
10 |
+ AND |
|
11 |
+ (y.language_id = (SELECT id FROM languages WHERE (value = :language_value_to))) |
|
12 |
+ AND |
|
13 |
+ (x.value LIKE :part) |
|
14 |
+ ) |
|
15 |
+; |
|
16 |
+ |
... | ... |
@@ -0,0 +1,20 @@ |
1 |
+CREATE TABLE IF NOT EXISTS |
|
2 |
+ `concepts`( |
|
3 |
+ `id` |
|
4 |
+ INTEGER |
|
5 |
+ PRIMARY KEY |
|
6 |
+ AUTOINCREMENT |
|
7 |
+ , |
|
8 |
+ `type_id` |
|
9 |
+ INTEGER |
|
10 |
+ NOT NULL |
|
11 |
+ , |
|
12 |
+ `description` |
|
13 |
+ TEXT |
|
14 |
+ DEFAULT NULL |
|
15 |
+ , |
|
16 |
+ FOREIGN KEY |
|
17 |
+ (`type_id`) |
|
18 |
+ REFERENCES `types`(`id`) |
|
19 |
+ ) |
|
20 |
+; |
... | ... |
@@ -0,0 +1,24 @@ |
1 |
+CREATE TABLE IF NOT EXISTS |
|
2 |
+ `concept_tags`( |
|
3 |
+ `id` |
|
4 |
+ INTEGER |
|
5 |
+ PRIMARY KEY |
|
6 |
+ AUTOINCREMENT |
|
7 |
+ , |
|
8 |
+ `concept_id` |
|
9 |
+ INTEGER |
|
10 |
+ NOT NULL |
|
11 |
+ , |
|
12 |
+ `tag_id` |
|
13 |
+ INTEGER |
|
14 |
+ NOT NULL |
|
15 |
+ , |
|
16 |
+ FOREIGN KEY |
|
17 |
+ (`concept_id`) |
|
18 |
+ REFERENCES `concepts`(`id`) |
|
19 |
+ , |
|
20 |
+ FOREIGN KEY |
|
21 |
+ (`tag_id`) |
|
22 |
+ REFERENCES `tags`(`id`) |
|
23 |
+ ) |
|
24 |
+; |
... | ... |
@@ -0,0 +1,28 @@ |
1 |
+CREATE TABLE IF NOT EXISTS |
|
2 |
+ `concept_translations`( |
|
3 |
+ `id` |
|
4 |
+ INTEGER |
|
5 |
+ PRIMARY KEY |
|
6 |
+ AUTOINCREMENT |
|
7 |
+ , |
|
8 |
+ `concept_id` |
|
9 |
+ INTEGER |
|
10 |
+ NOT NULL |
|
11 |
+ , |
|
12 |
+ `language_id` |
|
13 |
+ INTEGER |
|
14 |
+ NOT NULL |
|
15 |
+ , |
|
16 |
+ `value` |
|
17 |
+ TEXT |
|
18 |
+ NOT NULL |
|
19 |
+ , |
|
20 |
+ FOREIGN KEY |
|
21 |
+ (`language_id`) |
|
22 |
+ REFERENCES `languages`(`id`) |
|
23 |
+ , |
|
24 |
+ FOREIGN KEY |
|
25 |
+ (`concept_id`) |
|
26 |
+ REFERENCES `concepts`(`id`) |
|
27 |
+ ) |
|
28 |
+; |