Christian Fraß commited on 2021-03-03 23:53:00
              Zeige 20 geänderte Dateien mit 747 Einfügungen und 425 Löschungen.
            
| ... | ... | 
                      @@ -14,5 +14,35 @@ namespace helpers.file  | 
                  
| 14 | 14 | 
                        return content;  | 
                    
| 15 | 15 | 
                        }  | 
                    
| 16 | 16 | 
                         | 
                    
| 17 | 
                        +  | 
                    |
| 18 | 
                        + /**  | 
                    |
| 19 | 
                        + */  | 
                    |
| 20 | 
                        + export function write  | 
                    |
| 21 | 
                        + (  | 
                    |
| 22 | 
                        + path : string,  | 
                    |
| 23 | 
                        + content : string  | 
                    |
| 24 | 
                        + ) : Promise<void>  | 
                    |
| 25 | 
                        +	{
                       | 
                    |
| 26 | 
                        +		const nm_fs = require("fs");
                       | 
                    |
| 27 | 
                        + return (  | 
                    |
| 28 | 
                        + new Promise<void>  | 
                    |
| 29 | 
                        + (  | 
                    |
| 30 | 
                        + (resolve, reject) =>  | 
                    |
| 31 | 
                        +				{
                       | 
                    |
| 32 | 
                        + nm_fs.writeFileSync  | 
                    |
| 33 | 
                        + (  | 
                    |
| 34 | 
                        + path,  | 
                    |
| 35 | 
                        + content,  | 
                    |
| 36 | 
                        + (error) =>  | 
                    |
| 37 | 
                        +						{
                       | 
                    |
| 38 | 
                        + if (error) reject(error);  | 
                    |
| 39 | 
                        + else resolve(undefined);  | 
                    |
| 40 | 
                        + }  | 
                    |
| 41 | 
                        + );  | 
                    |
| 42 | 
                        + }  | 
                    |
| 43 | 
                        + )  | 
                    |
| 44 | 
                        + );  | 
                    |
| 45 | 
                        + }  | 
                    |
| 46 | 
                        +  | 
                    |
| 17 | 47 | 
                        }  | 
                    
| 18 | 48 | 
                         | 
                    
| ... | ... | 
                      @@ -20,5 +20,21 @@ namespace helpers.string  | 
                  
| 20 | 20 | 
                        return result;  | 
                    
| 21 | 21 | 
                        }  | 
                    
| 22 | 22 | 
                         | 
                    
| 23 | 
                        +  | 
                    |
| 24 | 
                        + export function pad_left  | 
                    |
| 25 | 
                        + (  | 
                    |
| 26 | 
                        + subject : string,  | 
                    |
| 27 | 
                        + length : int,  | 
                    |
| 28 | 
                        + filler : string  | 
                    |
| 29 | 
                        + ) : string  | 
                    |
| 30 | 
                        +	{
                       | 
                    |
| 31 | 
                        + let result : string = subject;  | 
                    |
| 32 | 
                        + while (result.length < length)  | 
                    |
| 33 | 
                        +		{
                       | 
                    |
| 34 | 
                        + result = (filler + result);  | 
                    |
| 35 | 
                        + }  | 
                    |
| 36 | 
                        + return result;  | 
                    |
| 37 | 
                        + }  | 
                    |
| 38 | 
                        +  | 
                    |
| 23 | 39 | 
                        }  | 
                    
| 24 | 40 | 
                         | 
                    
| ... | ... | 
                      @@ -24,18 +24,19 @@ async function main(args : Array<string>) : Promise<void>  | 
                  
| 24 | 24 | 
                         	{
                       | 
                    
| 25 | 25 | 
                        case "setup":  | 
                    
| 26 | 26 | 
                         		{
                       | 
                    
| 27 | 
                        - await repositories.language.setup()  | 
                    |
| 28 | 
                        - await repositories.type.setup()  | 
                    |
| 29 | 
                        - await repositories.tag.setup()  | 
                    |
| 30 | 
                        - await repositories.concept.setup()  | 
                    |
| 27 | 
                        + await repositories.language.setup();  | 
                    |
| 28 | 
                        + await repositories.type.setup();  | 
                    |
| 29 | 
                        + await repositories.tag.setup();  | 
                    |
| 30 | 
                        + await repositories.expression.setup();  | 
                    |
| 31 | 
                        + await repositories.concept.setup();  | 
                    |
| 31 | 32 | 
                        process.exit(0);  | 
                    
| 32 | 33 | 
                        break;  | 
                    
| 33 | 34 | 
                        }  | 
                    
| 34 | 35 | 
                        case "show":  | 
                    
| 35 | 36 | 
                         		{
                       | 
                    
| 36 | 37 | 
                        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"));  | 
                    |
| 38 | 
                        + const exposal : services.concept.type_exposal = await services.concept.expose(concept_id);  | 
                    |
| 39 | 
                        + console.info(JSON.stringify(exposal, undefined, "\t"));  | 
                    |
| 39 | 40 | 
                        process.exit(0);  | 
                    
| 40 | 41 | 
                        break;  | 
                    
| 41 | 42 | 
                        }  | 
                    
| ... | ... | 
                      @@ -74,15 +75,29 @@ async function main(args : Array<string>) : Promise<void>  | 
                  
| 74 | 75 | 
                        }  | 
                    
| 75 | 76 | 
                        case "export":  | 
                    
| 76 | 77 | 
                         		{
                       | 
                    
| 77 | 
                        - const result : Array<any> = await services.concept.export_();  | 
                    |
| 78 | 
                        - console.info(JSON.stringify(result, undefined, "\t"));  | 
                    |
| 78 | 
                        + const directory : string = ((args.length >= 1) ? args.shift() : "/tmp");  | 
                    |
| 79 | 
                        + const result : Array<services.concept.type_exposal> = await services.concept.export_();  | 
                    |
| 80 | 
                        + for await (const exposal of result)  | 
                    |
| 81 | 
                        +			{
                       | 
                    |
| 82 | 
                        + const path : string = helpers.string.coin  | 
                    |
| 83 | 
                        + (  | 
                    |
| 84 | 
                        +					"{{directory}}/concept_{{id}}.json",
                       | 
                    |
| 85 | 
                        +					{
                       | 
                    |
| 86 | 
                        + "directory": directory,  | 
                    |
| 87 | 
                        + "id": helpers.string.pad_left(exposal.id.toFixed(0), 5, "0"),  | 
                    |
| 88 | 
                        + }  | 
                    |
| 89 | 
                        + );  | 
                    |
| 90 | 
                        + const content : string = JSON.stringify(result, undefined, "\t");  | 
                    |
| 91 | 
                        + await helpers.file.write(path, content);  | 
                    |
| 92 | 
                        + }  | 
                    |
| 93 | 
                        + console.info(directory);  | 
                    |
| 79 | 94 | 
                        process.exit(0);  | 
                    
| 80 | 95 | 
                        break;  | 
                    
| 81 | 96 | 
                        }  | 
                    
| 82 | 97 | 
                        case "search":  | 
                    
