diff --git a/.gitignore b/.gitignore
new file mode 100755
index 0000000..69a66f6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+Data
+Public/data
+CSV2SQL.apache2.conf
diff --git a/Artbook/logo.svg b/Artbook/logo.svg
new file mode 100755
index 0000000..774f308
--- /dev/null
+++ b/Artbook/logo.svg
@@ -0,0 +1,94 @@
+
+
diff --git a/Artbook/logo.xcf b/Artbook/logo.xcf
new file mode 100755
index 0000000..874cb22
Binary files /dev/null and b/Artbook/logo.xcf differ
diff --git a/PHP/CSV2SQL.Secrets.php b/PHP/CSV2SQL.Secrets.php
new file mode 100755
index 0000000..0911a93
--- /dev/null
+++ b/PHP/CSV2SQL.Secrets.php
@@ -0,0 +1,10 @@
+ {};
+
+ this.start = callback => {
+
+ const end = status => csv2sql.is_function(callback) && callback(status);
+
+ if(started){
+ end(false);
+ return false;
+ };
+ started = true;
+
+ tab = csv2sql.settings_get(["mysql_tabulation", "tabulation"]);
+
+ self.add_reserved_words(csv2sql.settings_get("default_mysql_reserved_words"), () => {
+ self.add_reserved_words(csv2sql.settings_get("mysql_reserved_words"), () => {
+ end(true);
+ });
+ });
+
+ return true;
+ };
+
+ this.add_reserved_words = (inputs, callback) => {
+
+ let loaded = 0;
+ const total = (csv2sql.is_array(inputs) ? inputs : csv2sql.is_string(inputs) ? inputs = [inputs] : inputs = []).length,
+ end = () => ++ loaded == total && csv2sql.is_function(callback) && callback();
+
+ if(total){
+ for(let i = 0; i < total; i ++){
+ if(csv2sql.is_array(inputs[i]))
+ self.add_reserved_words(inputs[i], end);
+ else if(csv2sql.is_string(inputs[i]) && inputs[i]){
+ if(['[', '{'].includes(inputs[i].trim()[0])){
+ try{
+ self.add_reserved_words(csv2sql.json_decode(inputs[i]), end);
+ }catch(exception){
+ end();
+ };
+ continue;
+ };
+ if(/^[a-z0-9_]+$/.test(inputs[i])){
+ !reserved_words.includes(inputs[i]) && reserved_words.push(inputs[i]);
+ end();
+ continue;
+ };
+ csv2sql.ajax.get(inputs[i], response => {
+ try{
+ self.add_reserved_words(csv2sql.json_decode(response), end);
+ }catch(exception){
+ end();
+ };
+ });
+ }else
+ end();
+ };
+ }else{
+ loaded --;
+ end();
+ };
+
+ };
+
+ const word = this.word = name => reserved_words.includes(name) ? "`" + name + "`" : name;
+
+ this.database_creator = name => (
+ "create database if not exists " + word(name) + " character set utf8mb4 collate utf8mb4_general_ci;\n" +
+ "use " + word(name) + ";"
+ );
+
+ this.table_remover = data => tab + tab + "drop table if exists " + word(data.table) + ";";
+
+ const attributes = attribute => (
+ attribute.type == "varchar" ? attribute.length[0] == attribute.length[1] ? "char" : "varchar" :
+ attribute.type
+ ) + (
+ attribute.type == "varchar" ? "(" + attribute.length[1] + ")" :
+ ""
+ ) + (attribute.null ? "" : " not null");
+
+ this.table_creator = data => {
+
+ let sql = "";
+
+ data.id_attribute && (sql += "\n" + tab + tab + tab + "id integer not null auto_increment");
+
+ data.order.forEach(key => {
+
+ const attribute = data.attributes[key];
+
+ sql += (sql ? "," : "") + "\n" + tab + tab + tab + word(key) + " " + attributes(attribute);
+
+ });
+
+ data.deleted_attribute && (sql += ",\n" + tab + tab + tab + "deleted datetime");
+ data.date_in_attribute && (sql += ",\n" + tab + tab + tab + "date_in datetime not null default now()");
+ data.date_out_attribute && (sql += ",\n" + tab + tab + tab + "date_out datetime");
+
+ data.id_attribute && (sql += ",\n" + tab + tab + tab + "constraint " + csv2sql.to_snake(data.table) + "_id primary key(id)");
+
+ return tab + tab + "create table if not exists " + word(data.table) + "(" + sql + "\n" + tab + tab + ");"
+ };
+
+ this.table_updater = data => {
+
+ let sql = "";
+
+ data.order.forEach(key => {
+
+ const attribute = data.attributes[key];
+
+ sql += ((sql ? "\n\n" : "") +
+ tab + tab + "if (select 1 from information_schema.columns where table_schema = '" + data.database + "' && table_name = '" + data.table + "' && column_name = '" + key + "' limit 1) is null then \n" +
+ tab + tab + tab + "alter table " + word(data.table) + " add column " + word(key) + " " + attributes(attribute) + ";\n" +
+ tab + tab + "end if;"
+ );
+
+ });
+
+ data.deleted_attribute && (sql += ("\n\n" +
+ tab + tab + "if (select 1 from information_schema.columns where table_schema = '" + data.database + "' && table_name = '" + data.table + "' && column_name = 'deleted' limit 1) is null then \n" +
+ tab + tab + tab + "alter table " + word(data.table) + " add column deleted datetime;\n" +
+ tab + tab + "end if;"
+ ));
+ data.date_in_attribute && (sql += ("\n\n" +
+ tab + tab + "if (select 1 from information_schema.columns where table_schema = '" + data.database + "' && table_name = '" + data.table + "' && column_name = 'date_in' limit 1) is null then \n" +
+ tab + tab + tab + "alter table " + word(data.table) + " add column date_in datetime not null default now();\n" +
+ tab + tab + "end if;"
+ ));
+ data.date_out_attribute && (sql += ("\n\n" +
+ tab + tab + "if (select 1 from information_schema.columns where table_schema = '" + data.database + "' && table_name = '" + data.table + "' && column_name = 'date_out' limit 1) is null then \n" +
+ tab + tab + tab + "alter table " + word(data.table) + " add column date_out datetime;\n" +
+ tab + tab + "end if;"
+ ));
+
+ return sql;
+ };
+
+ this.create_filler = data => {
+
+ const header = "insert into " + word(data.table) + "(" + data.order.map(key => word(key)).join(", ") + ") values";
+ let sql = "";
+
+ if(data.uniques.length){}else{
+
+ data.data.forEach(tuple => {
+
+ let tuple_sql = "";
+
+ data.order.forEach(key => tuple_sql += (tuple_sql ? ", " : "") + (
+ csv2sql.null_or_undefined(tuple[key]) ? "null" :
+ ["integer", "bigint", "float"].includes(data.attributes[key].type) ? tuple[key] :
+ ["bool"].includes(data.attributes[key].type) ? tuple[key] ? "true" : "false" :
+ "'" + tuple[key].replace(/([\\''])/g, "\\$1") + "'"
+ ));
+
+ sql += (sql ? "," : "") + "\n" + tab + tab + tab + "(" + tuple_sql + ")";
+
+ });
+
+ sql = tab + tab + header + sql + ";";
+
+ };
+
+ return sql;
+ };
+
+ this.create_file = variables => {
+
+ let sql = "",
+ callers = "";
+ const key = variables.key ? variables.key + "_" : "";
+
+ sql += (
+ (variables.creator_database ? variables.creator_database : "use " + word(variables.database) + ";") + "\n\n" +
+ "delimiter ;^"
+ );
+
+ if(variables.remover_tables){
+ sql += ("\n\n" +
+ tab + "drop procedure if exists csv2sql_" + key + "tables_remove;^\n" +
+ tab + "create procedure csv2sql_" + key + "tables_remove() begin \n\n" +
+ variables.remover_tables + "\n\n" +
+ tab + "end;^"
+ );
+ callers += "\n" + tab + "call csv2sql_" + key + "tables_remove();^";
+ };
+
+ if(variables.creator_tables){
+ sql += ("\n\n" +
+ tab + "drop procedure if exists csv2sql_" + key + "tables_create;^\n" +
+ tab + "create procedure csv2sql_" + key + "tables_create() begin \n\n" +
+ variables.creator_tables + "\n\n" +
+ tab + "end;^"
+ );
+ callers += "\n" + tab + "call csv2sql_" + key + "tables_create();^";
+ };
+
+ if(variables.updater_tables){
+ sql += ("\n\n" +
+ tab + "drop procedure if exists csv2sql_" + key + "tables_update;^\n" +
+ tab + "create procedure csv2sql_" + key + "tables_update() begin \n\n" +
+ variables.updater_tables + "\n\n" +
+ tab + "end;^"
+ );
+ callers += "\n" + tab + "call csv2sql_" + key + "tables_update();^";
+ };
+
+ if(variables.filler_tables){
+ sql += ("\n\n" +
+ tab + "drop procedure if exists csv2sql_" + key + "tables_fill;^\n" +
+ tab + "create procedure csv2sql_" + key + "tables_fill() begin \n\n" +
+ variables.filler_tables + "\n\n" +
+ tab + "end;^"
+ );
+ callers += "\n" + tab + "call csv2sql_" + key + "tables_fill();^";
+ };
+
+ callers && (sql += "\n" + callers);
+
+ sql += "\n\ndelimiter ;";
+
+ return sql;
+ };
+
+ construct();
+
+};
\ No newline at end of file
diff --git a/Public/ecma/CSV2SQL.SQLServer.ecma.js b/Public/ecma/CSV2SQL.SQLServer.ecma.js
new file mode 100755
index 0000000..035832c
--- /dev/null
+++ b/Public/ecma/CSV2SQL.SQLServer.ecma.js
@@ -0,0 +1,245 @@
+CSV2SQL.SQLServer = function(csv2sql, input){
+
+ const self = this,
+ reserved_words = [];
+ let started = false,
+ tab;
+
+ const construct = () => {};
+
+ this.start = callback => {
+
+ const end = status => csv2sql.is_function(callback) && callback(status);
+
+ if(started){
+ end(false);
+ return false;
+ };
+ started = true;
+
+ tab = csv2sql.settings_get(["mysql_tabulation", "tabulation"]);
+
+ self.add_reserved_words(csv2sql.settings_get("default_sql_server_reserved_words"), () => {
+ self.add_reserved_words(csv2sql.settings_get("sql_server_reserved_words"), () => {
+ end(true);
+ });
+ });
+
+ return true;
+ };
+
+ this.add_reserved_words = (inputs, callback) => {
+
+ let loaded = 0;
+ const total = (csv2sql.is_array(inputs) ? inputs : csv2sql.is_string(inputs) ? inputs = [inputs] : inputs = []).length,
+ end = () => ++ loaded == total && csv2sql.is_function(callback) && callback();
+
+ if(total){
+ for(let i = 0; i < total; i ++){
+ if(csv2sql.is_array(inputs[i]))
+ self.add_reserved_words(inputs[i], end);
+ else if(csv2sql.is_string(inputs[i]) && inputs[i]){
+ if(['[', '{'].includes(inputs[i].trim()[0])){
+ try{
+ self.add_reserved_words(csv2sql.json_decode(inputs[i]), end);
+ }catch(exception){
+ end();
+ };
+ continue;
+ };
+ if(/^[a-z0-9_]+$/.test(inputs[i])){
+ !reserved_words.includes(inputs[i]) && reserved_words.push(inputs[i]);
+ end();
+ continue;
+ };
+ csv2sql.ajax.get(inputs[i], response => {
+ try{
+ self.add_reserved_words(csv2sql.json_decode(response), end);
+ }catch(exception){
+ end();
+ };
+ });
+ }else
+ end();
+ };
+ }else{
+ loaded --;
+ end();
+ };
+
+ };
+
+ const word = this.word = name => reserved_words.includes(name) ? "[" + name + "]" : name;
+
+ this.database_creator = name => (
+ "if (select top 1 1 from sys.databases where name = '" + name + "') is null create database " + word(name) + "\n" +
+ "go\n" +
+ "use " + word(name)
+ );
+
+ this.table_remover = data => tab + "if object_id(N'dbo." + data.table + "', N'U') is not null drop table dbo." + word(data.table);
+
+ const attributes = attribute => (
+ attribute.type == "varchar" ? attribute.length[0] == attribute.length[1] ? "char" : "varchar" :
+ attribute.type == "bool" ? "bit" :
+ attribute.type
+ ) + (
+ attribute.type == "varchar" ? "(" + attribute.length[1] + ")" :
+ ""
+ ) + (attribute.null ? "" : " not null");
+
+ this.table_creator = data => {
+
+ let sql = "";
+
+ data.id_attribute && (sql += "\n" + tab + tab + "id integer not null identity(1, 1)");
+
+ data.order.forEach(key => {
+
+ const attribute = data.attributes[key];
+
+ sql += (sql ? "," : "") + "\n" + tab + tab + word(key) + " " + attributes(attribute);
+
+ });
+
+ data.deleted_attribute && (sql += ",\n" + tab + tab + "deleted datetime");
+ data.date_in_attribute && (sql += ",\n" + tab + tab + "date_in datetime not null constraint " + csv2sql.to_snake(data.table) + "_date_in default getdate()");
+ data.date_out_attribute && (sql += ",\n" + tab + tab + "date_out datetime");
+
+ data.id_attribute && (sql += ",\n" + tab + tab + "constraint " + csv2sql.to_snake(data.table) + "_id primary key(id)");
+
+ return tab + "if object_id(N'dbo." + data.table + "', N'U') is null create table dbo." + word(data.table) + "(" + sql + "\n" + tab + ")"
+ };
+
+ this.table_updater = data => {
+
+ let sql = "";
+
+ data.order.forEach(key => {
+
+ const attribute = data.attributes[key];
+
+ sql += ((sql ? "\n\n" : "") +
+ tab + "if (select top 1 1 from information_schema.columns where table_catalog = '" + data.database + "' and table_name = '" + data.table + "' and column_name = '" + key + "') is null \n" +
+ tab + tab + "alter table " + word(data.table) + " add " + word(key) + " " + attributes(attribute)
+ );
+
+ });
+
+ data.deleted_attribute && (sql += ("\n\n" +
+ tab + "if (select top 1 1 from information_schema.columns where table_catalog = '" + data.database + "' and table_name = '" + data.table + "' and column_name = 'deleted') is null \n" +
+ tab + tab + "alter table " + word(data.table) + " add deleted datetime"
+ ));
+ data.date_in_attribute && (sql += ("\n\n" +
+ tab + "if (select top 1 1 from information_schema.columns where table_catalog = '" + data.database + "' and table_name = '" + data.table + "' and column_name = 'date_in') is null \n" +
+ tab + tab + "alter table " + word(data.table) + " add date_in datetime not null constraint " + csv2sql.to_snake(data.table) + "_date_in default getdate()"
+ ));
+ data.date_out_attribute && (sql += ("\n\n" +
+ tab + "if (select top 1 1 from information_schema.columns where table_catalog = '" + data.database + "' and table_name = '" + data.table + "' and column_name = 'date_out') is null \n" +
+ tab + tab + "alter table " + word(data.table) + " add date_out datetime"
+ ));
+
+ return sql;
+ };
+
+ this.create_filler = data => {
+
+ const header = "insert into dbo." + word(data.table) + "(" + data.order.map(key => word(key)).join(", ") + ") values";
+ let sql = "";
+
+ if(data.uniques.length){}else{
+
+ let subsql = "";
+ const division = csv2sql.settings_get("sql_server_insert_division");
+
+ data.data.forEach((tuple, i) => {
+
+ let tuple_sql = "";
+
+ if(!(i % division)){
+ subsql && (sql += (sql ? "\n" : "") + tab + header + subsql);
+ subsql = "";
+ };
+
+ data.order.forEach(key => tuple_sql += (tuple_sql ? ", " : "") + (
+ tuple[key] === null ? "null" :
+ ["integer", "bigint", "float"].includes(data.attributes[key].type) ? tuple[key] :
+ ["bool"].includes(data.attributes[key].type) ? tuple[key] ? "1" : "0" :
+ "'" + tuple[key].replace(/'/, "''") + "'"
+ ));
+
+ subsql += (subsql ? "," : "") + "\n" + tab + tab + "(" + tuple_sql + ")";
+
+ });
+
+ subsql && (sql += (sql ? "\n" : "") + tab + header + subsql);
+
+ };
+
+ return sql;
+ };
+
+ this.create_file = variables => {
+
+ let sql = "",
+ callers = "";
+ const key = variables.key ? variables.key + "_" : "";
+
+ sql += variables.creator_database ? variables.creator_database : "use " + word(variables.database);
+
+ if(variables.remover_tables){
+ sql += ("\n\n" +
+ "if object_id(N'dbo.csv2sql_" + key + "tables_remove', N'P') is not null drop procedure dbo.csv2sql_" + key + "tables_remove\n" +
+ "go\n" +
+ "create procedure dbo.csv2sql_" + key + "tables_remove as begin \n\n" +
+ variables.remover_tables + "\n\n" +
+ "end\n" +
+ "go"
+ );
+ callers += "\nexecute dbo.csv2sql_" + key + "tables_remove";
+ };
+
+ if(variables.creator_tables){
+ sql += ("\n\n" +
+ "if object_id(N'dbo.csv2sql_" + key + "tables_create', N'P') is not null drop procedure dbo.csv2sql_" + key + "tables_create\n" +
+ "go\n" +
+ "create procedure dbo.csv2sql_" + key + "tables_create as begin \n\n" +
+ variables.creator_tables + "\n\n" +
+ "end\n" +
+ "go"
+ );
+ callers += "\nexecute dbo.csv2sql_" + key + "tables_create";
+ };
+
+ if(variables.updater_tables){
+ sql += ("\n\n" +
+ "if object_id(N'dbo.csv2sql_" + key + "tables_update', N'P') is not null drop procedure dbo.csv2sql_" + key + "tables_update\n" +
+ "go\n" +
+ "create procedure dbo.csv2sql_" + key + "tables_update as begin \n\n" +
+ variables.updater_tables + "\n\n" +
+ "end\n" +
+ "go"
+ );
+ callers += "\nexecute dbo.csv2sql_" + key + "tables_update";
+ };
+
+ if(variables.filler_tables){
+ sql += ("\n\n" +
+ "if object_id(N'dbo.csv2sql_" + key + "tables_fill', N'P') is not null drop procedure dbo.csv2sql_" + key + "tables_fill\n" +
+ "go\n" +
+ "create procedure dbo.csv2sql_" + key + "tables_fill as begin \n\n" +
+ variables.filler_tables + "\n\n" +
+ "end\n" +
+ "go"
+ );
+ callers += "\nexecute dbo.csv2sql_" + key + "tables_fill";
+ };
+
+ callers && (sql += "\n" + callers);
+
+ return sql;
+ };
+
+ construct();
+
+};
\ No newline at end of file
diff --git a/Public/ecma/CSV2SQL.ecma.js b/Public/ecma/CSV2SQL.ecma.js
new file mode 100755
index 0000000..cb68a0d
--- /dev/null
+++ b/Public/ecma/CSV2SQL.ecma.js
@@ -0,0 +1,429 @@
+CSV2SQL = function(anp, input){
+
+ const self = this;
+ let started = false;
+
+ let mysql = this.mysql;
+ let sql_server = this.sql_server;
+
+ const construct = () => {
+
+ CSV2SQL.MySQL && (mysql = self.mysql = new CSV2SQL.MySQL(self, input));
+ CSV2SQL.SQLServer && (sql_server = self.sql_server = new CSV2SQL.SQLServer(self, input));
+
+ };
+
+ this.start = callback => {
+
+ const end = status => csv2sql.is_function(callback) && callback(status);
+
+ if(started){
+ end(false);
+ return;
+ };
+ started = true;
+
+ self.launch(self, ["mysql", "sql_server"], () => {
+ end(true);
+ });
+
+ return true;
+ };
+
+ this.create_subforms = item => {
+
+ const default_database = self.item_self.querySelector("[name=default_database]").value,
+ creator_database = self.item_self.querySelector("[name=default_creator_database]").checked,
+ remover_tables = self.item_self.querySelector("[name=default_remover_tables]").checked,
+ creator_tables = self.item_self.querySelector("[name=default_creator_tables]").checked,
+ updater_tables = self.item_self.querySelector("[name=default_updater_tables]").checked,
+ filler_tables = self.item_self.querySelector("[name=default_filler_tables]").checked,
+ uniques = self.item_self.querySelector("[name=default_uniques]").value,
+ id_attribute = self.item_self.querySelector("[name=default_id_attribute]").checked,
+ deleted_attribute = self.item_self.querySelector("[name=default_deleted_attribute]").checked,
+ date_in_attribute = self.item_self.querySelector("[name=default_date_in_attribute]").checked,
+ date_out_attribute = self.item_self.querySelector("[name=default_date_out_attribute]").checked,
+ fill_last_attribute = self.item_self.querySelector("[name=default_fill_last_attribute]").checked,
+ files = self.comp.files.get(item),
+ container = self.item_self.querySelector(".field[data-i18n=files_data] .content");
+
+ (self.comp.files.get(item) || []).forEach((file, i) => {
+
+ if(file){
+
+ if(container.querySelector("[data-i='" + i + "']"))
+ return;
+
+ const block = container.appendChild(document.createElement("div"));
+ let html;
+
+ block.innerHTML = html = self.comp.forms.create({
+ i18n : "file_data",
+ variables : {
+ i : i,
+ mime : file.mime,
+ name : file.name,
+ size : file.size
+ },
+ structure : [
+ {name : "database", type : "text", value : default_database},
+ {name : "table", type : "text", value : (file.name[0].toUpperCase() + file.name.replace(/\.csv$/i, "").substr(1)).replace(/[^a-z0-9]+([a-z])?/gi, (...arguments) => (arguments[1] || "").toUpperCase())},
+ {name : "creator_database", type : "checkbox", checked : creator_database},
+ {name : "remover_tables", type : "checkbox", checked : remover_tables},
+ {name : "creator_tables", type : "checkbox", checked : creator_tables},
+ {name : "updater_tables", type : "checkbox", checked : updater_tables},
+ {name : "filler_tables", type : "checkbox", checked : filler_tables},
+ {name : "uniques", type : "text", value : uniques, multiline : true},
+ {name : "id_attribute", type : "checkbox", checked : id_attribute},
+ {name : "deleted_attribute", type : "checkbox", checked : deleted_attribute},
+ {name : "date_in_attribute", type : "checkbox", checked : date_in_attribute},
+ {name : "date_out_attribute", type : "checkbox", checked : date_out_attribute},
+ {name : "fill_last_attribute", type : "checkbox", checked : fill_last_attribute}
+ ]
+ });
+ block.setAttribute("data-i", i);
+
+ }else{
+
+ const subform = container.querySelector("[data-i='" + i + "']");
+
+ subform && subform.remove();
+
+ };
+
+ });
+
+ };
+
+ const get_files_data = values => {
+
+ const data = [],
+ default_database = csv2sql.item_self.querySelector("[name=default_database]").value;
+
+ values.files.forEach((file, i) => {
+ if(!file)
+ return;
+
+ const subform = csv2sql.item_self.querySelector(".field[data-i18n=files_data] .content [data-i='" + i + "']"),
+ fill_last_attribute = subform.querySelector("[name=fill_last_attribute]").checked;
+
+ if(!subform)
+ return;
+
+ const table = [],
+ tuples = csv2sql.utf8_decode(csv2sql.base64_decode(file.data)).split(/[\r\n]+/),
+ attributes = {},
+ order = [];
+ let subdata = {};
+
+ tuples[0].replace(/(^|,)(\s*"([^"]+)"|([^,]+))?/gm, (...arguments) => {
+
+ const name = arguments[3] || arguments[4] || "";
+
+ order.push(name);
+ attributes[name] = {
+ null : false,
+ type : "unknown",
+ length : [Number.MAX_SAFE_INTEGER, 0]
+ };
+
+ });
+
+ tuples.slice(1).forEach((tuple, k) => {
+ if(!tuple)
+ return;
+
+ let j = 0;
+
+ table.push({});
+
+ tuple.replace(/(^|,)(\s*"([^"]+)"|([^,]+))?/gm, (...arguments) => {
+
+ let value = arguments[3] || arguments[4] || "",
+ name = order[j];
+ const length = value.length,
+ type = (
+ value == "NULL" ? "null" :
+ /^[0-9]+$/.test(value) && value.length < 13 ? "integer" :
+ /^[0-9]+$/.test(value) && value.length < 19 ? "bigint" :
+ /^(([0-9]+)?\.[0-9]+|[0-9]+\.)$/.test(value) && value.length < 18 ? "float" :
+ /^(true|false)$/i.test(value) ? "boolean" :
+ "varchar"
+ ),
+ is_null = value == "NULL";
+
+ if(!name){
+ if(fill_last_attribute){
+ name = order[order.length - 1];
+ value = table[k][name] + "," + value;
+ }else{
+ order.push(name = "column_" + j);
+ attributes[name] = {
+ type : "unknown",
+ length : [Number.MAX_SAFE_INTEGER, 0]
+ };
+ // console.log([k, name, value]);
+ };
+ };
+
+ if(!is_null){
+ length < attributes[name].length[0] && (attributes[name].length[0] = length);
+ length > attributes[name].length[1] && (attributes[name].length[1] = length);
+ };
+
+ is_null && !attributes[name].null && (attributes[name].null = true);
+
+ switch(attributes[name].type){
+ case "unknown":
+ type != "null" && (attributes[name].type = type);
+ break;
+ case "integer":
+ ["float", "varchar"].includes(type) && (attributes[name].type = type);
+ break;
+ case "float":
+ case "boolean":
+ ["varchar"].includes(type) && (attributes[name].type = type);
+ break;
+ };
+
+ table[k][name] = value == "NULL" ? null : value;
+
+ j ++;
+
+ });
+
+ });
+
+ subdata = {
+ database : subform.querySelector("[name=database]").value || default_database,
+ table : subform.querySelector("[name=table]").value,
+ file_name : file.name,
+ data : table,
+ attributes : attributes,
+ order : order,
+ creator_database : values.files_data[i].creator_database,
+ uniques : (values.uniques + " " + values.files_data[i].uniques).trim()
+ };
+ subdata.uniques = subdata.uniques ? subdata.uniques.split(/(\s|[\r\n])+/) : [];
+
+ [
+ "creator_database", "remover_tables", "creator_tables",
+ "updater_tables", "filler_tables", "id_attribute",
+ "deleted_attribute", "date_in_attribute", "date_out_attribute"
+ ].forEach(key => subdata[key] = values.files_data[i][key]);
+
+ data.push(subdata);
+
+ });
+
+ return data;
+ };
+
+ this.validate_string = (string, empty) => (
+ string === undefined ? 1 << 0 :
+ string === null ? 1 << 1 :
+ !csv2sql.is_string(string) ? 1 << 2 :
+ !empty && !string ? 1 << 3 :
+ 0);
+
+ this.validate_string_messages = key => [
+ key + "_undefined",
+ key + "_null",
+ key + "_not_string",
+ key + "_empty"
+ ];
+
+ this.validate_files = (files, empty) => (
+ files === undefined ? 1 << 0 :
+ files === null ? 1 << 1 :
+ !csv2sql.is_array(files) ? 1 << 2 :
+ !empty && !files.length ? 1 << 3 :
+ 0);
+
+ this.validate_files_messages = key => [
+ key + "_undefined",
+ key + "_null",
+ key + "_not_files",
+ key + "_empty"
+ ];
+
+ this.validate_bool = value => (
+ value === undefined ? 1 << 0 :
+ value === null ? 1 << 1 :
+ !csv2sql.is_bool(value) ? 1 << 2 :
+ 0);
+
+ this.validate_bool_messages = key => [
+ key + "_undefined",
+ key + "_null",
+ key + "_not_bool"
+ ];
+
+ const validate = (values, conditions) => {
+
+ const messages = ["exception"];
+ let error = "",
+ i = 1,
+ ok;
+
+ try{
+
+ conditions.forEach(([key, type, empty, extra]) => {
+
+ const new_messages = self["validate_" + type + "_messages"](key),
+ new_error = self["validate_" + type](values[key], empty);
+
+ error = csv2sql.errors.set(error, new_error, i, 0);
+ [].push.apply(messages, new_messages);
+
+ i += new_messages.length;
+
+ !new_error && extra && extra.forEach(([invalid, message]) => {
+ error = csv2sql.errors.set(error, invalid ? 1 << 0 : 0, i ++, 0);
+ messages.push(message);
+ });
+
+ });
+
+ }catch(exception){
+ csv2sql.settings_get("process_exception_print") && console.error(exception);
+ ok = false;
+ error = csv2sql.errors.set(error, 1 << 0, 0, 0);
+ };
+
+ return [ok, error, messages];
+ };
+
+ const process = item => {
+
+ const [values, form] = csv2sql.comp.forms.get_values(item);
+ let [ok, error, messages] = validate(values, [
+ ["default_database", "string", true],
+ ["type", "string", false, [
+ [!["mysql", "sqlserver"].includes(values.type), "type_unkown"]
+ ]],
+ ["default_creator_database", "bool"],
+ ["default_remover_tables", "bool"],
+ ["default_creator_tables", "bool"],
+ ["default_updater_tables", "bool"],
+ ["default_filler_tables", "bool"],
+ ["default_uniques", "string", true],
+ ["default_id_attribute", "bool"],
+ ["default_deleted_attribute", "bool"],
+ ["default_date_in_attribute", "bool"],
+ ["default_date_out_attribute", "bool"],
+ ["default_fill_last_attribute", "bool"],
+ ["files", "files", false],
+ ["file_name", "string", true]
+ ]);
+
+ if(ok = csv2sql.errors.validate(form, error, "main_menu_error", messages)){
+
+ values.files_data = {};
+
+ form.querySelectorAll(".field[data-i18n=files_data] .structure").forEach(structure => {
+
+ const i_key = structure.parentNode.parentNode.getAttribute("data-i"),
+ [subvalues, subform] = csv2sql.comp.forms.get_values(structure, true);
+ let [subok, suberror, submessages] = validate(values, [
+ ["database", "string", true, [
+ [!values.default_database && !subvalues.database, "database_name_required"]
+ ]],
+ ["table", "string", false],
+ ["creator_database", "bool"],
+ ["remover_tables", "bool"],
+ ["creator_tables", "bool"],
+ ["updater_tables", "bool"],
+ ["filler_tables", "bool"],
+ ["uniques", "string", true],
+ ["id_attribute", "bool"],
+ ["deleted_attribute", "bool"],
+ ["date_in_attribute", "bool"],
+ ["date_out_attribute", "bool"],
+ ["fill_last_attribute", "bool"]
+ ]);
+
+ subok = csv2sql.errors.validate(structure.parentNode, suberror, "file_menu_error", submessages, null, {file_name : values.files[i_key].name});
+
+ !subok && (ok = false);
+
+ values.files_data[i_key] = subvalues;
+
+ });
+
+ };
+
+ return [ok, values, form];
+ };
+
+ this.download_files = (item, event) => {
+
+ const [ok, values, form] = process(item);
+
+ if(ok){
+
+ const zip = new JSZip(),
+ engine = self[values.type == "mysql" ? "mysql" : "sql_server"];
+
+ get_files_data(values).forEach(file => {
+
+ zip.file(file.file_name.replace(/\.csv$/i, "." + (values.type == "mysql" ? "my" : "transact") + ".sql"), engine.create_file({
+ database : file.database,
+ creator_database : file.creator_database ? engine.database_creator(file.database) : null,
+ remover_tables : file.remover_tables ? engine.table_remover(file) : null,
+ creator_tables : file.creator_tables ? engine.table_creator(file) : null,
+ updater_tables : file.updater_tables ? engine.table_updater(file) : null,
+ filler_tables : file.filler_tables ? engine.create_filler(file) : null,
+ key : self.to_snake(file.table)
+ }));
+
+ });
+
+ console.log([values, get_files_data(values)]);
+
+ // self.jszip_download(zip, values.file_name + ".zip");
+
+ };
+
+ };
+
+ this.download_one_file = (item, event) => {
+
+ const [ok, values, form] = process(item);
+
+ if(ok){
+
+ const engine = self[values.type == "mysql" ? "mysql" : "sql_server"];
+ let creator = "",
+ remover = "",
+ updater = "",
+ filler = "";
+
+ get_files_data(values).forEach(file => {
+ file.remover_tables && (remover += (remover ? "\n" : "") + engine.table_remover(file));
+ file.creator_tables && (creator += (creator ? "\n\n" : "") + engine.table_creator(file));
+ file.updater_tables && (updater += (updater ? "\n\n" : "") + engine.table_updater(file));
+ file.filler_tables && (filler += (filler ? "\n\n" : "") + engine.create_filler(file));
+ });
+
+ self.download(engine.create_file({
+ database : values.default_database,
+ creator_database : values.default_creator_database ? engine.database_creator(values.default_database) : null,
+ remover_tables : remover || null,
+ creator_tables : creator || null,
+ updater_tables : updater || null,
+ filler_tables : filler || null
+ }), "text/plain", values.file_name + "." + (values.type == "mysql" ? "my" : "transact") + ".sql");
+
+ };
+
+ };
+
+ this.to_snake = string => string.replace(/[^a-zA-Z0-9]+([a-zA-Z0-9])|([A-Z0-9]+)/g, (...arguments) => (
+ arguments[1] ? "_" + arguments[1] :
+ "_" + arguments[2]
+ )).toLowerCase().replace(/^_+|_+$/g, "");
+
+ construct();
+
+};
\ No newline at end of file
diff --git a/Public/images/CSV2SQL-180.webp b/Public/images/CSV2SQL-180.webp
new file mode 100755
index 0000000..c6761af
Binary files /dev/null and b/Public/images/CSV2SQL-180.webp differ
diff --git a/Public/images/CSV2SQL-192.webp b/Public/images/CSV2SQL-192.webp
new file mode 100755
index 0000000..2ab941f
Binary files /dev/null and b/Public/images/CSV2SQL-192.webp differ
diff --git a/Public/images/CSV2SQL-270.webp b/Public/images/CSV2SQL-270.webp
new file mode 100755
index 0000000..92b367c
Binary files /dev/null and b/Public/images/CSV2SQL-270.webp differ
diff --git a/Public/images/CSV2SQL-32.webp b/Public/images/CSV2SQL-32.webp
new file mode 100755
index 0000000..79a0af2
Binary files /dev/null and b/Public/images/CSV2SQL-32.webp differ
diff --git a/Public/images/CSV2SQL-512.webp b/Public/images/CSV2SQL-512.webp
new file mode 100755
index 0000000..49ccd0e
Binary files /dev/null and b/Public/images/CSV2SQL-512.webp differ
diff --git a/Public/images/CSV2SQL.webp b/Public/images/CSV2SQL.webp
new file mode 100755
index 0000000..49ccd0e
Binary files /dev/null and b/Public/images/CSV2SQL.webp differ
diff --git a/Public/images/logo-180.png b/Public/images/logo-180.png
new file mode 100755
index 0000000..c5301f3
Binary files /dev/null and b/Public/images/logo-180.png differ
diff --git a/Public/images/logo-192.png b/Public/images/logo-192.png
new file mode 100755
index 0000000..fdbe153
Binary files /dev/null and b/Public/images/logo-192.png differ
diff --git a/Public/images/logo-270.png b/Public/images/logo-270.png
new file mode 100755
index 0000000..432fb24
Binary files /dev/null and b/Public/images/logo-270.png differ
diff --git a/Public/images/logo-32.png b/Public/images/logo-32.png
new file mode 100755
index 0000000..f18ec39
Binary files /dev/null and b/Public/images/logo-32.png differ
diff --git a/Public/images/logo-512.png b/Public/images/logo-512.png
new file mode 100755
index 0000000..aa9f356
Binary files /dev/null and b/Public/images/logo-512.png differ
diff --git a/Public/images/logo.png b/Public/images/logo.png
new file mode 100755
index 0000000..c1b97e7
Binary files /dev/null and b/Public/images/logo.png differ
diff --git a/Public/index.php b/Public/index.php
new file mode 100755
index 0000000..914e977
--- /dev/null
+++ b/Public/index.php
@@ -0,0 +1,103 @@
+ "CSV2SQL",
+ "language" => "es",
+ "language_code" => "es_ES",
+ "license_text" => "© 2022-2023 CopyLeft. GPLv3",
+ "url" => AnPBuilder::get_host(),
+ "description" => "Aplicación Web orientada a migrar ficheros CSV a SQL.",
+ "keywords" => "csv,sql,mariadb,sqlserver,transact,mysql",
+ "since" => 20230209,
+ "version" => 20230209,
+ "kstats" => "1fGQBj6KGMzua8u9zasfhWTmU2jbjuJpCWwCBJvkzhWTnXFipxHZyAu3V",
+ "extension" => "webp",
+ "key" => "csv2sql",
+ "root" => "/^(\\/(index\\.php)?)?\\/?$/",
+ "domain" => preg_replace('/^csv2sql\.(.+)$/', "$1", $_SERVER["HTTP_HOST"]),
+ "script" => AnPBuilder::get_cache(function(){ ?> function(){
+
+ foreach([] as $file)
+ if(file_exists($file))
+ include $file;
+
+ $csv2sql = new AnP([
+ "root_paths" => [
+ "/mnt/d/git/CSV2SQL",
+ "/mnt/d/git/CSV2SQL/Public",
+ "/mnt/d/git/AnP",
+ "/mnt/d/git/AnP/Public"
+ ],
+ "settings_files" => "/JSON/CSV2SQL.php.settings.json",
+ "routes_files" => "/JSON/CSV2SQL.php.routes.json",
+ "routes_root" => "/app",
+ "secrets" => [
+ class_exists('\AnP\Secrets') && property_exists('\AnP\Secrets', "settings") ? \AnP\Secrets::settings : [],
+ class_exists('\CSV2SQL\Secrets') && property_exists('\CSV2SQL\Secrets', "settings") ? \CSV2SQL\Secrets::settings : [],
+ ]
+ ]);
+
+ }
+ ]);
diff --git a/Public/json/CSV2SQL.i18n.english.json b/Public/json/CSV2SQL.i18n.english.json
new file mode 100755
index 0000000..307d1cf
--- /dev/null
+++ b/Public/json/CSV2SQL.i18n.english.json
@@ -0,0 +1,153 @@
+{
+ "english" : {
+ "files_csv" : "CSV files",
+ "files_csv_text" : [
+ "For convert the CSV files to SQL, please, fill in the next form ",
+ "and select your local CSV files, and then fill in their subforms."
+ ],
+ "default_database" : "The default database",
+ "default_database_description" : [
+ "Choose a default database name for files that not set their own ",
+ "database."
+ ],
+ "type" : "Type",
+ "type_description" : "Choose the SQL type.",
+ "default_creator_database" : "Database creator",
+ "default_creator_database_description" : [
+ "Check it if you want create the Database in each SQL archive if ",
+ "it is not exists by default."
+ ],
+ "default_remover_tables" : "Tables remover",
+ "default_remover_tables_description" : [
+ "Check it if you want a tables remover for each CSV file by ",
+ "default."
+ ],
+ "default_creator_tables" : "Tables creator",
+ "default_creator_tables_description" : [
+ "Check it if you want a tables creator for each CSV file by ",
+ "default."
+ ],
+ "default_updater_tables" : "Tables updater",
+ "default_updater_tables_description" : [
+ "Check it if you want a tables attributes updater for each CSV ",
+ "file by default."
+ ],
+ "default_filler_tables" : "Tables filler",
+ "default_filler_tables_description" : [
+ "Check it if you want a tables filler for each CSV file by ",
+ "default. If you don't check it, any data will be migrated."
+ ],
+ "default_uniques" : "Default uniques attributes",
+ "default_uniques_description" : [
+ "In this text box, please, write all default attributes names ",
+ "that will not be repeated where saving the data separated by a ",
+ "white space (space, tabulation, new line, etc). If you empty ",
+ "this field, all data will be saved."
+ ],
+ "default_id_attribute" : "ID attribute",
+ "default_id_attribute_description" : [
+ "Check it if you want create the ID auto increment attribute for ",
+ "each table."
+ ],
+ "default_deleted_attribute" : "Deleted attribute",
+ "default_deleted_attribute_description" : [
+ "Check it if you want create the 'deleted' datetime attribute for ",
+ "each table for detecting a logical user delete."
+ ],
+ "default_date_in_attribute" : "Date in attribute",
+ "default_date_in_attribute_description" : [
+ "Check it if you want create the 'date_in' datetime attribute for ",
+ "each table for registering when was created each register."
+ ],
+ "default_date_out_attribute" : "Date out attribute",
+ "default_date_out_attribute_description" : [
+ "Check it if you want create the 'date_out' datetime attribute ",
+ "for each table for detecting a logical administrator delete."
+ ],
+ "default_fill_last_attribute" : "Fill the last attribute",
+ "default_fill_last_attribute_description" : [
+ "Check it if you want fill with unkown columns into last known ",
+ "attribute by default."
+ ],
+ "files" : "Files",
+ "files_description" : [
+ "Select the CSV files that you want convert to SQL."
+ ],
+ "files_data" : "Files data",
+ "files_data_description" : [
+ "Here you will have all subforms for each file that you load here."
+ ],
+ "database" : "Database",
+ "database_description" : "Database name for this table.",
+ "table" : "Table",
+ "table_description" : "The table name into database.",
+ "creator_database" : "Database creator",
+ "creator_database_description" : [
+ "Check it if you want create the Database for this file if it is ",
+ "not exists."
+ ],
+ "remover_tables" : "Tables remover",
+ "remover_tables_description" : [
+ "Check it if you want a table remover for this CSV file."
+ ],
+ "creator_tables" : "Tables creator",
+ "creator_tables_description" : [
+ "Check it if you want a table creator for this CSV file."
+ ],
+ "updater_tables" : "Tables updater",
+ "updater_tables_description" : [
+ "Check it if you want a table attributes updater for this CSV ",
+ "file."
+ ],
+ "filler_tables" : "Tables filler",
+ "filler_tables_description" : [
+ "Check it if you want a tables filler for this CSV file. If you ",
+ "don't check it, any data will be migrated."
+ ],
+ "uniques" : "Uniques attributes",
+ "uniques_description" : [
+ "In this text box, please, write all default attributes names ",
+ "that will not be repeated where saving the data separated by a ",
+ "white space (space, tabulation, new line, etc). If you empty ",
+ "this field, all data will be saved."
+ ],
+ "id_attribute" : "ID attribute",
+ "id_attribute_description" : [
+ "Check it if you want create the ID auto increment attribute."
+ ],
+ "deleted_attribute" : "Deleted attribute",
+ "deleted_attribute_description" : [
+ "Check it if you want create the 'deleted' datetime attribute for ",
+ "detecting a logical user delete."
+ ],
+ "date_in_attribute" : "Date in attribute",
+ "date_in_attribute_description" : [
+ "Check it if you want create the 'date_in' datetime attribute for ",
+ "registering when was created each register."
+ ],
+ "date_out_attribute" : "Date out attribute",
+ "date_out_attribute_description" : [
+ "Check it if you want create the 'date_out' datetime attribute ",
+ "for detecting a logical administrator delete."
+ ],
+ "fill_last_attribute" : "Fill the last attribute",
+ "fill_last_attribute_description" : [
+ "Check it if you want fill with unkown columns into last known ",
+ "attribute."
+ ],
+ "file_data" : "{name}",
+ "file_data_text" : "Data for the '{name}' file.",
+ "file_name" : "File name",
+ "file_name_description" : "The result file name for saving it.",
+ "download_files" : "Save files (ZIP)",
+ "download_one_file" : "Save all in one file",
+ "main_menu_error" : [
+ "There was any error with code '{code}' while getting and ",
+ "validating the main form data.{list}"
+ ],
+ "file_menu_error" : [
+ "There was any error with code '{code}' while getting and ",
+ "validating the file '{file_name}' data.{list}"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Public/json/CSV2SQL.i18n.espanol.json b/Public/json/CSV2SQL.i18n.espanol.json
new file mode 100755
index 0000000..17be9e2
--- /dev/null
+++ b/Public/json/CSV2SQL.i18n.espanol.json
@@ -0,0 +1,3 @@
+{
+ "espanol" : {}
+}
\ No newline at end of file
diff --git a/Public/json/CSV2SQL.i18n.galego.json b/Public/json/CSV2SQL.i18n.galego.json
new file mode 100755
index 0000000..8761660
--- /dev/null
+++ b/Public/json/CSV2SQL.i18n.galego.json
@@ -0,0 +1,3 @@
+{
+ "galego" : {}
+}
\ No newline at end of file
diff --git a/Public/json/CSV2SQL.i18n.nihongo.json b/Public/json/CSV2SQL.i18n.nihongo.json
new file mode 100755
index 0000000..118b7cb
--- /dev/null
+++ b/Public/json/CSV2SQL.i18n.nihongo.json
@@ -0,0 +1,3 @@
+{
+ "nihongo" : {}
+}
\ No newline at end of file
diff --git a/Public/json/CSV2SQL.i18n.russkiy.json b/Public/json/CSV2SQL.i18n.russkiy.json
new file mode 100755
index 0000000..1923ac4
--- /dev/null
+++ b/Public/json/CSV2SQL.i18n.russkiy.json
@@ -0,0 +1,3 @@
+{
+ "russkiy" : {}
+}
\ No newline at end of file
diff --git a/Public/json/CSV2SQL.routes.json b/Public/json/CSV2SQL.routes.json
new file mode 100755
index 0000000..36165ee
--- /dev/null
+++ b/Public/json/CSV2SQL.routes.json
@@ -0,0 +1,3 @@
+[
+ "/ files_csv_view"
+]
\ No newline at end of file
diff --git a/Public/json/CSV2SQL.settings.json b/Public/json/CSV2SQL.settings.json
new file mode 100755
index 0000000..be89570
--- /dev/null
+++ b/Public/json/CSV2SQL.settings.json
@@ -0,0 +1,39 @@
+[
+
+ ["ANP", {
+ "application_name" : "CSV2SQL",
+ "application_url" : "https://csv2sql.k3y.pw/",
+ "application_git" : "https://git.k3y.pw/KyMAN/CSV2SQL",
+ "application_logo" : "/images/CSV2SQL.webp",
+ "default_avatar" : "https://anp.k3y.pw/images/AnP.png",
+ "i18n_files" : [
+ "/json/CSV2SQL.i18n.english.json",
+ "/json/CSV2SQL.i18n.espanol.json",
+ "/json/CSV2SQL.i18n.galego.json",
+ "/json/CSV2SQL.i18n.nihongo.json",
+ "/json/CSV2SQL.i18n.russkiy.json"
+ ],
+ "default_language" : "espanol",
+ "views_files" : "/json/CSV2SQL.views.json",
+ "routes_files" : "/json/CSV2SQL.routes.json",
+ "class" : "csv2sql",
+ "main_menu_items" : [
+ {"i18n" : "documentation", "icon" : "documentation", "url" : "https://csv2sql.k3y.pw/doc"},
+ {"i18n" : "git", "icon" : "git", "url" : "https://git.k3y.pw/KyMAN/CSV2SQL"}
+ ],
+ "cells" : 80,
+ "minimum_font_size" : 14,
+ "allow_users" : false,
+ "allow_geolocation" : false,
+ "allow_breadcrumb" : false
+ }, "ANP"],
+
+ ["CSV2SQL", {
+ "default_sql_server_reserved_words" : [],
+ "process_exception_print" : true,
+ "mysql_tabulation" : " ",
+ "sql_server_tabulation" : "\t",
+ "sql_server_insert_division" : 900
+ }, "CSV2SQL"]
+
+]
\ No newline at end of file
diff --git a/Public/json/CSV2SQL.views.json b/Public/json/CSV2SQL.views.json
new file mode 100755
index 0000000..590bc12
--- /dev/null
+++ b/Public/json/CSV2SQL.views.json
@@ -0,0 +1,31 @@
+{
+ "files_csv_view" : {
+ "type" : "form",
+ "i18n" : "files_csv",
+ "structure" : [
+ {"name" : "default_database", "type" : "text"},
+ {"name" : "type", "type" : "selector", "options" : [
+ {"name" : "SQL Server", "value" : "sqlserver"},
+ {"name" : "MySQL/MariaDB", "value" : "mysql", "selected" : true}
+ ]},
+ {"name" : "default_creator_database", "type" : "checkbox", "checked" : true},
+ {"name" : "default_remover_tables", "type" : "checkbox", "checked" : true},
+ {"name" : "default_creator_tables", "type" : "checkbox", "checked" : true},
+ {"name" : "default_updater_tables", "type" : "checkbox", "checked" : true},
+ {"name" : "default_filler_tables", "type" : "checkbox", "checked" : true},
+ {"name" : "default_uniques", "type" : "text", "multiline" : true},
+ {"name" : "default_id_attribute", "type" : "checkbox", "checked" : true},
+ {"name" : "default_deleted_attribute", "type" : "checkbox", "checked" : false},
+ {"name" : "default_date_in_attribute", "type" : "checkbox", "checked" : true},
+ {"name" : "default_date_out_attribute", "type" : "checkbox", "checked" : true},
+ {"name" : "default_fill_last_attribute", "type" : "checkbox", "checked" : true},
+ {"name" : "files", "type" : "file", "multiple" : true, "onchange" : "{object_name}.create_subforms(this, event);", "accept" : ".csv"},
+ {"name" : "files_data"},
+ {"name" : "file_name", "type" : "text", "value" : "csv2sql"}
+ ],
+ "buttons" : [
+ {"i18n" : "download_files", "icon" : "download_files", "onclick" : "{object_name}.download_files(this, event);"},
+ {"i18n" : "download_one_file", "icon" : "download_one_file", "onclick" : "{object_name}.download_one_file(this, event);"}
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Public/scss/CSV2SQL.css b/Public/scss/CSV2SQL.css
new file mode 100755
index 0000000..2eff65b
--- /dev/null
+++ b/Public/scss/CSV2SQL.css
@@ -0,0 +1,4 @@
+.csv2sql .field[data-i18n=files_data] .buttons {
+ display: none; }
+
+/*# sourceMappingURL=CSV2SQL.css.map */
diff --git a/Public/scss/CSV2SQL.css.map b/Public/scss/CSV2SQL.css.map
new file mode 100755
index 0000000..8d268f3
--- /dev/null
+++ b/Public/scss/CSV2SQL.css.map
@@ -0,0 +1,7 @@
+{
+"version": 3,
+"mappings": "AAEI,8CAAqC;EAAC,OAAO,EAAG,IAAI",
+"sources": ["CSV2SQL.scss"],
+"names": [],
+"file": "CSV2SQL.css"
+}
diff --git a/Public/scss/CSV2SQL.scss b/Public/scss/CSV2SQL.scss
new file mode 100755
index 0000000..75b30b9
--- /dev/null
+++ b/Public/scss/CSV2SQL.scss
@@ -0,0 +1,5 @@
+.csv2sql{
+
+ .field[data-i18n=files_data] .buttons{display : none;}
+
+}