X-Git-Url: http://git.roojs.org/?a=blobdiff_plain;f=dbgenerate.js;h=0ea16fda806638b796beb905bec622c88ae15d72;hb=119290bc3234e9ece1c64dbd72ca486d9633b5b7;hp=e952011e66d0bee468197c5b28240b55e92ab28a;hpb=36ef991e3f22cdf1a39e16bebbbb9ed476c850d5;p=app.Builder.js diff --git a/dbgenerate.js b/dbgenerate.js index e952011e6..0ea16fda8 100644 --- a/dbgenerate.js +++ b/dbgenerate.js @@ -13,7 +13,25 @@ * * write readers.. * - * usage: seed generate.js + * usage: seed generate.js + * + * + * + * + *Hack needed to latest GLib-2.0.gir + * + * + + + + + + * + * + * remove introspectable =0 from g_key_file_get_groups + * and add transfer-owneership = none to return value + * remove introspectable =0 from g_key_file_get_keys + * and add transfer-owneership = none to return value* * */ Gda = imports.gi.Gda; @@ -25,7 +43,7 @@ console = imports.console; File = imports.File.File; Options = imports.Options.Options; -Gda.init(); +//Gda.init(); var prov = Gda.Config.list_providers (); //print(prov.dump_as_string()); @@ -34,10 +52,12 @@ var o = new Options({ help_description : 'Element builder for App Builder based on database schema', options: [ + { arg_long : 'DBTYPE' , arg_short : 't', description : 'Database Type (eg. MySQL or PostgreSQL ' }, { arg_long : 'DBNAME' , arg_short : 'd', description : 'Database Name' }, { arg_long : 'USERNAME' , arg_short : 'u', description : 'Username'}, - { arg_long : 'PASSWORD' , arg_short : 'p', description : '' , arg_default :'' }, - { arg_long : 'INI' , arg_short : 'I', description : 'Either base directory which has Pman/***/DataObjects/***.ini or location of ini file.' }, + { arg_long : 'PASSWORD' , arg_short : 'p', description : 'Password' , arg_default :'' }, + { arg_long : 'INI' , arg_short : 'I', description : + 'Either base directory which has Pman/***/DataObjects/***.links.ini or location of ini file.' }, ] }) @@ -47,9 +67,10 @@ var o = new Options({ var cfg = o.parse(Seed.argv); print(JSON.stringify(cfg, null,4)); -var cnc = Gda.Connection.open_from_string ("MySQL", "DB_NAME=" + cfg.DBNAME, - "USERNAME=" + cfg.USERNAME + ';PASSWORD=' + cfg.PASSWORD, - Gda.ConnectionOptions.NONE, null); +var cnc = Gda.Connection.open_from_string (cfg.DBTYPE, + "DB_NAME=" + cfg.DBNAME, + "USERNAME=" + cfg.USERNAME + ';PASSWORD=' + cfg.PASSWORD, + Gda.ConnectionOptions.NONE, null); @@ -96,14 +117,22 @@ Gda.DataSelect.prototype.fetchAll = function() var map = { 'date' : 'date', - 'datetime' : 'string', + 'datetime' : 'date', + 'timestamp with time zone' : 'date', + 'timestamp without time zone' : 'date', + 'time' : 'string', //bogus 'int' : 'int', + 'integer' : 'int', 'bigint' : 'int', - + 'double' : 'float', 'tinyint' : 'int', + 'smallint' : 'int', 'decimal' : 'float', 'float' : 'float', + 'numeric' : 'float', 'char' : 'string', + 'character' : 'string', + 'character varying' : 'string', 'varchar' : 'string', 'text' : 'string', 'longtext' : 'string', @@ -111,7 +140,10 @@ var map = { 'mediumtext' : 'string', 'enum' : 'string', 'timestamp' : 'number', - 'blob' : 'text' + 'blob' : 'text', + 'bytea' : 'text', + 'boolean' : 'int', + 'text[]' : 'string', } @@ -127,15 +159,22 @@ function readIni(fn) var groups = key_file.get_groups(); groups.forEach(function(g) { + //print("KEY:"+g); ini[g] = {} - + var keys = key_file.get_keys(g); + if (!keys) { return; } + keys.forEach(function(k) { - ini[g][k] = key_file.get_value(g,k); - }) - }) - + print("GET val: " + k); + ini[g][k] = key_file.get_value(g,k); + print(ini[g][k] ); + }); + //print("DONE KEY:"+g); + }); + //print("DONE KEYS"); } + if (File.isFile(cfg.INI)) { if (cfg.INI.match(/links\.ini$/)) { readIni(cfg.INI); @@ -144,6 +183,7 @@ if (File.isFile(cfg.INI)) { } } + if (File.isDirectory(cfg.INI)) { @@ -194,21 +234,80 @@ if (File.isDirectory(cfg.INI)) { } //print(JSON.stringify(ini, null,4)); //console.dump(ini); - +print("DONE INI"); //Seed.quit(); //GLib.key_file_load_from_file (key_file, String file, KeyFileFlags flags) : Boolean +switch(cfg.DBTYPE) { + case "MySQL": + query_tables = "SHOW TABLES"; + query_describe_table = "DESCRIBE `%s`"; + break; + + case 'PostgreSQL': + query_tables = "select c.relname FROM pg_catalog.pg_class c " + + "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace " + + "WHERE c.relkind IN ('r','') AND n.nspname NOT IN ('pg_catalog', 'pg_toast')" + + "AND pg_catalog.pg_table_is_visible(c.oid) "; + query_describe_table = + "SELECT " + + "f.attnum AS number, " + + "f.attname AS Field, " + + "f.attnum, " + + "CASE WHEN f.attnotnull = 't' THEN 'NO' ELSE 'YES' END AS isNull, " + + "pg_catalog.format_type(f.atttypid,f.atttypmod) AS Type, " + + "CASE WHEN p.contype = 'p' THEN 't' ELSE 'f' END AS primarykey, " + + "CASE WHEN p.contype = 'u' THEN 't' ELSE 'f' END AS uniquekey, " + + "CASE WHEN p.contype = 'f' THEN g.relname END AS foreignkey, " + + "CASE WHEN p.contype = 'f' THEN p.confkey END AS foreignkey_fieldnum, " + + "CASE WHEN p.contype = 'f' THEN g.relname END AS foreignkey, " + + "CASE WHEN p.contype = 'f' THEN p.conkey END AS foreignkey_connnum, " + + "CASE WHEN f.atthasdef = 't' THEN d.adsrc END AS default " + + "FROM pg_attribute f JOIN pg_class c ON c.oid = f.attrelid " + + " JOIN pg_type t ON t.oid = f.atttypid " + + " LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum " + + " LEFT JOIN pg_namespace n ON n.oid = c.relnamespace " + + " LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY ( p.conkey ) " + + " LEFT JOIN pg_class AS g ON p.confrelid = g.oid " + + "WHERE c.relkind = 'r'::char AND n.nspname = '%n' " + + "AND c.relname = '%s' AND f.attnum > 0 ORDER BY number"; + + + + break; + default: + throw { + name: "ArgumentError", + message: "Invalid data base type " + cfg.DBTYPE + " should be MySQL or PostgreSQL" + }; + +/* + "Field": "province", + "Type": "varchar(255)", + "Null": "NO", << or is null + "Key": null, + "Default": null, + "Extra": +*/ +} + -var tables = Gda.execute_select_command(cnc, "SHOW TABLES").fetchAll(); +var tables = cnc.execute_select_command( query_tables).fetchAll(); +print(JSON.stringify(tables)); + var readers = []; tables.forEach(function(table) { //print(table); - var schema = Gda.execute_select_command(cnc, "DESCRIBE `" + table+'`').fetchAll(); + var schema = cnc.execute_select_command( + query_describe_table.replace(/%s/, table).replace(/%n/,'public') + ).fetchAll(); + + var reader = []; var colmodel = []; var combofields= [ { name : 'id', type: 'int' } ]; // technically the primary key.. @@ -217,9 +316,12 @@ tables.forEach(function(table) { var firstTxtCol = ''; - //print(JSON.stringify(schema, null,4)); + //print(JSON.stringify(schema, null,4)); Seed.quit(); schema.forEach(function(e) { + e.Type = e.Type || e.type; + e.Field = e.Field || e.field; + var type = e.Type.match(/([^(]+)\(([^\)]+)\)/); var row = { }; if (type) { @@ -270,6 +372,8 @@ tables.forEach(function(table) { "*prop": "colModel[]" }); var xtype = 'TextField'; + + if (row.type == 'number') { xtype = 'NumberField'; } @@ -293,6 +397,11 @@ tables.forEach(function(table) { '|xns' : 'Roo.form', xtype : xtype } + if (xtype == 'DateField') { + form[row.name].format = 'Y-m-d'; + form[row.name].width = 100; + } + if (xtype == 'TextArea') { form[row.name].height = 100; } @@ -306,8 +415,8 @@ tables.forEach(function(table) { var combo = { '|xns' : 'Roo.form', xtype: 'ComboBox', - allowBlank : 'false', - editable : 'false', + allowBlank : false, + editable : false, emptyText : 'Select ' + table, forceSelection : true, listWidth : 400, @@ -458,6 +567,7 @@ readers.forEach(function(reader) { var dir = GLib.get_home_dir() + '/.Builder/Roo.data.JsonReader'; if (!File.isDirectory(dir)) { + print("mkdir " + dir); File.mkdir(dir); } @@ -472,6 +582,7 @@ readers.forEach(function(reader) { root : "data", '*prop' : "reader", id : 'id', // maybe no.. + '|fields' : JSON.stringify(reader.reader, null,4).replace(/"/g,"'") }; @@ -484,6 +595,7 @@ readers.forEach(function(reader) { // GRIDS dir = GLib.get_home_dir() + '/.Builder/Roo.GridPanel'; if (!File.isDirectory(dir)) { + print("mkdir " + dir); File.mkdir(dir); } @@ -502,6 +614,7 @@ readers.forEach(function(reader) { "fitContainer": true, "tableName": reader.table, "background": true, + "region" : 'center', "listeners": { "|activate": "function() {\n _this.panel = this;\n if (_this.grid) {\n _this.grid.footer.onClick('first');\n }\n}" }, @@ -514,12 +627,19 @@ readers.forEach(function(reader) { "listeners": { "|render": "function() \n" + "{\n" + - " _this.grid = this; \n" + + " _this.grid = this; \n" + " //_this.dialog = Pman.Dialog.FILL_IN\n" + " if (_this.panel.active) {\n" + " this.footer.onClick('first');\n" + " }\n" + - "}" + "}", + "|rowdblclick": "function (_self, rowIndex, e)\n" + + "{\n" + + " if (!_this.dialog) return;\n" + + " _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n" + + " _this.grid.footer.onClick('first');\n" + + " }); \n" + + "}\n" }, "|xns": "Roo.grid", @@ -527,7 +647,8 @@ readers.forEach(function(reader) { { "*prop": "dataSource", "xtype": "Store", - + remoteSort : true, + '|sortInfo' : "{ field : '" + reader.firstTxtCol + "', direction: 'ASC' }", "|xns": "Roo.data", "items": [ @@ -563,9 +684,10 @@ readers.forEach(function(reader) { "listeners": { "|click": "function()\n"+ "{\n"+ - " //yourdialog.show( { id : 0 } , function() {\n"+ - " // _this.grid.footer.onClick('first');\n"+ - " //}); \n"+ + " if (!_this.dialog) return;\n" + + " _this.dialog.show( { id : 0 } , function() {\n"+ + " _this.grid.footer.onClick('first');\n"+ + " }); \n"+ "}\n" }, "|xns": "Roo.Toolbar" @@ -583,10 +705,10 @@ readers.forEach(function(reader) { " Roo.MessageBox.alert(\"Error\", s.length ? \"Select only one Row\" : \"Select a Row\");\n"+ " return;\n"+ " }\n"+ - " \n"+ - " //_this.dialog.show(s[0].data, function() {\n"+ - " // _this.grid.footer.onClick('first');\n"+ - " // }); \n"+ + " if (!_this.dialog) return;\n" + + " _this.dialog.show(s[0].data, function() {\n"+ + " _this.grid.footer.onClick('first');\n"+ + " }); \n"+ " \n"+ "}\n" @@ -601,7 +723,7 @@ readers.forEach(function(reader) { "listeners": { "|click": "function()\n"+ "{\n"+ - " //Pman.genericDelete(_this, _this.grid.tableName); \n"+ + " Pman.genericDelete(_this, '" + reader.table + "'); \n"+ "}\n"+ " " }, @@ -621,16 +743,23 @@ readers.forEach(function(reader) { dir = GLib.get_home_dir() + '/.Builder/Roo.form.Form'; if (!File.isDirectory(dir)) { + print("mkdir " + dir); File.mkdir(dir); } var formElements = []; + var formHeight = 50; for (var k in reader.form) { if (k == 'id') { // should really do primary key testing.. continue; } + formHeight += reader.form[k].xtype == 'TextArea' ? 100 : 30; + formElements.push(reader.form[k]); } - formElements.push(reader.form['id']); + if (reader.form['id']) { + formElements.push(reader.form['id']); + } + print("WRITE: " + dir + '/' + cfg.DBNAME + '_' + reader.table + '.json'); var frmCfg = @@ -689,6 +818,7 @@ readers.forEach(function(reader) { dir = GLib.get_home_dir() + '/.Builder/Roo.form.ComboBox'; if (!File.isDirectory(dir)) { + print("mkdir " + dir); File.mkdir(dir); } @@ -711,6 +841,7 @@ readers.forEach(function(reader) { dir = GLib.get_home_dir() + '/.Builder/Roo.LayoutDialog'; if (!File.isDirectory(dir)) { + print("mkdir " + dir); File.mkdir(dir); } var formElements = []; @@ -732,10 +863,11 @@ readers.forEach(function(reader) { "closable": false, "collapsible": false, - "height": 120, + "height": formHeight, "resizable": false, - "title": "Edit / Create Port", + "title": "Edit / Create " + reader.table, "width": 400, + "modal" : true, "xtype": "LayoutDialog", "|xns": "Roo", "items": [