| 83 | 98 | 
                         		{
                       | 
                    
| 84 | 99 | 
                         			const part : string = args.join(" "); args = [];
                       | 
                    
| 85 | 
                        - const result = await services.concept.search(part);  | 
                    |
| 100 | 
                        + const result : Array<services.concept.type_exposal> = await services.concept.search(part);  | 
                    |
| 86 | 101 | 
                        result.forEach  | 
                    
| 87 | 102 | 
                        (  | 
                    
| 88 | 103 | 
                        (entry) =>  | 
                    
| ... | ... | 
                      @@ -91,13 +106,23 @@ async function main(args : Array<string>) : Promise<void>  | 
                  
| 91 | 106 | 
                        (  | 
                    
| 92 | 107 | 
                        helpers.string.coin  | 
                    
| 93 | 108 | 
                        (  | 
                    
| 94 | 
                        -							"{{id}} | {{type}} | {{description}} | {{tags}} | {{translations}}",
                       | 
                    |
| 109 | 
                        +							"{{id}} | {{type}} | {{description}} | {{tags}} | {{expressions}}",
                       | 
                    |
| 95 | 110 | 
                         							{
                       | 
                    
| 96 | 111 | 
                        "id": entry["id"].toFixed(),  | 
                    
| 97 | 112 | 
                        "type": entry["type"],  | 
                    
| 98 | 113 | 
                        "description": (entry["description"] ?? '-'),  | 
                    
| 99 | 114 | 
                         								"tags": entry["tags"].join(","),
                       | 
                    
| 100 | 
                        -								"translations": entry["translations"].map(foo => (foo["language"] + ":" + foo["value"])).join(","),
                       | 
                    |
| 115 | 
                        + "expressions": (  | 
                    |
| 116 | 
                        + () =>  | 
                    |
| 117 | 
                        +									{
                       | 
                    |
| 118 | 
                        + let parts : Array<string> = [];  | 
                    |
| 119 | 
                        + for (const [key, value] of Object.entries(entry["expressions"]))  | 
                    |
| 120 | 
                        +										{
                       | 
                    |
| 121 | 
                        +											parts.push(key + ":" + value.join("/"));
                       | 
                    |
| 122 | 
                        + }  | 
                    |
| 123 | 
                        +										return parts.join(",");
                       | 
                    |
| 124 | 
                        + }  | 
                    |
| 125 | 
                        + ) (),  | 
                    |
| 101 | 126 | 
                        }  | 
                    
| 102 | 127 | 
                        )  | 
                    
| 103 | 128 | 
                        );  | 
                    
| ... | ... | 
                      @@ -140,7 +165,7 @@ async function main(args : Array<string>) : Promise<void>  | 
                  
| 140 | 165 | 
                        "type": type,  | 
                    
| 141 | 166 | 
                        "description": description,  | 
                    
| 142 | 167 | 
                        "tags": tags,  | 
                    
| 143 | 
                        - "translations": [],  | 
                    |
| 168 | 
                        + "expressions": [],  | 
                    |
| 144 | 169 | 
                        };  | 
                    
| 145 | 170 | 
                        const concept_id : int = await services.concept.suck(concept_thing);  | 
                    
| 146 | 171 | 
                        console.info(concept_id);  | 
                    
| ... | ... | 
                      @@ -1,78 +0,0 @@  | 
                  
| 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 | 
                        -  | 
                    
| ... | ... | 
                      @@ -1,92 +0,0 @@  | 
                  
| 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 | 
                        -  | 
                    
| ... | ... | 
                      @@ -1,94 +0,0 @@  | 
                  
| 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 | 
                        -  | 
                    
| ... | ... | 
                      @@ -1,45 +1,291 @@  | 
                  
| 1 | 1 | 
                        namespace repositories  | 
                    
| 2 | 2 | 
                         {
                       | 
                    
| 3 | 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 | 
                        + export var concept_tags : helpers.repository_sqltable =  | 
                    |
| 79 | 
                        +	{
                       | 
                    |
| 80 | 
                        + "setup": function ()  | 
                    |
| 81 | 
                        +		{
                       | 
                    |
| 82 | 
                        +			return helpers.database.query_do_named("concept.setup-tags");
                       | 
                    |
| 83 | 
                        + },  | 
                    |
| 84 | 
                        + "teardown": function ()  | 
                    |
| 85 | 
                        +		{
                       | 
                    |
| 86 | 
                        +			throw (new Error("not implemented"));
                       | 
                    |
| 87 | 
                        + },  | 
                    |
| 88 | 
                        + "create": function (row)  | 
                    |
| 89 | 
                        +		{
                       | 
                    |
| 90 | 
                        + return helpers.database.query_put_free  | 
                    |
| 91 | 
                        + (  | 
                    |
| 92 | 
                        + "INSERT INTO concept_tags(concept_id, tag_id) VALUES (:concept_id, :tag_id);",  | 
                    |
| 93 | 
                        +				{
                       | 
                    |
| 94 | 
                        + "concept_id": row["concept_id"],  | 
                    |
| 95 | 
                        + "tag_id": row["tag_id"],  | 
                    |
| 96 | 
                        + }  | 
                    |
| 97 | 
                        + );  | 
                    |
| 98 | 
                        + },  | 
                    |
| 99 | 
                        + "update": function (concept_tag_id, row)  | 
                    |
| 100 | 
                        +		{
                       | 
                    |
| 101 | 
                        + return helpers.database.query_do_free  | 
                    |
| 102 | 
                        + (  | 
                    |
| 103 | 
                        + "UPDATE concept_tags SET concept_id = :concept_id, tag_id = :tag_id WHERE (id = :id)",  | 
                    |
| 104 | 
                        +				{
                       | 
                    |
| 105 | 
                        + "id": concept_tag_id,  | 
                    |
| 106 | 
                        + "concept_id": row["concept_id"],  | 
                    |
| 107 | 
                        + "tag_id": row["tag_id"],  | 
                    |
| 108 | 
                        + }  | 
                    |
| 109 | 
                        + );  | 
                    |
| 110 | 
                        + },  | 
                    |
| 111 | 
                        + "delete": function (concept_tag_id)  | 
                    |
| 112 | 
                        +		{
                       | 
                    |
| 113 | 
                        + return helpers.database.query_do_free  | 
                    |
| 114 | 
                        + (  | 
                    |
| 115 | 
                        + "DELETE FROM concept_tags WHERE (id = :id)",  | 
                    |
| 116 | 
                        +				{
                       | 
                    |
| 117 | 
                        + "id": concept_tag_id,  | 
                    |
| 118 | 
                        + }  | 
                    |
| 119 | 
                        + );  | 
                    |
| 120 | 
                        + },  | 
                    |
| 121 | 
                        + "read": async function (concept_tag_id)  | 
                    |
| 122 | 
                        +		{
                       | 
                    |
| 123 | 
                        + return (  | 
                    |
| 124 | 
                        + helpers.database.query_get_free  | 
                    |
| 125 | 
                        + (  | 
                    |
| 126 | 
                        + "SELECT concept_id,tag_id FROM concept_tags WHERE (id = :id)",  | 
                    |
| 127 | 
                        +					{
                       | 
                    |
| 128 | 
                        + "id": concept_tag_id,  | 
                    |
| 129 | 
                        + }  | 
                    |
| 130 | 
                        + )  | 
                    |
| 131 | 
                        + .then  | 
                    |
| 132 | 
                        + (  | 
                    |
| 133 | 
                        + (rows) => (  | 
                    |
| 134 | 
                        + (rows.length === 1)  | 
                    |
| 135 | 
                        + ? Promise.resolve<type_row>(rows[0])  | 
                    |
| 136 | 
                        +						: Promise.reject<type_row>(new Error("not found"))
                       | 
                    |
| 137 | 
                        + )  | 
                    |
| 138 | 
                        + )  | 
                    |
| 139 | 
                        + );  | 
                    |
| 140 | 
                        + },  | 
                    |
| 141 | 
                        + "purge": async function (column, value)  | 
                    |
| 142 | 
                        +		{
                       | 
                    |
| 143 | 
                        + return helpers.database.query_do_free  | 
                    |
| 144 | 
                        + (  | 
                    |
| 145 | 
                        +				"DELETE FROM concept_tags WHERE (" + column + " = :value)",
                       | 
                    |
| 146 | 
                        +				{
                       | 
                    |
| 147 | 
                        + "value": value,  | 
                    |
| 148 | 
                        + }  | 
                    |
| 149 | 
                        + );  | 
                    |
| 150 | 
                        + },  | 
                    |
| 151 | 
                        + "take": async function (column, value)  | 
                    |
| 152 | 
                        +		{
                       | 
                    |
| 153 | 
                        + return await helpers.database.query_get_free  | 
                    |
| 154 | 
                        + (  | 
                    |
| 155 | 
                        +				"SELECT concept_id,tag_id FROM concept_tags WHERE (" + column + " = :value)",
                       | 
                    |
| 156 | 
                        +				{
                       | 
                    |
| 157 | 
                        + "value": value,  | 
                    |
| 158 | 
                        + }  | 
                    |
| 159 | 
                        + );  | 
                    |
| 160 | 
                        + },  | 
                    |
| 161 | 
                        + };  | 
                    |
| 162 | 
                        +  | 
                    |
| 163 | 
                        +  | 
                    |
| 4 | 164 | 
                        /**  | 
                    
| 5 | 165 | 
                        */  | 
                    
| 166 | 
                        + export var concept_expressions : helpers.repository_sqltable =  | 
                    |
| 167 | 
                        +	{
                       | 
                    |
| 168 | 
                        + "setup": function ()  | 
                    |
| 169 | 
                        +		{
                       | 
                    |
| 170 | 
                        +			return helpers.database.query_do_named("concept.setup-expressions");
                       | 
                    |
| 171 | 
                        + },  | 
                    |
| 172 | 
                        + "teardown": function ()  | 
                    |
| 173 | 
                        +		{
                       | 
                    |
| 174 | 
                        +			throw (new Error("not implemented"));
                       | 
                    |
| 175 | 
                        + },  | 
                    |
| 176 | 
                        + "create": function (row)  | 
                    |
| 177 | 
                        +		{
                       | 
                    |
| 178 | 
                        + return helpers.database.query_put_free  | 
                    |
| 179 | 
                        + (  | 
                    |
| 180 | 
                        + "INSERT INTO concept_expressions(concept_id, expression_id) VALUES (:concept_id, :expression_id);",  | 
                    |
| 181 | 
                        +				{
                       | 
                    |
| 182 | 
                        + "concept_id": row["concept_id"],  | 
                    |
| 183 | 
                        + "expression_id": row["expression_id"],  | 
                    |
| 184 | 
                        + }  | 
                    |
| 185 | 
                        + );  | 
                    |
| 186 | 
                        + },  | 
                    |
| 187 | 
                        + "update": function (concept_expression_id, row)  | 
                    |
| 188 | 
                        +		{
                       | 
                    |
| 189 | 
                        + return helpers.database.query_do_free  | 
                    |
| 190 | 
                        + (  | 
                    |
| 191 | 
                        + "UPDATE concept_expressions SET concept_id = :concept_id, expression_id = :expression_id WHERE (id = :id)",  | 
                    |
| 192 | 
                        +				{
                       | 
                    |
| 193 | 
                        + "id": concept_expression_id,  | 
                    |
| 194 | 
                        + "concept_id": row["concept_id"],  | 
                    |
| 195 | 
                        + "expression_id": row["expression_id"],  | 
                    |
| 196 | 
                        + }  | 
                    |
| 197 | 
                        + );  | 
                    |
| 198 | 
                        + },  | 
                    |
| 199 | 
                        + "delete": function (concept_expression_id)  | 
                    |
| 200 | 
                        +		{
                       | 
                    |
| 201 | 
                        + return helpers.database.query_do_free  | 
                    |
| 202 | 
                        + (  | 
                    |
| 203 | 
                        + "DELETE FROM concept_expressions WHERE (id = :id)",  | 
                    |
| 204 | 
                        +				{
                       | 
                    |
| 205 | 
                        + "id": concept_expression_id,  | 
                    |
| 206 | 
                        + }  | 
                    |
| 207 | 
                        + );  | 
                    |
| 208 | 
                        + },  | 
                    |
| 209 | 
                        + "read": async function (concept_expression_id)  | 
                    |
| 210 | 
                        +		{
                       | 
                    |
| 211 | 
                        + return (  | 
                    |
| 212 | 
                        + helpers.database.query_get_free  | 
                    |
| 213 | 
                        + (  | 
                    |
| 214 | 
                        + "SELECT concept_id,expression_id FROM concept_expressions WHERE (id = :id)",  | 
                    |
| 215 | 
                        +					{
                       | 
                    |
| 216 | 
                        + "id": concept_expression_id,  | 
                    |
| 217 | 
                        + }  | 
                    |
| 218 | 
                        + )  | 
                    |
| 219 | 
                        + .then  | 
                    |
| 220 | 
                        + (  | 
                    |
| 221 | 
                        + (rows) => (  | 
                    |
| 222 | 
                        + (rows.length === 1)  | 
                    |
| 223 | 
                        + ? Promise.resolve<type_row>(rows[0])  | 
                    |
| 224 | 
                        +						: Promise.reject<type_row>(new Error("not found"))
                       | 
                    |
| 225 | 
                        + )  | 
                    |
| 226 | 
                        + )  | 
                    |
| 227 | 
                        + );  | 
                    |
| 228 | 
                        + },  | 
                    |
| 229 | 
                        + "purge": async function (column, value)  | 
                    |
| 230 | 
                        +		{
                       | 
                    |
| 231 | 
                        + return helpers.database.query_do_free  | 
                    |
| 232 | 
                        + (  | 
                    |
| 233 | 
                        +				"DELETE FROM concept_expressions WHERE (" + column + " = :value)",
                       | 
                    |
| 234 | 
                        +				{
                       | 
                    |
| 235 | 
                        + "value": value,  | 
                    |
| 236 | 
                        + }  | 
                    |
| 237 | 
                        + );  | 
                    |
| 238 | 
                        + },  | 
                    |
| 239 | 
                        + "take": async function (column, value)  | 
                    |
| 240 | 
                        +		{
                       | 
                    |
| 241 | 
                        + return await helpers.database.query_get_free  | 
                    |
| 242 | 
                        + (  | 
                    |
| 243 | 
                        +				"SELECT concept_id,expression_id FROM concept_expressions WHERE (" + column + " = :value)",
                       | 
                    |
| 244 | 
                        +				{
                       | 
                    |
| 245 | 
                        + "value": value,  | 
                    |
| 246 | 
                        + }  | 
                    |
| 247 | 
                        + );  | 
                    |
| 248 | 
                        + },  | 
                    |
| 249 | 
                        + };  | 
                    |
| 250 | 
                        +  | 
                    |
| 251 | 
                        +  | 
                    |
| 6 | 252 | 
                        export var concept : (  | 
                    
| 7 | 253 | 
                        helpers.repository<int, entities.concept>  | 
                    
| 8 | 254 | 
                        &  | 
                    
| 9 | 255 | 
                         		{
                       | 
                    
| 10 | 256 | 
                        get_translations : (language_from : string, language_to : string, part : string)=>Promise<Array<type_row>>;  | 
                    
| 257 | 
                        + search : (part : string)=>Promise<Array<int>>;  | 
                    |
| 11 | 258 | 
                        export : ()=>Promise<Array<type_row>>;  | 
                    
| 12 | 
                        - search : (part : string)=>Promise<Array<type_row>>;  | 
                    |
| 13 | 259 | 
                        }  | 
                    
| 14 | 260 | 
                        ) =  | 
                    
| 15 | 261 | 
                         	{
                       | 
                    
| 16 | 262 | 
                        "setup": async function ()  | 
                    
| 17 | 263 | 
                         		{
                       | 
                    
| 18 | 
                        - await repositories.concept_core.setup();  | 
                    |
| 19 | 
                        - await repositories.concept_tags.setup();  | 
                    |
| 20 | 
                        - await repositories.concept_translations.setup();  | 
                    |
| 264 | 
                        + await concept_core.setup();  | 
                    |
| 265 | 
                        + await concept_tags.setup();  | 
                    |
| 266 | 
                        + await concept_expressions.setup();  | 
                    |
| 21 | 267 | 
                        return Promise.resolve<void>(undefined);  | 
                    
| 22 | 268 | 
                        },  | 
                    
| 23 | 269 | 
                        "teardown": async function ()  | 
                    
| 24 | 270 | 
                         		{
                       | 
                    
| 25 | 
                        - await repositories.concept_translations.teardown();  | 
                    |
| 26 | 
                        - await repositories.concept_tags.teardown();  | 
                    |
| 27 | 
                        - await repositories.concept_core.teardown();  | 
                    |
| 271 | 
                        + await concept_expressions.teardown();  | 
                    |
| 272 | 
                        + await concept_tags.teardown();  | 
                    |
| 273 | 
                        + await concept_core.teardown();  | 
                    |
| 28 | 274 | 
                        return Promise.resolve<void>(undefined);  | 
                    
| 29 | 275 | 
                        },  | 
                    
| 30 | 276 | 
                        "create": async function (concept_entity)  | 
                    
| 31 | 277 | 
                         		{
                       | 
                    
| 32 | 278 | 
                         			const row_core : type_row = {"type_id": concept_entity.type_id, "description": concept_entity.description};
                       | 
                    
| 33 | 
                        - const concept_id : int = await repositories.concept_core.create(row_core);  | 
                    |
| 279 | 
                        + const concept_id : int = await concept_core.create(row_core);  | 
                    |
| 34 | 280 | 
                        for await (let tag_id of concept_entity.tags)  | 
                    
| 35 | 281 | 
                         			{
                       | 
                    
| 36 | 282 | 
                         				const row_tag : type_row = {"concept_id": concept_id, "tag_id": tag_id};
                       | 
                    
| 37 | 
                        - const concept_tag_id : int = await repositories.concept_tags.create(row_tag);  | 
                    |
| 283 | 
                        + const concept_tag_id : int = await concept_tags.create(row_tag);  | 
                    |
| 38 | 284 | 
                        }  | 
                    
| 39 | 
                        -			for await (let {"language_id": language_id, "value": value} of concept_entity.translations)
                       | 
                    |
| 285 | 
                        + for await (let expression_id of concept_entity.expressions)  | 
                    |
| 40 | 286 | 
                         			{
                       | 
                    
| 41 | 
                        -				const row_translations : type_row = {"concept_id": concept_id, "language_id": language_id, "value": value};
                       | 
                    |
| 42 | 
                        - const concept_translations_id : int = await repositories.concept_translations.create(row_translations);  | 
                    |
| 287 | 
                        +				const row_expressions : type_row = {"concept_id": concept_id, "expression_id": expression_id};
                       | 
                    |
| 288 | 
                        + const concept_expressions_id : int = await concept_expressions.create(row_expressions);  | 
                    |
| 43 | 289 | 
                        }  | 
                    
| 44 | 290 | 
                        return Promise.resolve<int>(concept_id);  | 
                    
| 45 | 291 | 
                        },  | 
                    
| ... | ... | 
                      @@ -49,22 +295,22 @@ namespace repositories  | 
                  
| 49 | 295 | 
                        },  | 
                    
| 50 | 296 | 
                        "delete": async function (concept_id)  | 
                    
| 51 | 297 | 
                         		{
                       | 
                    
| 52 | 
                        -			await repositories.concept_translations.purge("concept_id", concept_id);
                       | 
                    |
| 53 | 
                        -			await repositories.concept_tags.purge("concept_id", concept_id);
                       | 
                    |
| 54 | 
                        - await repositories.concept_core.delete(concept_id);  | 
                    |
| 298 | 
                        +			await concept_expressions.purge("concept_id", concept_id);
                       | 
                    |
| 299 | 
                        +			await concept_tags.purge("concept_id", concept_id);
                       | 
                    |
| 300 | 
                        + await concept_core.delete(concept_id);  | 
                    |
| 55 | 301 | 
                        return Promise.resolve<void>(undefined);  | 
                    
| 56 | 302 | 
                        },  | 
                    
| 57 | 303 | 
                        "read": async function (concept_id)  | 
                    
| 58 | 304 | 
                         		{
                       | 
                    
| 59 | 
                        - const row_core : type_row = await repositories.concept_core.read(concept_id);;  | 
                    |
| 60 | 
                        -			const rows_tags : Array<type_row> = await repositories.concept_tags.take("concept_id", concept_id);
                       | 
                    |
| 61 | 
                        -			const rows_translations : Array<type_row> = await repositories.concept_translations.take("concept_id", concept_id);
                       | 
                    |
| 305 | 
                        + const row_core : type_row = await concept_core.read(concept_id);;  | 
                    |
| 306 | 
                        +			const rows_tags : Array<type_row> = await concept_tags.take("concept_id", concept_id);
                       | 
                    |
| 307 | 
                        +			const rows_expressions : Array<type_row> = await concept_expressions.take("concept_id", concept_id);
                       | 
                    |
| 62 | 308 | 
                        const concept_entity : entities.concept =  | 
                    
| 63 | 309 | 
                         			{
                       | 
                    
| 64 | 310 | 
                        "type_id": row_core["type_id"],  | 
                    
| 65 | 311 | 
                        "description": row_core["description"],  | 
                    
| 66 | 312 | 
                        "tags": rows_tags.map(row_tag => row_tag["tag_id"]),  | 
                    
| 67 | 
                        -				"translations": rows_translations.map(row_translation => ({"language_id": row_translation["language_id"], "value": row_translation["value"]})),
                       | 
                    |
| 313 | 
                        + "expressions": rows_expressions.map(row_expression => row_expression["expression_id"]),  | 
                    |
| 68 | 314 | 
                        };  | 
                    
| 69 | 315 | 
                        return Promise.resolve<entities.concept>(concept_entity);  | 
                    
| 70 | 316 | 
                        },  | 
                    
| ... | ... | 
                      @@ -80,13 +326,19 @@ namespace repositories  | 
                  
| 80 | 326 | 
                        }  | 
                    
| 81 | 327 | 
                        );  | 
                    
