Christian Fraß commited on 2021-03-03 01:35:40
Zeige 5 geänderte Dateien mit 201 Einfügungen und 48 Löschungen.
| ... | ... |
@@ -8,6 +8,13 @@ import {repositories.concept} from './repository-concept';
|
| 8 | 8 |
*/ |
| 9 | 9 |
|
| 10 | 10 |
|
| 11 |
+function syntaxerror() : void |
|
| 12 |
+{
|
|
| 13 |
+ console.error("-- wrong syntax");
|
|
| 14 |
+ process.exit(1); |
|
| 15 |
+} |
|
| 16 |
+ |
|
| 17 |
+ |
|
| 11 | 18 |
/** |
| 12 | 19 |
*/ |
| 13 | 20 |
async function main(args : Array<string>) : Promise<void> |
| ... | ... |
@@ -24,13 +31,11 @@ async function main(args : Array<string>) : Promise<void> |
| 24 | 31 |
process.exit(0); |
| 25 | 32 |
break; |
| 26 | 33 |
} |
| 27 |
- case "feed": |
|
| 34 |
+ case "show": |
|
| 28 | 35 |
{
|
| 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); |
|
| 36 |
+ const concept_id = parseInt(args.shift()); |
|
| 37 |
+ const concept_entity : entities.concept = await services.concept.get(concept_id); |
|
| 38 |
+ console.info(JSON.stringify(concept_entity, undefined, "\t")); |
|
| 34 | 39 |
process.exit(0); |
| 35 | 40 |
break; |
| 36 | 41 |
} |
| ... | ... |
@@ -38,7 +43,7 @@ async function main(args : Array<string>) : Promise<void> |
| 38 | 43 |
{
|
| 39 | 44 |
const language_from : string = args.shift(); |
| 40 | 45 |
const language_to : string = args.shift(); |
| 41 |
- const part : string = args.shift(); |
|
| 46 |
+ const part : string = args.join(" "); args = [];
|
|
| 42 | 47 |
const result = await services.concept.get_translations |
| 43 | 48 |
( |
| 44 | 49 |
language_from, |
| ... | ... |
@@ -55,9 +60,9 @@ async function main(args : Array<string>) : Promise<void> |
| 55 | 60 |
( |
| 56 | 61 |
"[{{language_from}}] {{value_from}} ~ [{{language_to}}] {{value_to}}",
|
| 57 | 62 |
{
|
| 58 |
- "language_from": language_from, |
|
| 63 |
+ "language_from": entry["language_from"], |
|
| 59 | 64 |
"value_from": entry["value_from"], |
| 60 |
- "language_to": language_to, |
|
| 65 |
+ "language_to": entry["language_to"], |
|
| 61 | 66 |
"value_to": entry["value_to"], |
| 62 | 67 |
} |
| 63 | 68 |
) |
| ... | ... |
@@ -74,13 +79,86 @@ async function main(args : Array<string>) : Promise<void> |
| 74 | 79 |
process.exit(0); |
| 75 | 80 |
break; |
| 76 | 81 |
} |
| 77 |
- case "show": |
|
| 82 |
+ case "search": |
|
| 78 | 83 |
{
|
| 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")); |
|
| 84 |
+ const part : string = args.join(" "); args = [];
|
|
| 85 |
+ const result = await services.concept.search(part); |
|
| 86 |
+ result.forEach |
|
| 87 |
+ ( |
|
| 88 |
+ (entry) => |
|
| 89 |
+ {
|
|
| 90 |
+ console.info |
|
| 91 |
+ ( |
|
| 92 |
+ helpers.string.coin |
|
| 93 |
+ ( |
|
| 94 |
+ "{{id}} | {{type}} | {{description}} | {{tags}} | {{translations}}",
|
|
| 95 |
+ {
|
|
| 96 |
+ "id": entry["id"].toFixed(), |
|
| 97 |
+ "type": entry["type"], |
|
| 98 |
+ "description": (entry["description"] ?? '-'), |
|
| 99 |
+ "tags": entry["tags"].join(","),
|
|
| 100 |
+ "translations": entry["translations"].map(foo => (foo["language"] + ":" + foo["value"])).join(","),
|
|
| 101 |
+ } |
|
| 102 |
+ ) |
|
| 103 |
+ ); |
|
| 104 |
+ } |
|
| 105 |
+ ); |
|
| 106 |
+ process.exit(0); |
|
| 107 |
+ break; |
|
| 108 |
+ } |
|
| 109 |
+ case "feed": |
|
| 110 |
+ {
|
|
| 111 |
+ const content : string = await helpers.misc.stdin(); |
|
| 112 |
+ const data : any = JSON.parse(content); |
|
| 113 |
+ const concept_thing : any = data; |
|
| 114 |
+ const concept_id : int = await services.concept.suck(concept_thing); |
|
| 115 |
+ console.info(concept_id); |
|
| 116 |
+ process.exit(0); |
|
| 82 | 117 |
break; |
| 83 | 118 |
} |
| 119 |
+ case "new": |
|
| 120 |
+ {
|
|
| 121 |
+ if (args.length < 1) |
|
| 122 |
+ {
|
|
| 123 |
+ syntaxerror(); |
|
| 124 |
+ } |
|
| 125 |
+ else |
|
| 126 |
+ {
|
|
| 127 |
+ const type : string = args.shift(); |
|
| 128 |
+ const tags : Array<string> = ( |
|
| 129 |
+ (args.length >= 1) |
|
| 130 |
+ ? args.shift().split(",")
|
|
| 131 |
+ : [] |
|
| 132 |
+ ); |
|
| 133 |
+ const description : string = ( |
|
| 134 |
+ (args.length >= 1) |
|
| 135 |
+ ? args.shift() |
|
| 136 |
+ : null |
|
| 137 |
+ ); |
|
| 138 |
+ const concept_thing : any = |
|
| 139 |
+ {
|
|
| 140 |
+ "type": type, |
|
| 141 |
+ "description": description, |
|
| 142 |
+ "tags": tags, |
|
| 143 |
+ "translations": [], |
|
| 144 |
+ }; |
|
| 145 |
+ const concept_id : int = await services.concept.suck(concept_thing); |
|
| 146 |
+ console.info(concept_id); |
|
| 147 |
+ process.exit(0); |
|
| 148 |
+ } |
|
| 149 |
+ break; |
|
| 150 |
+ } |
|
| 151 |
+ case "set": |
|
| 152 |
+ {
|
|
| 153 |
+ if (args.length < 1) |
|
| 154 |
+ {
|
|
| 155 |
+ syntaxerror(); |
|
| 156 |
+ } |
|
| 157 |
+ else |
|
| 158 |
+ {
|
|
| 159 |
+ const concept_id : int = parseInt(args.shift()); |
|
| 160 |
+ } |
|
| 161 |
+ } |
|
| 84 | 162 |
default: |
| 85 | 163 |
{
|
| 86 | 164 |
console.error("unhandled command: " + command);
|
| ... | ... |
@@ -9,6 +9,7 @@ namespace repositories |
| 9 | 9 |
{
|
| 10 | 10 |
get_translations : (language_from : string, language_to : string, part : string)=>Promise<Array<type_row>>; |
| 11 | 11 |
export : ()=>Promise<Array<type_row>>; |
| 12 |
+ search : (part : string)=>Promise<Array<type_row>>; |
|
| 12 | 13 |
} |
| 13 | 14 |
) = |
| 14 | 15 |
{
|
| ... | ... |
@@ -67,21 +68,25 @@ namespace repositories |
| 67 | 68 |
}; |
| 68 | 69 |
return Promise.resolve<entities.concept>(concept_entity); |
| 69 | 70 |
}, |
| 70 |
- "get_translations": function (language_from : string, language_to : string, part : string) : Promise<Array<type_row>> |
|
| 71 |
+ "get_translations": function (language_from, language_to, part) |
|
| 71 | 72 |
{
|
| 72 | 73 |
return helpers.database.query_get_named |
| 73 | 74 |
( |
| 74 | 75 |
"concept.get_translations", |
| 75 | 76 |
{
|
| 76 |
- "language_value_from": language_from, |
|
| 77 |
- "language_value_to": language_to, |
|
| 77 |
+ "language_from": language_from, |
|
| 78 |
+ "language_to": language_to, |
|
| 78 | 79 |
"part": part.replace(new RegExp("-", "g"), "%"),
|
| 79 | 80 |
} |
| 80 | 81 |
); |
| 81 | 82 |
}, |
| 82 | 83 |
"export": function () : Promise<Array<type_row>> |
| 83 | 84 |
{
|
| 84 |
- return helpers.database.query_get_named("concept.export");
|
|
| 85 |
+ return helpers.database.query_get_named("concept.dump", {"part": null});
|
|
| 86 |
+ }, |
|
| 87 |
+ "search": function (part) : Promise<Array<type_row>> |
|
| 88 |
+ {
|
|
| 89 |
+ return helpers.database.query_get_named("concept.dump", {"part": part.replace(new RegExp("-", "g"), "%")});
|
|
| 85 | 90 |
}, |
| 86 | 91 |
}; |
| 87 | 92 |
|
| ... | ... |
@@ -67,6 +67,41 @@ namespace services.concept |
| 67 | 67 |
} |
| 68 | 68 |
|
| 69 | 69 |
|
| 70 |
+ /** |
|
| 71 |
+ */ |
|
| 72 |
+ function parse_tags( |
|
| 73 |
+ tags_raw : string |
|
| 74 |
+ ) : Array<string> |
|
| 75 |
+ {
|
|
| 76 |
+ return ( |
|
| 77 |
+ (tags_raw === null) |
|
| 78 |
+ ? [] |
|
| 79 |
+ : tags_raw.split(",")
|
|
| 80 |
+ ); |
|
| 81 |
+ } |
|
| 82 |
+ |
|
| 83 |
+ |
|
| 84 |
+ /** |
|
| 85 |
+ */ |
|
| 86 |
+ function parse_translations |
|
| 87 |
+ ( |
|
| 88 |
+ translations_raw : string |
|
| 89 |
+ ) : Array<{id : int; language : string; value : string;}>
|
|
| 90 |
+ {
|
|
| 91 |
+ let result : Array<{id : int; language : string; value : string;}> = [];
|
|
| 92 |
+ const parts : Array<string> = translations_raw.split(",")
|
|
| 93 |
+ parts.forEach |
|
| 94 |
+ ( |
|
| 95 |
+ (part) => |
|
| 96 |
+ {
|
|
| 97 |
+ const [id, language, value] : Array<string> = part.split(":", 3);
|
|
| 98 |
+ result.push({"id": parseInt(id), "language": language, "value": value});
|
|
| 99 |
+ } |
|
| 100 |
+ ); |
|
| 101 |
+ return result; |
|
| 102 |
+ } |
|
| 103 |
+ |
|
| 104 |
+ |
|
| 70 | 105 |
/** |
| 71 | 106 |
*/ |
| 72 | 107 |
export function get_translations |
| ... | ... |
@@ -89,33 +124,45 @@ namespace services.concept |
| 89 | 124 |
*/ |
| 90 | 125 |
export async function export_ |
| 91 | 126 |
( |
| 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> |
|
| 127 |
+ ) : Promise<Array<{id : int; type : string; description : string; tags : Array<string>; translations : Array<{id : int; language : string; value : string;}>;}>>
|
|
| 95 | 128 |
{
|
| 96 | 129 |
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 |
|
| 130 |
+ repositories.concept.export() |
|
| 131 |
+ .then |
|
| 107 | 132 |
( |
| 108 |
- (part) => |
|
| 133 |
+ rows => Promise.resolve |
|
| 134 |
+ ( |
|
| 135 |
+ rows.map |
|
| 136 |
+ ( |
|
| 137 |
+ (row) => ( |
|
| 109 | 138 |
{
|
| 110 |
- const [language, value] : Array<string> = part.split(":", 2);
|
|
| 111 |
- if (! result.hasOwnProperty(language)) result[language] = []; |
|
| 112 |
- result[language].push(value); |
|
| 139 |
+ "id": row["id"], |
|
| 140 |
+ "type": row["type"], |
|
| 141 |
+ "description": row["description"], |
|
| 142 |
+ "tags": parse_tags(row["tags"]), |
|
| 143 |
+ "translations": parse_translations(row["translations"]), |
|
| 113 | 144 |
} |
| 114 |
- ); |
|
| 115 |
- return result; |
|
| 116 |
- }; |
|
| 117 |
- const rows : Array<type_row> = await repositories.concept.export(); |
|
| 118 |
- return Promise.resolve<any>( |
|
| 145 |
+ ) |
|
| 146 |
+ ) |
|
| 147 |
+ ) |
|
| 148 |
+ ) |
|
| 149 |
+ ) |
|
| 150 |
+ } |
|
| 151 |
+ |
|
| 152 |
+ |
|
| 153 |
+ /** |
|
| 154 |
+ */ |
|
| 155 |
+ export function search |
|
| 156 |
+ ( |
|
| 157 |
+ part : string |
|
| 158 |
+ ) : Promise<Array<{id : int; type : string; description : string; tags : Array<string>; translations : Array<{id : int; language : string; value : string;}>;}>>
|
|
| 159 |
+ {
|
|
| 160 |
+ return ( |
|
| 161 |
+ repositories.concept.search(part) |
|
| 162 |
+ .then |
|
| 163 |
+ ( |
|
| 164 |
+ rows => Promise.resolve |
|
| 165 |
+ ( |
|
| 119 | 166 |
rows.map |
| 120 | 167 |
( |
| 121 | 168 |
(row) => ( |
| ... | ... |
@@ -125,7 +172,10 @@ namespace services.concept |
| 125 | 172 |
"description": row["description"], |
| 126 | 173 |
"tags": parse_tags(row["tags"]), |
| 127 | 174 |
"translations": parse_translations(row["translations"]), |
| 128 |
- }) |
|
| 175 |
+ } |
|
| 176 |
+ ) |
|
| 177 |
+ ) |
|
| 178 |
+ ) |
|
| 129 | 179 |
) |
| 130 | 180 |
) |
| 131 | 181 |
} |
| ... | ... |
@@ -1,8 +1,9 @@ |
| 1 | 1 |
SELECT |
| 2 | 2 |
x1.id AS id, |
| 3 | 3 |
MIN(x2.value) AS type, |
| 4 |
+ MIN(x1.description) AS description, |
|
| 4 | 5 |
GROUP_CONCAT(DISTINCT x4.value) AS tags, |
| 5 |
- GROUP_CONCAT(x6.value || ':' || x5.value) AS translations |
|
| 6 |
+ GROUP_CONCAT(x5.id || ':' || x6.value || ':' || x5.value) AS translations |
|
| 6 | 7 |
FROM |
| 7 | 8 |
concepts AS x1 |
| 8 | 9 |
LEFT OUTER JOIN types AS x2 ON (x1.type_id = x2.id) |
| ... | ... |
@@ -10,6 +11,12 @@ FROM |
| 10 | 11 |
LEFT OUTER JOIN tags AS x4 ON (x3.tag_id = x4.id) |
| 11 | 12 |
LEFT OUTER JOIN concept_translations AS x5 ON (x1.id = x5.concept_id) |
| 12 | 13 |
LEFT OUTER JOIN languages AS x6 ON (x5.language_id = x6.id) |
| 14 |
+WHERE |
|
| 15 |
+ ( |
|
| 16 |
+ (:part IS NULL) |
|
| 17 |
+ OR |
|
| 18 |
+ (x5.value LIKE :part) |
|
| 19 |
+ ) |
|
| 13 | 20 |
GROUP BY |
| 14 | 21 |
x1.id |
| 15 | 22 |
; |
| ... | ... |
@@ -1,16 +1,29 @@ |
| 1 | 1 |
SELECT |
| 2 |
- x.concept_id AS concept_id, |
|
| 3 |
- x.value AS value_from, |
|
| 4 |
- y.value AS value_to |
|
| 2 |
+ x1.concept_id AS concept_id, |
|
| 3 |
+ x2.value AS language_from, |
|
| 4 |
+ x1.value AS value_from, |
|
| 5 |
+ y2.value AS language_to, |
|
| 6 |
+ y1.value AS value_to |
|
| 5 | 7 |
FROM |
| 6 |
- concept_translations AS x INNER JOIN concept_translations AS y ON (x.concept_id = y.concept_id) |
|
| 8 |
+ concept_translations AS x1 |
|
| 9 |
+ INNER JOIN languages AS x2 ON (x1.language_id = x2.id) |
|
| 10 |
+ INNER JOIN concept_translations AS y1 ON ((x1.id <> y1.id) AND (x1.concept_id = y1.concept_id)) |
|
| 11 |
+ INNER JOIN languages AS y2 ON (y1.language_id = y2.id) |
|
| 7 | 12 |
WHERE |
| 8 | 13 |
( |
| 9 |
- (x.language_id = (SELECT id FROM languages WHERE (value = :language_value_from))) |
|
| 14 |
+ ( |
|
| 15 |
+ (:language_from = '_') |
|
| 16 |
+ OR |
|
| 17 |
+ (x2.value = :language_from) |
|
| 18 |
+ ) |
|
| 10 | 19 |
AND |
| 11 |
- (y.language_id = (SELECT id FROM languages WHERE (value = :language_value_to))) |
|
| 20 |
+ ( |
|
| 21 |
+ (:language_to = '_') |
|
| 22 |
+ OR |
|
| 23 |
+ (y2.value = :language_to) |
|
| 24 |
+ ) |
|
| 12 | 25 |
AND |
| 13 |
- (x.value LIKE :part) |
|
| 26 |
+ (x1.value LIKE :part) |
|
| 14 | 27 |
) |
| 15 | 28 |
; |
| 16 | 29 |
|
| 17 | 30 |