| 82 | 328 | 
                        },  | 
                    
| 83 | 
                        - "export": function () : Promise<Array<type_row>>  | 
                    |
| 329 | 
                        + "search": function (part) : Promise<Array<int>>  | 
                    |
| 84 | 330 | 
                         		{
                       | 
                    
| 85 | 
                        -			return helpers.database.query_get_named("concept.dump", {"part": null});
                       | 
                    |
| 331 | 
                        + return (  | 
                    |
| 332 | 
                        +				helpers.database.query_get_named("concept.search", {"part": part.replace(new RegExp("-", "g"), "%")})
                       | 
                    |
| 333 | 
                        + .then<Array<int>>  | 
                    |
| 334 | 
                        + (  | 
                    |
| 335 | 
                        + (rows) => Promise.resolve<Array<int>>(rows.map(row => row["id"]))  | 
                    |
| 336 | 
                        + )  | 
                    |
| 337 | 
                        + );  | 
                    |
| 86 | 338 | 
                        },  | 
                    
| 87 | 
                        - "search": function (part) : Promise<Array<type_row>>  | 
                    |
| 339 | 
                        + "export": function () : Promise<Array<type_row>>  | 
                    |
| 88 | 340 | 
                         		{
                       | 
                    
| 89 | 
                        -			return helpers.database.query_get_named("concept.dump", {"part": part.replace(new RegExp("-", "g"), "%")});
                       | 
                    |
| 341 | 
                        +			return helpers.database.query_get_named("concept.dump", {"part": null});
                       | 
                    |
| 90 | 342 | 
                        },  | 
                    
| 91 | 343 | 
                        };  | 
                    
| 92 | 344 | 
                         | 
                    
| ... | ... | 
                      @@ -0,0 +1,113 @@  | 
                  
| 1 | 
                        +namespace repositories  | 
                    |
| 2 | 
                        +{
                       | 
                    |
| 3 | 
                        +  | 
                    |
| 4 | 
                        + /**  | 
                    |
| 5 | 
                        + */  | 
                    |
| 6 | 
                        +	export var expression : helpers.repository_sqltable & {identify : (language_id : int, value : string)=>Promise<int>;} =
                       | 
                    |
| 7 | 
                        +	{
                       | 
                    |
| 8 | 
                        + "setup": function ()  | 
                    |
| 9 | 
                        +		{
                       | 
                    |
| 10 | 
                        +			return helpers.database.query_do_named("expression.setup");
                       | 
                    |
| 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 expressions(language_id, value) VALUES (:language_id, :value);",  | 
                    |
| 21 | 
                        +				{
                       | 
                    |
| 22 | 
                        + "language_id": row["language_id"],  | 
                    |
| 23 | 
                        + "value": row["value"],  | 
                    |
| 24 | 
                        + }  | 
                    |
| 25 | 
                        + );  | 
                    |
| 26 | 
                        + },  | 
                    |
| 27 | 
                        + "update": function (concept_expression_id, row)  | 
                    |
| 28 | 
                        +		{
                       | 
                    |
| 29 | 
                        + return helpers.database.query_do_free  | 
                    |
| 30 | 
                        + (  | 
                    |
| 31 | 
                        + "UPDATE expressions SET language_id = :language_id, value = :value WHERE (id = :id)",  | 
                    |
| 32 | 
                        +				{
                       | 
                    |
| 33 | 
                        + "id": concept_expression_id,  | 
                    |
| 34 | 
                        + "language_id": row["language_id"],  | 
                    |
| 35 | 
                        + "value": row["value"],  | 
                    |
| 36 | 
                        + }  | 
                    |
| 37 | 
                        + );  | 
                    |
| 38 | 
                        + },  | 
                    |
| 39 | 
                        + "delete": function (concept_expression_id)  | 
                    |
| 40 | 
                        +		{
                       | 
                    |
| 41 | 
                        + return helpers.database.query_do_free  | 
                    |
| 42 | 
                        + (  | 
                    |
| 43 | 
                        + "DELETE FROM expressions WHERE (id = :id)",  | 
                    |
| 44 | 
                        +				{
                       | 
                    |
| 45 | 
                        + "id": concept_expression_id,  | 
                    |
| 46 | 
                        + }  | 
                    |
| 47 | 
                        + );  | 
                    |
| 48 | 
                        + },  | 
                    |
| 49 | 
                        + "read": async function (concept_expression_id)  | 
                    |
| 50 | 
                        +		{
                       | 
                    |
| 51 | 
                        + return (  | 
                    |
| 52 | 
                        + helpers.database.query_get_free  | 
                    |
| 53 | 
                        + (  | 
                    |
| 54 | 
                        + "SELECT language_id,value FROM expressions WHERE (id = :id)",  | 
                    |
| 55 | 
                        +					{
                       | 
                    |
| 56 | 
                        + "id": concept_expression_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 expressions 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 language_id,value FROM expressions WHERE (" + column + " = :value)",
                       | 
                    |
| 84 | 
                        +				{
                       | 
                    |
| 85 | 
                        + "value": value,  | 
                    |
| 86 | 
                        + }  | 
                    |
| 87 | 
                        + );  | 
                    |
| 88 | 
                        + },  | 
                    |
| 89 | 
                        + "identify": function (language_id : int, value : string) : Promise<int>  | 
                    |
| 90 | 
                        +		{
                       | 
                    |
| 91 | 
                        + return (  | 
                    |
| 92 | 
                        + helpers.database.query_get_free  | 
                    |
| 93 | 
                        + (  | 
                    |
| 94 | 
                        + "SELECT id FROM expressions WHERE (language_id = :language_id) AND (value = :value);",  | 
                    |
| 95 | 
                        +					{
                       | 
                    |
| 96 | 
                        + "language_id": language_id,  | 
                    |
| 97 | 
                        + "value": value,  | 
                    |
| 98 | 
                        + }  | 
                    |
| 99 | 
                        + )  | 
                    |
| 100 | 
                        + .then  | 
                    |
| 101 | 
                        + (  | 
                    |
| 102 | 
                        + (rows) => (  | 
                    |
| 103 | 
                        + (rows.length === 1)  | 
                    |
| 104 | 
                        + ? Promise.resolve<int>(rows[0]["id"])  | 
                    |
| 105 | 
                        + : Promise.reject<int>()  | 
                    |
| 106 | 
                        + )  | 
                    |
| 107 | 
                        + )  | 
                    |
| 108 | 
                        + );  | 
                    |
| 109 | 
                        + },  | 
                    |
| 110 | 
                        + };  | 
                    |
| 111 | 
                        +  | 
                    |
| 112 | 
                        +}  | 
                    |
| 113 | 
                        +  | 
                    
| ... | ... | 
                      @@ -3,102 +3,209 @@ namespace services.concept  | 
                  
| 3 | 3 | 
                         | 
                    
| 4 | 4 | 
                        /**  | 
                    
| 5 | 5 | 
                        */  | 
                    
| 6 | 
                        - export function get  | 
                    |
| 7 | 
                        - (  | 
                    |
| 8 | 
                        - concept_id : int  | 
                    |
| 9 | 
                        - ) : Promise<entities.concept>  | 
                    |
| 6 | 
                        + export type type_bloated =  | 
                    |
| 7 | 
                        +	{
                       | 
                    |
| 8 | 
                        + id : int;  | 
                    |
| 9 | 
                        + description : string;  | 
                    |
| 10 | 
                        + type :  | 
                    |
| 11 | 
                        +		{
                       | 
                    |
| 12 | 
                        + id : int;  | 
                    |
| 13 | 
                        + value : string;  | 
                    |
| 14 | 
                        + };  | 
                    |
| 15 | 
                        + tags : Array<  | 
                    |
| 16 | 
                        +			{
                       | 
                    |
| 17 | 
                        + id : int;  | 
                    |
| 18 | 
                        + value : string;  | 
                    |
| 19 | 
                        + }  | 
                    |
| 20 | 
                        + >;  | 
                    |
| 21 | 
                        + expressions : Array<  | 
                    |
| 22 | 
                        +			{
                       | 
                    |
| 23 | 
                        + id : int;  | 
                    |
| 24 | 
                        + language :  | 
                    |
| 10 | 25 | 
                         				{
                       | 
                    
| 11 | 
                        - return repositories.concept.read(concept_id);  | 
                    |
| 26 | 
                        + id : int;  | 
                    |
| 27 | 
                        + value : string;  | 
                    |
| 28 | 
                        + };  | 
                    |
| 29 | 
                        + value : string;  | 
                    |
| 12 | 30 | 
                        }  | 
                    
| 31 | 
                        + >;  | 
                    |
| 32 | 
                        + };  | 
                    |
| 13 | 33 | 
                         | 
                    
| 14 | 34 | 
                         | 
                    
| 15 | 35 | 
                        /**  | 
                    
| 16 | 36 | 
                        */  | 
                    
| 17 | 
                        - export async function suck  | 
                    |
| 37 | 
                        + export type type_exposal =  | 
                    |
| 38 | 
                        +	{
                       | 
                    |
| 39 | 
                        + id : int;  | 
                    |
| 40 | 
                        + description : string;  | 
                    |
| 41 | 
                        + type : string;  | 
                    |
| 42 | 
                        + tags : Array<string>;  | 
                    |
| 43 | 
                        +		expressions : {[language : string] : Array<string>};
                       | 
                    |
| 44 | 
                        + };  | 
                    |
| 45 | 
                        +  | 
                    |
| 46 | 
                        +  | 
                    |
| 47 | 
                        + /**  | 
                    |
| 48 | 
                        + */  | 
                    |
| 49 | 
                        + function parse_tags(  | 
                    |
| 50 | 
                        + tags_raw : string  | 
                    |
| 51 | 
                        + ) : Array<string>  | 
                    |
| 52 | 
                        +	{
                       | 
                    |
| 53 | 
                        + return (  | 
                    |
| 54 | 
                        + (tags_raw === null)  | 
                    |
| 55 | 
                        + ? []  | 
                    |
| 56 | 
                        +			: tags_raw.split(",")
                       | 
                    |
| 57 | 
                        + );  | 
                    |
| 58 | 
                        + }  | 
                    |
| 59 | 
                        +  | 
                    |
| 60 | 
                        +  | 
                    |
| 61 | 
                        + /**  | 
                    |
| 62 | 
                        + */  | 
                    |
| 63 | 
                        + function parse_expressions  | 
                    |
| 18 | 64 | 
                        (  | 
                    
| 19 | 
                        - concept_thing : any  | 
                    |
| 20 | 
                        - ) : Promise<int>  | 
                    |
| 65 | 
                        + expressions_raw : string  | 
                    |
| 66 | 
                        +	) : {[language : string] : Array<string>}
                       | 
                    |
| 21 | 67 | 
                         	{
                       | 
                    
| 22 | 
                        - const type_id : int = await services.type.give(concept_thing["type"]);  | 
                    |
| 23 | 
                        - const concept_id : int = await repositories.concept_core.create  | 
                    |
| 68 | 
                        +		let result : {[language : string] : Array<string>} = {};
                       | 
                    |
| 69 | 
                        +		const parts : Array<string> = expressions_raw.split(",");
                       | 
                    |
| 70 | 
                        + parts.forEach  | 
                    |
| 24 | 71 | 
                        (  | 
                    
| 72 | 
                        + (part) =>  | 
                    |
| 25 | 73 | 
                         			{
                       | 
                    
| 26 | 
                        - "type_id": type_id,  | 
                    |
| 27 | 
                        - "description": concept_thing["description"],  | 
                    |
| 74 | 
                        +				const [language, value] : Array<string> = part.split(":", 2);
                       | 
                    |
| 75 | 
                        + if (! result.hasOwnProperty(language)) result[language] = [];  | 
                    |
| 76 | 
                        + result[language].push(value);  | 
                    |
| 28 | 77 | 
                        }  | 
                    
| 29 | 78 | 
                        );  | 
                    
| 30 | 
                        - await concept_thing["tags"].map  | 
                    |
| 79 | 
                        + return result;  | 
                    |
| 80 | 
                        + }  | 
                    |
| 81 | 
                        +  | 
                    |
| 82 | 
                        +  | 
                    |
| 83 | 
                        + /**  | 
                    |
| 84 | 
                        + */  | 
                    |
| 85 | 
                        + export async function bloat  | 
                    |
| 31 | 86 | 
                        (  | 
                    
| 32 | 
                        - async (tag_value) =>  | 
                    |
| 87 | 
                        + concept_id : int  | 
                    |
| 88 | 
                        + ) : Promise<type_bloated>  | 
                    |
| 33 | 89 | 
                         	{
                       | 
                    
| 34 | 
                        - const tag_id : int = await services.tag.give(tag_value);  | 
                    |
| 35 | 
                        - const concept_tag_id : int = await repositories.concept_tags.create  | 
                    |
| 90 | 
                        + const concept_entity : entities.concept = await repositories.concept.read(concept_id);  | 
                    |
| 91 | 
                        + const type_value : string = (await repositories.type.read(concept_entity.type_id))["value"];  | 
                    |
| 92 | 
                        + let result : type_bloated =  | 
                    |
| 93 | 
                        +		{
                       | 
                    |
| 94 | 
                        + "id": concept_id,  | 
                    |
| 95 | 
                        + "description": concept_entity.description,  | 
                    |
| 96 | 
                        + "type":  | 
                    |
| 97 | 
                        +			{
                       | 
                    |
| 98 | 
                        + "id": concept_entity.type_id,  | 
                    |
| 99 | 
                        + "value": type_value,  | 
                    |
| 100 | 
                        + },  | 
                    |
| 101 | 
                        + "tags": [],  | 
                    |
| 102 | 
                        + "expressions": [],  | 
                    |
| 103 | 
                        + };  | 
                    |
| 104 | 
                        + for await (const tag_id of concept_entity.tags)  | 
                    |
| 105 | 
                        +		{
                       | 
                    |
| 106 | 
                        + const tag_value : string = (await repositories.tag.read(tag_id))["value"];  | 
                    |
| 107 | 
                        +			result.tags.push({"id": tag_id, "value": tag_value});
                       | 
                    |
| 108 | 
                        + }  | 
                    |
| 109 | 
                        + for await (const expression_id of concept_entity.expressions)  | 
                    |
| 110 | 
                        +		{
                       | 
                    |
| 111 | 
                        + const expression_row : type_row = await repositories.expression.read(expression_id);  | 
                    |
| 112 | 
                        + const language_id : int = expression_row["language_id"];  | 
                    |
| 113 | 
                        + const language_row : type_row = (await repositories.language.read(expression_row["language_id"]));  | 
                    |
| 114 | 
                        + result.expressions.push  | 
                    |
| 36 | 115 | 
                        (  | 
                    
| 37 | 116 | 
                         				{
                       | 
                    
| 38 | 
                        - "concept_id": concept_id,  | 
                    |
| 39 | 
                        - "tag_id": tag_id,  | 
                    |
| 117 | 
                        + "id": expression_id,  | 
                    |
| 118 | 
                        + "language":  | 
                    |
| 119 | 
                        +					{
                       | 
                    |
| 120 | 
                        + "id": language_id,  | 
                    |
| 121 | 
                        + "value": language_row["value"]  | 
                    |
| 122 | 
                        + },  | 
                    |
| 123 | 
                        + "value": expression_row["value"]  | 
                    |
| 40 | 124 | 
                        }  | 
                    
| 41 | 125 | 
                        );  | 
                    
| 42 | 
                        - return concept_tag_id;  | 
                    |
| 43 | 126 | 
                        }  | 
                    
| 44 | 
                        - );  | 
                    |
| 45 | 
                        - await Object.keys(concept_thing["translations"]).map  | 
                    |
| 127 | 
                        + return Promise.resolve<type_bloated>(result);  | 
                    |
| 128 | 
                        + }  | 
                    |
| 129 | 
                        +  | 
                    |
| 130 | 
                        +  | 
                    |
| 131 | 
                        + /**  | 
                    |
| 132 | 
                        + */  | 
                    |
| 133 | 
                        + export async function expose  | 
                    |
| 46 | 134 | 
                        (  | 
                    
| 47 | 
                        - async (language_value) =>  | 
                    |
| 135 | 
                        + concept_id : int  | 
                    |
| 136 | 
                        + ) : Promise<type_exposal>  | 
                    |
| 48 | 137 | 
                         	{
                       | 
                    
| 49 | 
                        - const language_id : int = await services.language.give(language_value);  | 
                    |
| 50 | 
                        - const concept_translation_ids = await concept_thing["translations"][language_value].map  | 
                    |
| 138 | 
                        + const bloated : type_bloated = await bloat(concept_id);  | 
                    |
| 139 | 
                        + return Promise.resolve<type_exposal>  | 
                    |
| 51 | 140 | 
                        (  | 
                    
| 52 | 
                        - async (translation_value) =>  | 
                    |
| 53 | 141 | 
                         			{
                       | 
                    
| 54 | 
                        - const concept_translation_id : int = await repositories.concept_translations.create  | 
                    |
| 142 | 
                        + "id": bloated.id,  | 
                    |
| 143 | 
                        + "description": bloated.description,  | 
                    |
| 144 | 
                        + "type": bloated.type.value,  | 
                    |
| 145 | 
                        + "tags": bloated.tags.map(tag_entry => tag_entry.value),  | 
                    |
| 146 | 
                        + "expressions": (  | 
                    |
| 147 | 
                        + () =>  | 
                    |
| 148 | 
                        +					{
                       | 
                    |
| 149 | 
                        +						let expressions : {[language : string] : Array<string>} = {};
                       | 
                    |
| 150 | 
                        + bloated.expressions.forEach  | 
                    |
| 55 | 151 | 
                        (  | 
                    
| 152 | 
                        + expression_entry =>  | 
                    |
| 56 | 153 | 
                         							{
                       | 
                    
| 57 | 
                        - "concept_id": concept_id,  | 
                    |
| 58 | 
                        - "language_id": language_id,  | 
                    |
| 59 | 
                        - "value": translation_value,  | 
                    |
| 154 | 
                        + const language : string = expression_entry.language.value;  | 
                    |
| 155 | 
                        + if (! expressions.hasOwnProperty(language))  | 
                    |
| 156 | 
                        +								{
                       | 
                    |
| 157 | 
                        + expressions[language] = [];  | 
                    |
| 60 | 158 | 
                        }  | 
                    
| 61 | 
                        - );  | 
                    |
| 159 | 
                        + expressions[language].push(expression_entry.value);  | 
                    |
| 62 | 160 | 
                        }  | 
                    
| 63 | 161 | 
                        );  | 
                    
| 162 | 
                        + return expressions;  | 
                    |
| 163 | 
                        + }  | 
                    |
| 164 | 
                        + ) (),  | 
                    |
| 64 | 165 | 
                        }  | 
                    
| 65 | 166 | 
                        );  | 
                    
| 66 | 
                        - return concept_id;  | 
                    |
| 67 | 167 | 
                        }  | 
                    
| 68 | 168 | 
                         | 
                    
| 69 | 169 | 
                         | 
                    
| 70 | 170 | 
                        /**  | 
                    
| 71 | 171 | 
                        */  | 
                    
| 72 | 
                        - function parse_tags(  | 
                    |
| 73 | 
                        - tags_raw : string  | 
                    |
| 74 | 
                        - ) : Array<string>  | 
                    |
| 172 | 
                        + export async function export_  | 
                    |
| 173 | 
                        + (  | 
                    |
| 174 | 
                        + ) : Promise<Array<type_exposal>>  | 
                    |
| 75 | 175 | 
                         	{
                       | 
                    
| 76 | 
                        - return (  | 
                    |
| 77 | 
                        - (tags_raw === null)  | 
                    |
| 78 | 
                        - ? []  | 
                    |
| 79 | 
                        -			: tags_raw.split(",")
                       | 
                    |
| 176 | 
                        + const rows : Array<type_row> = await repositories.concept.export();  | 
                    |
| 177 | 
                        + return Promise.resolve<Array<type_exposal>>  | 
                    |
| 178 | 
                        + (  | 
                    |
| 179 | 
                        + rows.map  | 
                    |
| 180 | 
                        + (  | 
                    |
| 181 | 
                        + (row) => (  | 
                    |
| 182 | 
                        +					{
                       | 
                    |
| 183 | 
                        + "id": row["id"],  | 
                    |
| 184 | 
                        + "type": row["type"],  | 
                    |
| 185 | 
                        + "description": row["description"],  | 
                    |
| 186 | 
                        + "tags": parse_tags(row["tags"]),  | 
                    |
| 187 | 
                        + "expressions": parse_expressions(row["expressions"]),  | 
                    |
| 188 | 
                        + }  | 
                    |
| 189 | 
                        + )  | 
                    |
| 190 | 
                        + )  | 
                    |
| 80 | 191 | 
                        );  | 
                    
| 81 | 192 | 
                        }  | 
                    
| 82 | 193 | 
                         | 
                    
| 83 | 194 | 
                         | 
                    
| 84 | 195 | 
                        /**  | 
                    
| 85 | 196 | 
                        */  | 
                    
| 86 | 
                        - function parse_translations  | 
                    |
| 197 | 
                        + export async function search  | 
                    |
| 87 | 198 | 
                        (  | 
                    
| 88 | 
                        - translations_raw : string  | 
                    |
| 89 | 
                        -	) : Array<{id : int; language : string; value : string;}>
                       | 
                    |
| 199 | 
                        + part : string  | 
                    |
| 200 | 
                        + ) : Promise<Array<type_exposal>>  | 
                    |
| 90 | 201 | 
                         	{
                       | 
                    
| 91 | 
                        -		let result : Array<{id : int; language : string; value : string;}> = [];
                       | 
                    |
| 92 | 
                        -		const parts : Array<string> = translations_raw.split(",")
                       | 
                    |
| 93 | 
                        - parts.forEach  | 
                    |
| 94 | 
                        - (  | 
                    |
| 95 | 
                        - (part) =>  | 
                    |
| 202 | 
                        + const concept_ids : Array<int> = await repositories.concept.search(part);  | 
                    |
| 203 | 
                        + let result : Array<type_exposal> = [];  | 
                    |
| 204 | 
                        + for await (const concept_id of concept_ids)  | 
                    |
| 96 | 205 | 
                         		{
                       | 
                    
| 97 | 
                        -				const [id, language, value] : Array<string> = part.split(":", 3);
                       | 
                    |
| 98 | 
                        -				result.push({"id": parseInt(id), "language": language, "value": value});
                       | 
                    |
| 206 | 
                        + result.push(await expose(concept_id));  | 
                    |
| 99 | 207 | 
                        }  | 
                    
| 100 | 
                        - );  | 
                    |
| 101 | 
                        - return result;  | 
                    |
| 208 | 
                        + return Promise.resolve<Array<type_exposal>>(result);  | 
                    |
| 102 | 209 | 
                        }  | 
                    
| 103 | 210 | 
                         | 
                    
| 104 | 211 | 
                         | 
                    
| ... | ... | 
                      @@ -122,62 +229,46 @@ namespace services.concept  | 
                  
| 122 | 229 | 
                         | 
                    
| 123 | 230 | 
                        /**  | 
                    
| 124 | 231 | 
                        */  | 
                    
| 125 | 
                        - export async function export_  | 
                    |
| 232 | 
                        + export async function suck  | 
                    |
| 126 | 233 | 
                        (  | 
                    
| 127 | 
                        -	) : Promise<Array<{id : int; type : string; description : string; tags : Array<string>; translations : Array<{id : int; language : string; value : string;}>;}>>
                       | 
                    |
| 234 | 
                        + concept_thing : any  | 
                    |
| 235 | 
                        + ) : Promise<int>  | 
                    |
| 128 | 236 | 
                         	{
                       | 
                    
| 129 | 
                        - return (  | 
                    |
| 130 | 
                        - repositories.concept.export()  | 
                    |
| 131 | 
                        - .then  | 
                    |
| 132 | 
                        - (  | 
                    |
| 133 | 
                        - rows => Promise.resolve  | 
                    |
| 237 | 
                        + const type_id : int = await services.type.give(concept_thing["type"]);  | 
                    |
| 238 | 
                        + const concept_id : int = await repositories.concept_core.create  | 
                    |
| 134 | 239 | 
                        (  | 
                    
| 135 | 
                        - rows.map  | 
                    |
| 240 | 
                        +			{
                       | 
                    |
| 241 | 
                        + "type_id": type_id,  | 
                    |
| 242 | 
                        + "description": concept_thing["description"],  | 
                    |
| 243 | 
                        + }  | 
                    |
| 244 | 
                        + );  | 
                    |
| 245 | 
                        + for await (const tag_value of concept_thing["tags"])  | 
                    |
| 246 | 
                        +		{
                       | 
                    |
| 247 | 
                        + const tag_id : int = await services.tag.give(tag_value);  | 
                    |
| 248 | 
                        + const concept_tag_id : int = await repositories.concept_tags.create  | 
                    |
| 136 | 249 | 
                        (  | 
                    
| 137 | 
                        - (row) => (  | 
                    |
| 138 | 250 | 
                         				{
                       | 
                    
| 139 | 
                        - "id": row["id"],  | 
                    |
| 140 | 
                        - "type": row["type"],  | 
                    |
| 141 | 
                        - "description": row["description"],  | 
                    |
| 142 | 
                        - "tags": parse_tags(row["tags"]),  | 
                    |
| 143 | 
                        - "translations": parse_translations(row["translations"]),  | 
                    |
| 251 | 
                        + "concept_id": concept_id,  | 
                    |
| 252 | 
                        + "tag_id": tag_id,  | 
                    |
| 144 | 253 | 
                        }  | 
                    
| 145 | 
                        - )  | 
                    |
| 146 | 
                        - )  | 
                    |
| 147 | 
                        - )  | 
                    |
| 148 | 
                        - )  | 
                    |
| 149 | 
                        - )  | 
                    |
| 254 | 
                        + );  | 
                    |
| 150 | 255 | 
                        }  | 
                    
| 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;}>;}>>
                       | 
                    |
| 256 | 
                        + for await (const [language_value, expression_values] of Object.entries(concept_thing["expressions"]))  | 
                    |
| 159 | 257 | 
                         		{
                       | 
                    
| 160 | 
                        - return (  | 
                    |
| 161 | 
                        - repositories.concept.search(part)  | 
                    |
| 162 | 
                        - .then  | 
                    |
| 163 | 
                        - (  | 
                    |
| 164 | 
                        - rows => Promise.resolve  | 
                    |
| 165 | 
                        - (  | 
                    |
| 166 | 
                        - rows.map  | 
                    |
| 258 | 
                        + const language_id : int = await services.language.give(language_value);  | 
                    |
| 259 | 
                        + for await (const expression_value of <Array<string>>(expression_values))  | 
                    |
| 260 | 
                        +			{
                       | 
                    |
| 261 | 
                        + const expression_id : int = await services.expression.give(language_id, expression_value);  | 
                    |
| 262 | 
                        + const concept_expression_id : int = await repositories.concept_expressions.create  | 
                    |
| 167 | 263 | 
                        (  | 
                    
| 168 | 
                        - (row) => (  | 
                    |
| 169 | 264 | 
                         					{
                       | 
                    
| 170 | 
                        - "id": row["id"],  | 
                    |
| 171 | 
                        - "type": row["type"],  | 
                    |
| 172 | 
                        - "description": row["description"],  | 
                    |
| 173 | 
                        - "tags": parse_tags(row["tags"]),  | 
                    |
| 174 | 
                        - "translations": parse_translations(row["translations"]),  | 
                    |
| 265 | 
                        + "concept_id": concept_id,  | 
                    |
| 266 | 
                        + "expression_id": expression_id,  | 
                    |
| 175 | 267 | 
                        }  | 
                    
| 176 | 
                        - )  | 
                    |
| 177 | 
                        - )  | 
                    |
| 178 | 
                        - )  | 
                    |
| 179 | 
                        - )  | 
                    |
| 180 | 
                        - )  | 
                    |
| 268 | 
                        + );  | 
                    |
| 269 | 
                        + }  | 
                    |
| 270 | 
                        + }  | 
                    |
| 271 | 
                        + return concept_id;  | 
                    |
| 181 | 272 | 
                        }  | 
                    
| 182 | 273 | 
                         | 
                    
| 183 | 274 | 
                        }  | 
                    
| ... | ... | 
                      @@ -0,0 +1,13 @@  | 
                  
| 1 | 
                        +namespace services.expression  | 
                    |
| 2 | 
                        +{
                       | 
                    |
| 3 | 
                        +  | 
                    |
| 4 | 
                        + export function give(language_id : int, value : string) : Promise<int>  | 
                    |
| 5 | 
                        +	{
                       | 
                    |
| 6 | 
                        + return (  | 
                    |
| 7 | 
                        + repositories.expression.identify(language_id, value)  | 
                    |
| 8 | 
                        +			.catch(() => repositories.expression.create({"language_id": language_id, "value": value}))
                       | 
                    |
| 9 | 
                        + );  | 
                    |
| 10 | 
                        + }  | 
                    |
| 11 | 
                        +  | 
                    |
| 12 | 
                        +}  | 
                    |
| 13 | 
                        +  | 
                    
| ... | ... | 
                      @@ -3,7 +3,10 @@ namespace services.language  | 
                  
| 3 | 3 | 
                         | 
                    
| 4 | 4 | 
                        export function give(value : string) : Promise<int>  | 
                    
| 5 | 5 | 
                         	{
                       | 
                    
| 6 | 
                        -		return (repositories.language.identify(value).catch(() => repositories.language.create({"value": value})))
                       | 
                    |
| 6 | 
                        + return (  | 
                    |
| 7 | 
                        + repositories.language.identify(value)  | 
                    |
| 8 | 
                        +			.catch(() => repositories.language.create({"value": value}))
                       | 
                    |
| 9 | 
                        + );  | 
                    |
| 7 | 10 | 
                        }  | 
                    
| 8 | 11 | 
                         | 
                    
| 9 | 12 | 
                        }  | 
                    
| ... | ... | 
                      @@ -3,7 +3,10 @@ namespace services.tag  | 
                  
| 3 | 3 | 
                         | 
                    
| 4 | 4 | 
                        export function give(value : string) : Promise<int>  | 
                    
| 5 | 5 | 
                         	{
                       | 
                    
| 6 | 
                        -		return (repositories.tag.identify(value).catch(() => repositories.tag.create({"value": value})))
                       | 
                    |
| 6 | 
                        + return (  | 
                    |
| 7 | 
                        + repositories.tag.identify(value)  | 
                    |
| 8 | 
                        +			.catch(() => repositories.tag.create({"value": value}))
                       | 
                    |
| 9 | 
                        + );  | 
                    |
| 7 | 10 | 
                        }  | 
                    
| 8 | 11 | 
                         | 
                    
| 9 | 12 | 
                        }  | 
                    
| ... | ... | 
                      @@ -3,7 +3,10 @@ namespace services.type  | 
                  
| 3 | 3 | 
                         | 
                    
| 4 | 4 | 
                        export function give(value : string) : Promise<int>  | 
                    
| 5 | 5 | 
                         	{
                       | 
                    
| 6 | 
                        -		return (repositories.type.identify(value).catch(() => repositories.type.create({"value": value})))
                       | 
                    |
| 6 | 
                        + return (  | 
                    |
| 7 | 
                        + repositories.type.identify(value)  | 
                    |
| 8 | 
                        +			.catch(() => repositories.type.create({"value": value}))
                       | 
                    |
| 9 | 
                        + );  | 
                    |
| 7 | 10 | 
                        }  | 
                    
| 8 | 11 | 
                         | 
                    
| 9 | 12 | 
                        }  | 
                    
| ... | ... | 
                      @@ -3,14 +3,15 @@ SELECT  | 
                  
| 3 | 3 | 
                        MIN(x2.value) AS type,  | 
                    
| 4 | 4 | 
                        MIN(x1.description) AS description,  | 
                    
| 5 | 5 | 
                        GROUP_CONCAT(DISTINCT x4.value) AS tags,  | 
                    
| 6 | 
                        - GROUP_CONCAT(x5.id || ':' || x6.value || ':' || x5.value) AS translations  | 
                    |
| 6 | 
                        + GROUP_CONCAT(x7.value || ':' || x6.value) AS expressions  | 
                    |
| 7 | 7 | 
                        FROM  | 
                    
| 8 | 8 | 
                        concepts AS x1  | 
                    
| 9 | 9 | 
                        LEFT OUTER JOIN types AS x2 ON (x1.type_id = x2.id)  | 
                    
| 10 | 10 | 
                        LEFT OUTER JOIN concept_tags AS x3 ON (x1.id = x3.concept_id)  | 
                    
| 11 | 11 | 
                        LEFT OUTER JOIN tags AS x4 ON (x3.tag_id = x4.id)  | 
                    
| 12 | 
                        - LEFT OUTER JOIN concept_translations AS x5 ON (x1.id = x5.concept_id)  | 
                    |
| 13 | 
                        - LEFT OUTER JOIN languages AS x6 ON (x5.language_id = x6.id)  | 
                    |
| 12 | 
                        + LEFT OUTER JOIN concept_expressions AS x5 ON (x1.id = x5.concept_id)  | 
                    |
| 13 | 
                        + LEFT OUTER JOIN expressions AS x6 ON (x5.expression_id = x6.id)  | 
                    |
| 14 | 
                        + LEFT OUTER JOIN languages AS x7 ON (x5.language_id = x7.id)  | 
                    |
| 14 | 15 | 
                        WHERE  | 
                    
| 15 | 16 | 
                        (  | 
                    
| 16 | 17 | 
                        (:part IS NULL)  | 
                    
| ... | ... | 
                      @@ -1,29 +1,30 @@  | 
                  
| 1 | 1 | 
                        SELECT  | 
                    
| 2 | 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  | 
                    |
| 3 | 
                        + x3.value AS language_from,  | 
                    |
| 4 | 
                        + x2.value AS value_from,  | 
                    |
| 5 | 
                        + y3.value AS language_to,  | 
                    |
| 6 | 
                        + y2.value AS value_to  | 
                    |
| 7 | 7 | 
                        FROM  | 
                    
| 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)  | 
                    |
| 8 | 
                        + concept_expressions AS x1 INNER JOIN concept_expressions AS y1 ON ((x1.id <> y1.id) AND (x1.concept_id = y1.concept_id))  | 
                    |
| 9 | 
                        + LEFT OUTER JOIN expressions AS x2 ON (x1.expression_id = x2.id)  | 
                    |
| 10 | 
                        + LEFT OUTER JOIN languages AS x3 ON (x2.language_id = x3.id)  | 
                    |
| 11 | 
                        + LEFT OUTER JOIN expressions AS y2 ON (y1.expression_id = y2.id)  | 
                    |
| 12 | 
                        + LEFT OUTER JOIN languages AS y3 ON (y2.language_id = y3.id)  | 
                    |
| 12 | 13 | 
                        WHERE  | 
                    
| 13 | 14 | 
                        (  | 
                    
| 14 | 15 | 
                        (  | 
                    
| 15 | 16 | 
                        (:language_from = '_')  | 
                    
| 16 | 17 | 
                        OR  | 
                    
| 17 | 
                        - (x2.value = :language_from)  | 
                    |
| 18 | 
                        + (x3.value = :language_from)  | 
                    |
| 18 | 19 | 
                        )  | 
                    
| 19 | 20 | 
                        AND  | 
                    
| 20 | 21 | 
                        (  | 
                    
| 21 | 22 | 
                        (:language_to = '_')  | 
                    
| 22 | 23 | 
                        OR  | 
                    
| 23 | 
                        - (y2.value = :language_to)  | 
                    |
| 24 | 
                        + (y3.value = :language_to)  | 
                    |
| 24 | 25 | 
                        )  | 
                    
| 25 | 26 | 
                        AND  | 
                    
| 26 | 
                        - (x1.value LIKE :part)  | 
                    |
| 27 | 
                        + (x2.value LIKE :part)  | 
                    |
| 27 | 28 | 
                        )  | 
                    
| 28 | 29 | 
                        ;  | 
                    
| 29 | 30 | 
                         | 
                    
| ... | ... | 
                      @@ -0,0 +1,20 @@  | 
                  
| 1 | 
                        +SELECT  | 
                    |
| 2 | 
                        + x1.id  | 
                    |
| 3 | 
                        +FROM  | 
                    |
| 4 | 
                        + concepts AS x1  | 
                    |
| 5 | 
                        + LEFT OUTER JOIN types AS x2 ON (x1.type_id = x2.id)  | 
                    |
| 6 | 
                        + LEFT OUTER JOIN concept_tags AS x3 ON (x1.id = x3.concept_id)  | 
                    |
| 7 | 
                        + LEFT OUTER JOIN tags AS x4 ON (x3.tag_id = x4.id)  | 
                    |
| 8 | 
                        + LEFT OUTER JOIN concept_expressions AS x5 ON (x1.id = x5.concept_id)  | 
                    |
| 9 | 
                        + LEFT OUTER JOIN expressions AS x6 ON (x5.expression_id = x6.id)  | 
                    |
| 10 | 
                        + LEFT OUTER JOIN languages AS x7 ON (x6.language_id = x7.id)  | 
                    |
| 11 | 
                        +WHERE  | 
                    |
| 12 | 
                        + (  | 
                    |
| 13 | 
                        + (:part IS NULL)  | 
                    |
| 14 | 
                        + OR  | 
                    |
| 15 | 
                        + (x6.value LIKE :part)  | 
                    |
| 16 | 
                        + )  | 
                    |
| 17 | 
                        +GROUP BY  | 
                    |
| 18 | 
                        + x1.id  | 
                    |
| 19 | 
                        +;  | 
                    |
| 20 | 
                        +  | 
                    
| ... | ... | 
                      @@ -1,5 +1,5 @@  | 
                  
| 1 | 1 | 
                        CREATE TABLE IF NOT EXISTS  | 
                    
| 2 | 
                        - `concept_translations`(  | 
                    |
| 2 | 
                        + `concept_expressions`(  | 
                    |
| 3 | 3 | 
                        `id`  | 
                    
| 4 | 4 | 
                        INTEGER  | 
                    
| 5 | 5 | 
                        PRIMARY KEY  | 
                    
| ... | ... | 
                      @@ -9,20 +9,16 @@ CREATE TABLE IF NOT EXISTS  | 
                  
| 9 | 9 | 
                        INTEGER  | 
                    
| 10 | 10 | 
                        NOT NULL  | 
                    
| 11 | 11 | 
                        ,  | 
                    
| 12 | 
                        - `language_id`  | 
                    |
| 12 | 
                        + `expression_id`  | 
                    |
| 13 | 13 | 
                        INTEGER  | 
                    
| 14 | 14 | 
                        NOT NULL  | 
                    
| 15 | 15 | 
                        ,  | 
                    
| 16 | 
                        - `value`  | 
                    |
| 17 | 
                        - TEXT  | 
                    |
| 18 | 
                        - NOT NULL  | 
                    |
| 19 | 
                        - ,  | 
                    |
| 20 | 
                        - FOREIGN KEY  | 
                    |
| 21 | 
                        - (`language_id`)  | 
                    |
| 22 | 
                        - REFERENCES `languages`(`id`)  | 
                    |
| 23 | 
                        - ,  | 
                    |
| 24 | 16 | 
                        FOREIGN KEY  | 
                    
| 25 | 17 | 
                        (`concept_id`)  | 
                    
| 26 | 18 | 
                        REFERENCES `concepts`(`id`)  | 
                    
| 19 | 
                        + ,  | 
                    |
| 20 | 
                        + FOREIGN KEY  | 
                    |
| 21 | 
                        + (`expression_id`)  | 
                    |
| 22 | 
                        + REFERENCES `expression`(`id`)  | 
                    |
| 27 | 23 | 
                        )  | 
                    
| 28 | 24 | 
                        ;  | 
                    
| ... | ... | 
                      @@ -0,0 +1,20 @@  | 
                  
| 1 | 
                        +CREATE TABLE IF NOT EXISTS  | 
                    |
| 2 | 
                        + `expressions`(  | 
                    |
| 3 | 
                        + `id`  | 
                    |
| 4 | 
                        + INTEGER  | 
                    |
| 5 | 
                        + PRIMARY KEY  | 
                    |
| 6 | 
                        + AUTOINCREMENT  | 
                    |
| 7 | 
                        + ,  | 
                    |
| 8 | 
                        + `language_id`  | 
                    |
| 9 | 
                        + INTEGER  | 
                    |
| 10 | 
                        + NOT NULL  | 
                    |
| 11 | 
                        + ,  | 
                    |
| 12 | 
                        + `value`  | 
                    |
| 13 | 
                        + TEXT  | 
                    |
| 14 | 
                        + NOT NULL  | 
                    |
| 15 | 
                        + ,  | 
                    |
| 16 | 
                        + FOREIGN KEY  | 
                    |
| 17 | 
                        + (`language_id`)  | 
                    |
| 18 | 
                        + REFERENCES `languages`(`id`)  | 
                    |
| 19 | 
                        + )  | 
                    |
| 20 | 
                        +;  | 
                    
| ... | ... | 
                      @@ -32,13 +32,12 @@ ${dir_build}/manage: \
                     | 
                  
| 32 | 32 | 
                         	${dir_source}/repositories/language.ts \
                       | 
                    
| 33 | 33 | 
                         	${dir_source}/repositories/type.ts \
                       | 
                    
| 34 | 34 | 
                         	${dir_source}/repositories/tag.ts \
                       | 
                    
| 35 | 
                        -	${dir_source}/repositories/concept-core.ts \
                       | 
                    |
| 36 | 
                        -	${dir_source}/repositories/concept-tags.ts \
                       | 
                    |
| 37 | 
                        -	${dir_source}/repositories/concept-translations.ts \
                       | 
                    |
| 35 | 
                        +	${dir_source}/repositories/expression.ts \
                       | 
                    |
| 38 | 36 | 
                         	${dir_source}/repositories/concept.ts \
                       | 
                    
| 39 | 37 | 
                         	${dir_source}/services/language.ts \
                       | 
                    
| 40 | 38 | 
                         	${dir_source}/services/type.ts \
                       | 
                    
| 41 | 39 | 
                         	${dir_source}/services/tag.ts \
                       | 
                    
| 40 | 
                        +	${dir_source}/services/expression.ts \
                       | 
                    |
| 42 | 41 | 
                         	${dir_source}/services/concept.ts \
                       | 
                    
| 43 | 42 | 
                         	${dir_source}/main.ts
                       | 
                    
| 44 | 43 | 
                         	@ ${cmd_dir_make} ${dir_build}
                       | 
                    
| 45 | 44 |