diff --git a/model_manager.aproj b/model_manager.aproj deleted file mode 100644 index 5da5c35..0000000 --- a/model_manager.aproj +++ /dev/null @@ -1,699 +0,0 @@ - - - {89372B21-80FA-4EB8-B17C-072EB55713D6} - Debug - AnyCPU - Exe - model_manager - model_manager - src\main.anubis - ./%3b./src - False - False - False - - - bin\Debug\ - True - Full - False - -sc - - - bin\Release\ - False - None - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/model_manager.ide b/model_manager.ide deleted file mode 100644 index f717561..0000000 --- a/model_manager.ide +++ /dev/null @@ -1,18 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -# SharpDevelop 1.0.12.108 -Project("{B6712916-30DE-4a3e-A54C-2A79AC984AEE}") = "model_manager", "model_manager.aproj", "{89372B21-80FA-4EB8-B17C-072EB55713D6}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {89372B21-80FA-4EB8-B17C-072EB55713D6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {89372B21-80FA-4EB8-B17C-072EB55713D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {89372B21-80FA-4EB8-B17C-072EB55713D6}.Release|Any CPU.Build.0 = Release|Any CPU - {89372B21-80FA-4EB8-B17C-072EB55713D6}.Release|Any CPU.ActiveCfg = Release|Any CPU - EndGlobalSection -EndGlobal diff --git a/resources/js/hayamiki_designer/README.md b/resources/js/hayamiki_designer/README.md new file mode 100644 index 0000000..51c2a85 --- /dev/null +++ b/resources/js/hayamiki_designer/README.md @@ -0,0 +1,72 @@ +WWW SQL Designer allows users to create database designs, which can be saved/loaded and exported to SQL scripts. Various databases and languages are supported. Ability to import existing database design. + +[[YouTube video](http://www.youtube.com/watch?v=hCQzJx9AKhU)] + +# About + +Hi and welcome to WWW SQL Designer! This tool allows you to draw and create database schemas (E-R diagrams) directly in browser, without the need for any external programs (flash). You only need JavaScript enabled. +The Designer works perfectly in Mozillas (Firefox, Seamonkey), Internet Explorers (6, 7, 8), Safari and Operas. Konqueror works, but the experience is limited. + +Many database features are supported, such as keys, foreign key constraints, comments and indexes. You can either save your design (for further loading & modifications), print it or export as SQL script. It is possible to retrieve (import) schema from existing database. + +WWW SQL Designer was created by [Ondrej Zara](http://ondras.zarovi.cz/) and is built atop the [oz.js](http://code.google.com/p/oz-js/) JavaScript module. It is distributed under New BSD license. + +If you wish to support this project, Donate at PayPal at PayPal! + +# News + +## Moved to GitHub + +Google Code is closing down, we are now completely migrated to GitHub. + +## Experimental real-time collaboration version + +Thanks to Bharat Patil: http://bharat.whiteboard.jit.su/ + +## New release + +Version 2.7 was released on 3.8.2012. This is mainly a bugfix release, although several new features (most notable localStorage support) are present. + +## Release + +Version 2.6 was released on 22.9.2011. Several new translations (pt\_BR, sv, ar) added; VML removed; new visualization options available (show length and datatype); new DBs and backends; support for touch devices... + +## Experimental clone with deletion of saved designs + +http://code.google.com/r/charlieyouakim-wwwsqldesigner-deleteadd/ + +## New optional patch + +A new patch, which enable optional display of field details, was submitted by Wilson Oliveira. While this code is not ready yet to be commited into repository, everyone can download it from http://ondras.zarovi.cz/sql/wwwsqldesigner-inline_field_details_patch.zip. + + +## Support for CUBRID + +WWW SQL Designer now supports the [CUBRID database](http://www.cubrid.org/): both as a backend (using PHP) as well as datatype definition set. + + +## Release + +Version 2.5 was released on 18.6.2010. Many new features were added (hiding of sidebar, colored relation, multi-selection and multi-drag, ...), tons of bugs were fixed. + +## Release + +Version 2.4 was released on 5.11.2009. Several outstanding issues were fixed and new locales added. + +## Release + +Version 2.3.3 was released on 28.7.2009. This long-awaited release includes numerous fixes, compatibility improvements, new locales, backends and DB datatypes. + +## Release + +Version 2.3.2 was released on 8.1.2009. Apart from some traditional bugfixes and locales, a new functionality is introduced - the ability to mark foregin keys between existing table fields! + +## Google Code + +The project was recently moved to Google Code hosting, which (amongst many other things) introduces Subversion hosting. Enjoy! (The old website, http://ondras.zarovi.cz/sql/, will still exist for some time.) + +## 2.0 is here + +Good news: A new version of WWW SQL Designer, rewritten from scratch, is now available. I has many new features, including bezier connectors, support for various customizations, localization, options and more. + +Bad news: This new version is not backwards compatible with 1.x, so all old localizations and XSLT templates won't work with 2.x. Sorry for inconvenience :/ \ No newline at end of file diff --git a/resources/js/hayamiki_designer/backend/asp-file/Default.aspx b/resources/js/hayamiki_designer/backend/asp-file/Default.aspx new file mode 100644 index 0000000..d5384c3 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/asp-file/Default.aspx @@ -0,0 +1 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="backend_asp_file_Default" validateRequest="false" %> diff --git a/resources/js/hayamiki_designer/backend/asp-file/Default.aspx.cs b/resources/js/hayamiki_designer/backend/asp-file/Default.aspx.cs new file mode 100644 index 0000000..f05ba3b --- /dev/null +++ b/resources/js/hayamiki_designer/backend/asp-file/Default.aspx.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.IO; + +public partial class backend_asp_file_Default : System.Web.UI.Page +{ + protected void Page_Load(object sender, EventArgs e) + { + Response.Clear(); + + string action = Request.Params["action"].ToLower(); + + if (action.Equals("list")) + { + list(); + } + + if (action.Equals("load")) + { + load(); + } + + if (action.Equals("save")) + { + save(); + } + + Response.End(); + } + + private void list() + { + string[] filePaths = Directory.GetFiles(Server.MapPath("data")); + foreach (string filePath in filePaths) + { + Response.Write(Path.GetFileName(filePath) + "\n"); + } + } + + private void load() + { + string fNaam = "data/" + Request.Params["keyword"].ToLower(); + Response.ContentType = "text/xml"; + if (File.Exists(Server.MapPath(fNaam))) + { + Response.WriteFile(Server.MapPath(fNaam)); + } + else + { + Response.StatusCode = 404; + } + } + + private void save() + { + string fNaam = "data/" + Request.Params["keyword"].ToLower(); + FileStream fs = new FileStream(Server.MapPath(fNaam), FileMode.Create); + + byte[] buffer = new byte[1024]; + int count; + while ((count = Request.InputStream.Read(buffer, 0, buffer.Length)) != 0) + fs.Write(buffer, 0, count); + + fs.Close(); + + } +} diff --git a/resources/js/hayamiki_designer/backend/asp-file/data/default b/resources/js/hayamiki_designer/backend/asp-file/data/default new file mode 100644 index 0000000..a6de8b9 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/asp-file/data/default @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +INTEGERVARCHAR(100)NULLid
INTEGERVARCHAR(100)NULLid
INTEGERINTEGERVARCHAR(100)id
INTEGERINTEGERINTEGERTIMESTAMPid
\ No newline at end of file diff --git a/resources/js/hayamiki_designer/backend/cf-mysql/database.sql b/resources/js/hayamiki_designer/backend/cf-mysql/database.sql new file mode 100644 index 0000000..ad05726 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/cf-mysql/database.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS `wwwsqldesigner`; + +CREATE TABLE `wwwsqldesigner` ( + `keyword` varchar(30) NOT NULL default '', + `data` mediumtext, + `dt` timestamp, + PRIMARY KEY (`keyword`) +); diff --git a/resources/js/hayamiki_designer/backend/cf-mysql/index.cfm b/resources/js/hayamiki_designer/backend/cf-mysql/index.cfm new file mode 100644 index 0000000..f04be39 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/cf-mysql/index.cfm @@ -0,0 +1,309 @@ + + + + + + + SELECT * + FROM #db.info_db#.#db.info_databases_table# + + + + + + + + + + SELECT * + FROM #db.info_db#.#db.info_tables_table# + + + WHERE #db.info_db_col# = + + + + + + + + + + + + SELECT * + FROM #db.info_db#.#db.info_columns_table# + WHERE #db.info_db_col# = + AND #db.info_table_col# = + + + + + + + + + + + + + SELECT REFERENCED_TABLE_NAME AS 'table', REFERENCED_COLUMN_NAME AS 'column' + FROM #db.info_db#.KEY_COLUMN_USAGE k + LEFT JOIN #db.info_db#.TABLE_CONSTRAINTS c + ON k.CONSTRAINT_NAME = c.CONSTRAINT_NAME + WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' + AND c.#db.info_db_col# = + AND c.#db.info_table_col# = + AND k.#db.info_column_col# = + + + + + + + + + + + SELECT * + FROM #db.info_db#.STATISTICS + WHERE #db.info_db_col# = + AND #db.info_table_col# = + ORDER BY SEQ_IN_INDEX ASC + + + + + + + + + + + + + + + + + + + + + + + + + SELECT * FROM databases + WHERE #db.info_database_col# = + + + + + + + + + + + + + + + + + ')> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ')> + + + + + + + + + + + SELECT keyword + FROM #db.table# + ORDER BY dt DESC + + + #keyword##chr(10)# + + + + + + + + + + SELECT * + FROM #db.table# + WHERE keyword = + + + + + UPDATE #db.table# + SET data = + WHERE keyword = + + + + INSERT INTO #db.table# (keyword, data) + VALUES ( + , + + ) + + + + + + + + + + + SELECT `data` + FROM #db.table# + WHERE keyword = + + + + + + + + #result.data# + + + + + + #import(URL.database)# + + + + + diff --git a/resources/js/hayamiki_designer/backend/perl-file/index.pl b/resources/js/hayamiki_designer/backend/perl-file/index.pl new file mode 100644 index 0000000..cbdf5bb --- /dev/null +++ b/resources/js/hayamiki_designer/backend/perl-file/index.pl @@ -0,0 +1,75 @@ +#!d:\perl\bin\perl.exe -wT +# C.SUDRE - cyril.sudre@edf.fr + +use strict; +use File::Basename; +use IO::File; +use CGI; + +# Directory for datafile. Take care to untaint current execution dir for CGI while -T if you +# choose to keep datafile in the same dir than cgi script. +my $base_dir = (dirname($0) =~ /(.*)/)[0] . "/data/"; + +my $query = new CGI; +my $action = $query->url_param('action') || ''; + +# List available files to load +if($action eq "list") { + print $query->header('text/plain'); + my @files = glob($base_dir . "*"); + for (@files) { + print(basename($_) . "\n"); + } +} + +# Save generated XML to file +elsif($action eq "save") { + # Accept names with spaces and/or extention + my $fname_parameter = ($query->url_param('keyword') =~ /([\w\s]+(\.\w+)*)/)[0]; # Untaint + if (! defined $fname_parameter) { die "Invalid filename!"; } + my $filename = $base_dir . $fname_parameter; + + my $fh = new IO::File ">" . $filename; + if (defined $fh) { + # Win32... + binmode $fh; + + #my $xml = $query->query_string(); + my $xml = $query->param('POSTDATA'); + + # Decode + $xml =~ tr/+/ /; + $xml =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; + + print $fh $xml; + + $fh->close; + } + + print $query->header(-status => "201 File created"); + } + +# Load XML from file +elsif($action eq "load") { + # Accept names with spaces and/or extention + my $fname_parameter = ($query->url_param('keyword') =~ /([\w\s]+(\.\w+)*)/)[0]; # Untaint + my $filename = $base_dir . $fname_parameter; + + undef $/; # Slurp + my $fh = new IO::File "< " . $filename; + + if (defined $fh) { + # Need this for UTF-8 AND Win32... + binmode($fh,":utf8"); + + my $content = <$fh>; + $fh->close; + + print $query->header("text/xml"), $content; + } else { print $query->header(-status => "404 Not Found"); } + } + +else { + print $query->header(-status => "501 Not Implemented"); + } + \ No newline at end of file diff --git a/resources/js/hayamiki_designer/backend/php-blank/index.php b/resources/js/hayamiki_designer/backend/php-blank/index.php new file mode 100644 index 0000000..7777f32 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-blank/index.php @@ -0,0 +1,3 @@ + diff --git a/resources/js/hayamiki_designer/backend/php-cubrid/cubrid_mysql_compat.php b/resources/js/hayamiki_designer/backend/php-cubrid/cubrid_mysql_compat.php new file mode 100644 index 0000000..83e9723 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-cubrid/cubrid_mysql_compat.php @@ -0,0 +1,399 @@ + 0) { + list($host, $port)=explode(":", $server, 2); + } else { + $host=$server; + $port=$GLOBALS['cubrid_default_port']; // default port + } + + // save database name + $GLOBALS['cubrid_database']=$database; + + return cubrid_connect($host, $port, $database, $username, $password); +} + +// MySQL syntax: +// bool mysql_close ( [resource link_identifier] ) +function cubrid_mysql_close($link_identifier) { + return cubrid_disconnect($link_identifier); +} + +// MySQL syntax: +function cubrid_mysql_errno($link_identifier = '') { + // int mysql_errno ( [resource link_identifier] ) + return cubrid_error_code(); +} + +// MySQL syntax: +function cubrid_mysql_error($link_identifier = '') { + // string mysql_error ( [resource link_identifier] ) + return cubrid_error_msg(); +} + +// MySQL syntax: +// resource mysql_query ( string query [, resource link_identifier] ) +function cubrid_mysql_query_native($query, $link_identifier) { + $result=cubrid_execute($link_identifier, $query); + // Cubrid does not do commit automatically by default (auto-commit is off by default) + cubrid_commit ($link_identifier); + return $result; +} + +// MySQL syntax: +// resource mysql_query ( string query [, resource link_identifier] ) +function cubrid_mysql_query($query, $link_identifier, $last_insert_id_column = '') { + $cubrid_query=trim($query); // need to trim to make sure we are handling properly the ";" terminator + + if ($GLOBALS['calculate_last_insert_id']) { + // HACK - Cubrid does not support yet INSERT_ID() + // We need to alter the INSERT query to be able to get last_insert_id + if (startsWith($cubrid_query, "insert", false)) { + if ($cubrid_query[strlen($cubrid_query) - 1] == ";") { // remove the ";" last char + $cubrid_query=substr($cubrid_query, 0, strlen($cubrid_query) - 1) . " INTO :xyz;"; + } else { + $cubrid_query=$cubrid_query . " INTO :xyz;"; + } + } + } + + $result=cubrid_execute($link_identifier, $cubrid_query); + + if (!$result) { + return false; + } + + if ($GLOBALS['calculate_last_insert_id']) { + if (startsWith($cubrid_query, "insert", false)) { + // get the last_insert_id for the specified column (In Cubrid can be multiple auto_increment columns) + if (strlen($last_insert_id_column) > 0) { + $GLOBALS['cubrid_last_insert_id']=cubrid_get_value(cubrid_last_insert_id_query($last_insert_id_column), + $link_identifier); + } + } else { + $GLOBALS['cubrid_last_insert_id']=0; // (re)set to 0 + } + } + cubrid_commit ($link_identifier); + return $result; +} + +// MySQL syntax: +// array mysql_free_result ( resource $link_identifier ) +function cubrid_mysql_free_result($link_identifier) { + return cubrid_free_result($link_identifier); +} + +// MySQL syntax: +// array mysql_fetch_row ( resource result ) +function cubrid_mysql_fetch_row($result) { + return cubrid_fetch_row($result); +} + +// MySQL syntax: +// array mysql_fetch_array ( resource result [, int result_type] ) +function cubrid_mysql_fetch_array($result, $result_type = 0) { + return cubrid_fetch($result, $result_type); +} + +// MySQL syntax: +// object mysql_fetch_object ( resource result ) +function cubrid_mysql_fetch_object($result) { + return cubrid_fetch_object($result); +} + +// MySQL syntax: +// bool mysql_data_seek ( resource result, int row_number ) +function cubrid_mysql_move_cursor($result, $offset) { + return cubrid_move_cursor($result, $offset); +} + +// MySQL syntax: +// object mysql_fetch_field ( resource result [, int field_offset] ) +function cubrid_mysql_fetch_field($result) { + return cubrid_fetch_field($result); +} + +// MySQL syntax: +// int mysql_insert_id ( [resource link_identifier] ) +function cubrid_mysql_insert_id($link_identifier = -1) { + return $GLOBALS['cubrid_last_insert_id']; +} + +// MySQL syntax: +// int mysql_num_rows ( resource result ) +function cubrid_mysql_num_rows($resultSet) { + return cubrid_num_rows($resultSet); +} + +// MySQL syntax: +// int mysql_num_fields ( resource result ) +function cubrid_mysql_num_fields($resultSet) { + return cubrid_num_cols($resultSet); +} + +// MySQL syntax: +// bool mysql_data_seek ( resource result, int row_number ) +function cubrid_mysql_data_seek($result, $row_number) { + return cubrid_data_seek($result, $row_number); +} + +// MySQL syntax: +// Zero if successful. Non-zero if an error occurred. +function cubrid_mysql_commit($link_identifier) { + return cubrid_commit($link_identifier); +} + +// MySQL syntax: +// Zero if successful. Non-zero if an error occurred. +function cubrid_mysql_rollback($link_identifier) { + return cubrid_rollback($link_identifier); +} + +// MySQL syntax: +// string mysql_real_escape_string ( string unescaped_string [, resource link_identifier] ) +function cubrid_mysql_real_escape_string($unescaped_string, $link_identifier = '') { + return str_replace("'", "''", $unescaped_string); +} + +// MySQL syntax: +// string mysql_result ( resource $result , int $row [, mixed $field = 0 ] ) +function cubrid_mysql_result($result, $row, $field = 0) { + return cubrid_result($result, $row, $field); +} + +// MySQL syntax: +// array mysql_fetch_assoc ( resource $result ) +function cubrid_mysql_fetch_assoc($result) { + return cubrid_fetch_assoc($result); +} + +// implements SHOW TABLES +function cubrid_SHOW_TABLES($link_identifier) { + return cubrid_mysql_query_native(get_SQL_SHOW_TABLES(), $link_identifier); +} + +// implements DESCRIBE +function cubrid_DESCRIBE($table, $link_identifier) { + return cubrid_mysql_query_native(get_SQL_describeTableSQL($table), $link_identifier); +} + +// implements SHOW INDEX +function cubrid_SHOW_INDEX_FROM($table, $link_identifier) { + return cubrid_mysql_query_native(get_SQL_SHOW_INDEX_FROM($table), $link_identifier); +} + +// gets data type for a table +function cubrid_ColumnDataType($identifier, $table, $column) { + $id_result =cubrid_mysql_query_native(get_SQL_ColumnDataType($table, $column), $identifier); + $id_row =cubrid_fetch_row($id_result); + cubrid_free_result ($id_result); + $calculated_value=$id_row[0]; + return $calculated_value; +} + +// gets a single value as a query result +function cubrid_get_value($query, $link_identifier) { + $result=cubrid_execute($link_identifier, $query); + + if ($result) { + $row =cubrid_fetch_row($result); + $value=$row[0]; + } else { + return -1; + } + + return $value; +} + +// returns the last_insert_id value +function cubrid_last_insert_id_query($last_insert_id_column, $cubrid_var = "xyz") { + return "SELECT :" . $cubrid_var . "." . $last_insert_id_column . " FROM db_root"; +} + +// returns the last_insert_id value +function cubrid_last_insert_id($last_insert_id_column, $link_identifier, $cubrid_var = "xyz") { + return cubrid_get_value(cubrid_last_insert_id_query($last_insert_id_column), $link_identifier); +} + +// return the current Cubrid database name +function cubrid_current_database() { + return $GLOBALS['cubrid_database']; +} + +// The following columns are returned: +// Field, Type, Null (YES,NO), Key (PRI,MUL), Default, Extra +function get_SQL_describeTableSQL($table) { + $sql=""; + $sql=$sql . "SELECT a.attr_name as \"Field\"," . " "; + $sql=$sql . "a.data_type || '(' || a.prec || ',' || a.scale || ')' as \"Type\"," . " "; + $sql=$sql . "a.prec || ',' || a.scale as \"Size\"," . " "; + $sql=$sql . "a.is_nullable as \"Null\"," . " "; + $sql=$sql . "'*' as \"Key\"," . " "; + $sql=$sql . "a.default_value as \"Default\"," . " "; + $sql=$sql . "'' as \"Extra\"" . " "; + $sql=$sql . "FROM db_attribute a" . " "; + $sql=$sql . "WHERE a.class_name='" . $table . "'" . " "; + $sql=$sql . "order by a.def_order ASC"; + + return $sql; +} + +// The column data type is returned +function get_SQL_ColumnDataType($table, $column) { + $sql=""; + $sql=$sql . "SELECT a.data_type" . " "; + $sql=$sql . "FROM db_attribute a" . " "; + $sql=$sql . "WHERE a.class_name='" . $table . "'" . " "; + $sql=$sql . "AND a.attr_name='" . $column . "'" . " "; + $sql=$sql . "order by a.def_order ASC"; + + return $sql; +} + +// The following columns are returned: +// Table,Non_unique,Key_name,Seq_in_index,Column_name,Collation,Cardinality,Sub_part,Packed,Index_type,Comment +function get_SQL_SHOW_INDEX_FROM($table) { + $query=""; + $query=$query . "select distinct a.class_name as \"Table\"," . " "; + $query=$query . "DECODE(a.is_unique, 'YES', 'True') as \"Non_unique\"," . " "; + $query=$query . "a.index_name as \"Key_name\"," . " "; + $query=$query . "b.key_order as \"Seq_in_index\"," . " "; + $query=$query . "b.key_attr_name as \"Column_name\"," . " "; + $query=$query . "'' as \"Collation\"," . " "; + $query=$query . "'' as \"Cardinality\"," . " "; + $query=$query . "'' as \"Sub_part\"," . " "; + $query=$query . "'' as \"Packed\"," . " "; + $query=$query . "'' as \"Index_type\"," . " "; + $query=$query . "'' as \"Comment\"" . " "; + $query=$query . "from \"db_index\" a, \"db_index_key\" b" . " "; + $query=$query . "where a.index_name = b.index_name" . " "; + $query=$query . "and b.key_attr_name in (select attr_name from db_attribute where class_name = '" . $table . "')" . " "; + $query=$query . "and a.is_foreign_key = 'NO'" . " "; + $query=$query . "and a.class_name = '" . $table . "'" . " "; + $query=$query . "order by a.index_name, b.key_order,b.key_attr_name"; + + return $query; +} + +// returns the list of non-system tables +function get_SQL_SHOW_TABLES($pattern = '') { + if (strlen($pattern) > 0) { + return "select class_name from db_class where class_type='CLASS' and is_system_class='NO' WHERE class_name LIKE '" + . $pattern . "' order by class_name ASC"; + } else { + return "select class_name from db_class where class_type='CLASS' and is_system_class='NO' order by class_name ASC"; + } +} + +// gets Primary Keys information +function columnIsPK($dbl, $table, $column) { + $ret = false; + + $sql = ""; + $sql = $sql . "select db_index_key.key_attr_name" . " "; + $sql = $sql . "from db_index, db_index_key" . " "; + $sql = $sql . "where db_index.index_name = db_index_key.index_name" . " "; + $sql = $sql . "and db_index.class_name='" . $table . "'" . " "; + $sql = $sql . "and db_index_key.key_attr_name='" . $column . "'" . " "; + $sql = $sql . "and db_index.is_primary_key='YES'"; + + $tableSql = cubrid_execute($dbl, $sql); + + if (@cubrid_num_rows($tableSql) > 0) { + $ret=true; + } + + return $ret; +} + +// emulates DROP TABLE IF EXISTS +function DROP_TABLE_IF_EXISTS($tablename, $link_identifier) { + $id_result + =cubrid_mysql_query_native("SELECT class_name FROM db_class WHERE class_name='" . $tablename . "'", + $link_identifier); + $rows=cubrid_num_rows($id_result); + + if ($rows > 0) { + cubrid_execute($link_identifier, "DROP TABLE " . $tablename); + } +} + +// The following columns are returned: +// Field, Type, Null (YES,NO), Key (PRI,MUL), Default, Extra +function get_SQL_SHOW_COLUMNS($table) { + $sql=""; + $sql=$sql . "SELECT a.attr_name as \"Field\"," . " "; + $sql=$sql . "a.data_type || '(' || a.prec || ',' || a.scale || ')' as \"Type\"," . " "; + $sql=$sql . "a.prec || ',' || a.scale as \"Size\"," . " "; + $sql=$sql . "a.is_nullable as \"Null\"," . " "; + $sql=$sql . "'*' as \"Key\"," . " "; + $sql=$sql . "a.default_value as \"Default\"," . " "; + $sql=$sql . "'' as \"Extra\"" . " "; + $sql=$sql . "FROM db_attribute a" . " "; + $sql=$sql . "WHERE a.class_name='" . $table . "'" . " "; + $sql=$sql . "order by a.def_order ASC"; + + return $sql; +} + +function startsWith($haystack, $needle, $case = true) { + if ($case) { + return strpos($haystack, $needle, 0) == 0; + } else { + return stripos($haystack, $needle, 0) == 0; + } +} + +function endsWith($haystack, $needle, $case = true) { + $expectedPosition=strlen($haystack) - strlen($needle); + + if ($case) { + return strrpos($haystack, $needle, 0) == $expectedPosition; + } else { + return strripos($haystack, $needle, 0) == $expectedPosition; + } +} + +?> \ No newline at end of file diff --git a/resources/js/hayamiki_designer/backend/php-cubrid/database.sql b/resources/js/hayamiki_designer/backend/php-cubrid/database.sql new file mode 100644 index 0000000..b31792d --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-cubrid/database.sql @@ -0,0 +1,8 @@ +DROP TABLE `wwwsqldesigner`; + +CREATE TABLE `wwwsqldesigner` ( + `keyword` varchar(30) NOT NULL, + `data` string, + `dt` timestamp, + PRIMARY KEY (`keyword`) +); diff --git a/resources/js/hayamiki_designer/backend/php-cubrid/index.php b/resources/js/hayamiki_designer/backend/php-cubrid/index.php new file mode 100644 index 0000000..f575585 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-cubrid/index.php @@ -0,0 +1,195 @@ +"; + echo "Please check your instalation." . "
"; + die; + } + + set_time_limit(0); + + function setup_saveloadlist() { + define("SERVER", "localhost:30000"); + define("USER", "dba"); + define("PASSWORD", ""); + define("DB", "demodb"); + define("TABLE", "wwwsqldesigner"); + } + function setup_import() { + define("SERVER", "localhost:30000"); + define("USER", "dba"); + define("PASSWORD", ""); + define("DB", "demodb"); + } + function connect() { + $conn = cubrid_mysql_connect(SERVER, USER, PASSWORD, DB); + if (!$conn) { + return false; + } + return $conn; + } + + function import($conn) { + $xml = ""; + + $arr = array(); + @ $datatypes = file("../../db/cubrid/datatypes.xml"); + $arr[] = $datatypes[0]; + $arr[] = ''; + for ($i=1;$i 0) { + while ($row = cubrid_mysql_fetch_assoc($result)) { + $table = $row["class_name"]; + $xml .= ''; + + $q = get_SQL_describeTableSQL($table); + $result2 = cubrid_mysql_query_native($q, $conn); + while ($row = cubrid_mysql_fetch_assoc($result2)) { + $name = $row["Field"]; + $type = str_replace(",0)", ")", $row["Type"]); + $null = ($row["Null"] == "YES" ? "1" : "0"); + $def = $row["Default"]; + $ai = (preg_match("/auto_increment/i",$row["Extra"]) ? "1" : "0"); + if ($def == "NULL") { + $def = ""; + } + $xml .= ''; + $xml .= ''.strtoupper($type).''; + $xml .= ''.$def.''; + + /* fk constraints */ + /* + $q = "SELECT + REFERENCED_TABLE_NAME AS 'table', REFERENCED_COLUMN_NAME AS 'column' + FROM KEY_COLUMN_USAGE k + LEFT JOIN TABLE_CONSTRAINTS c + ON k.CONSTRAINT_NAME = c.CONSTRAINT_NAME + WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' + AND c.TABLE_SCHEMA = '".$db."' AND c.TABLE_NAME = '".$table."' + AND k.COLUMN_NAME = '".$name."'"; + */ + $q = "SELECT NULL AS `table`, NULL AS `column` FROM db_root"; //no PHP support in CUBRID for FK + $result3 = cubrid_mysql_query_native($q, $conn); + + while ($row = cubrid_mysql_fetch_assoc($result3)) { + $xml .= ''; + } + + $xml .= ''; + } + + /* keys */ + $q = get_SQL_SHOW_INDEX_FROM($table); + $result2 = cubrid_mysql_query_native($q, $conn); + $idx = array(); + + while ($row = cubrid_mysql_fetch_assoc($result2)) { + $name = $row["Key_name"]; + if (array_key_exists($name, $idx)) { + $obj = $idx[$name]; + } else { + $t = "INDEX"; + + if ($row["Non_unique"] == "0") { + $t = "UNIQUE"; + } + + if(columnIsPK($conn, $table, $row["Column_name"])) { + $t = "PRIMARY"; + } + + $obj = array( + "columns" => array(), + "type" => $t + ); + } + + $obj["columns"][] = $row["Column_name"]; + $idx[$name] = $obj; + } + + foreach ($idx as $name=>$obj) { + $xml .= ''; + for ($i=0;$i'; + } + $xml .= ''; + } + $xml .= "
"; + } + } else { + $xml = ""; + } + $arr[] = $xml; + $arr[] = '
'; + return implode("\n",$arr); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////// + + $a = (isset($_GET["action"]) ? $_GET["action"] : false); + switch ($a) { + case "list": + setup_saveloadlist(); + $conn = connect(); + $sql = "SELECT `keyword`, DATE_FORMAT(`dt`, '%d-%M-%Y %H:%i') AS dt FROM ".TABLE." ORDER BY dt DESC"; + $result = cubrid_mysql_query_native($sql, $conn); + if(cubrid_mysql_num_rows($result) > 0) { + while ($row = cubrid_mysql_fetch_assoc($result)) { + echo $row["keyword"]." [".$row["dt"]."]\n"; + } + } + break; + case "save": + setup_saveloadlist(); + $conn = connect(); + $keyword = (isset($_GET["keyword"]) ? $_GET["keyword"] : ""); + $keyword = cubrid_mysql_real_escape_string($keyword); + $data = file_get_contents("php://input"); + if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) { + $data = stripslashes($data); + } + $data = cubrid_mysql_real_escape_string($data); + $r = cubrid_mysql_query_native("SELECT * FROM ".TABLE." WHERE `keyword` = '".$keyword."'", $conn); + if (cubrid_mysql_num_rows($r) > 0) { + $res = cubrid_mysql_query_native("UPDATE ".TABLE." SET `data` = '".$data."', `dt`=SYS_TIMESTAMP WHERE `keyword` = '".$keyword."'", $conn); + } else { + $res = cubrid_mysql_query_native("INSERT INTO ".TABLE." (`keyword`, `data`, `dt`) VALUES ('".$keyword."', '".$data."', SYS_TIMESTAMP)", $conn); + } + if (!$res) { + header("HTTP/1.0 500 Internal Server Error"); + } else { + header("HTTP/1.0 201 Created"); + } + break; + case "load": + setup_saveloadlist(); + $conn = connect(); + $keyword = (isset($_GET["keyword"]) ? $_GET["keyword"] : ""); + $keyword = cubrid_mysql_real_escape_string($keyword); + $result = cubrid_mysql_query_native("SELECT `data` FROM ".TABLE." WHERE `keyword` = '".$keyword."'", $conn); + $row = cubrid_mysql_fetch_assoc($result); + if (!$row) { + header("HTTP/1.0 404 Not Found"); + } else { + header("Content-type: text/xml"); + echo $row["data"]; + } + break; + case "import": + setup_import(); + $conn = connect(); + header("Content-type: text/xml"); + $txt = import($conn); + echo $txt; + break; + default: header("HTTP/1.0 501 Not Implemented"); + } + +?> \ No newline at end of file diff --git a/resources/js/hayamiki_designer/backend/php-file/data/default b/resources/js/hayamiki_designer/backend/php-file/data/default new file mode 100644 index 0000000..a6de8b9 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-file/data/default @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +INTEGERVARCHAR(100)NULLid
INTEGERVARCHAR(100)NULLid
INTEGERINTEGERVARCHAR(100)id
INTEGERINTEGERINTEGERTIMESTAMPid
\ No newline at end of file diff --git a/resources/js/hayamiki_designer/backend/php-file/index.php b/resources/js/hayamiki_designer/backend/php-file/index.php new file mode 100644 index 0000000..054ce47 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-file/index.php @@ -0,0 +1,35 @@ + diff --git a/resources/js/hayamiki_designer/backend/php-mysql+file/data/default b/resources/js/hayamiki_designer/backend/php-mysql+file/data/default new file mode 100644 index 0000000..a6de8b9 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-mysql+file/data/default @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +INTEGERVARCHAR(100)NULLid
INTEGERVARCHAR(100)NULLid
INTEGERINTEGERVARCHAR(100)id
INTEGERINTEGERINTEGERTIMESTAMPid
\ No newline at end of file diff --git a/resources/js/hayamiki_designer/backend/php-mysql+file/index.php b/resources/js/hayamiki_designer/backend/php-mysql+file/index.php new file mode 100644 index 0000000..4528c22 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-mysql+file/index.php @@ -0,0 +1,115 @@ + + * @since 10-July-2009 + */ + + // Define these constants for importing from your MySQL database. MySQL + // usually stores your metadata inside the `information_schema` database + // on the `TABLES` table + define('HOST', 'localhost'); + define('USER', 'root'); + define('PASS', 'password'); + define('DB', 'information_schema'); + + // This constant is the regular expression used to validate the filename + define('FILENAME_REGEX', '^[A-Za-z0-9_]{1,100}$'); + + // Pull the action variable from the GET and validate it + $action = isset($_GET['action']) ? $_GET['action'] : ''; + + if(!in_array($action, array('list','save','load','import'))) { + header('HTTP/1.0 501 Not Implemented'); + exit; + } + + // Save and Load actions must have the 'keyword' GET variable to work, + // I've used a regular expression to keep filenames simple and valid + // so that they don't do anything unintended. + if($action == 'save' || $action == 'load') { + if(!isset($_GET['keyword']) || !ereg(FILENAME_REGEX, $_GET['keyword'])) { + header('HTTP/1.0 400 Bad Request'); + exit; + } + } + + // The import action requires the database variable to be set + if($action == 'import' && !isset($_GET['database'])) { + header('HTTP/1.0 400 Bad Request'); + exit; + } + + // Based on the action variable return appropriate data + switch($action) { + case 'list': + // List all files in the data directory + foreach (glob('data/*') as $file) + echo basename($file)."\n"; + break; + + case 'save': + // Open the file for writing + $f = fopen('data/'.$_GET['keyword'], 'w'); + + // Read in the contents of the XML file from input + $data = file_get_contents('php://input'); + if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) { + $data = stripslashes($data); + } + + // Write the data to the file and close the file + fwrite($f, $data); + fclose($f); + + // Write the response HTTP code + header('HTTP/1.0 201 Created'); + break; + + case 'load': + $keyword = 'data/' . $_GET['keyword']; + if (!file_exists($keyword)) { + header('HTTP/1.0 404 Not Found'); + } else { + header('Content-type: text/xml'); + echo file_get_contents($keyword); + } + break; + + case 'import': + // The import command may take some time, so make sure that PHP won't timeout + set_time_limit(0); + + // I've included the mysql_import function from the php_mysql plugin as its + // own file for future compatibility and to take so much code out of this one + // file. + require_once 'mysql_import.php'; + + // Connect to the MySQL Database, short circuiting ensures that this code will + // execute without error + if (!mysql_connect(HOST,USER,PASS) || !mysql_select_db(DB)) { + header("HTTP/1.0 503 Service Unavailable"); + exit; + } + + header("Content-type: text/xml"); + echo import(); + + break; + } +?> diff --git a/resources/js/hayamiki_designer/backend/php-mysql+file/mysql_import.php b/resources/js/hayamiki_designer/backend/php-mysql+file/mysql_import.php new file mode 100644 index 0000000..8d399e0 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-mysql+file/mysql_import.php @@ -0,0 +1,95 @@ +'; + for ($i=1;$i'; + $comment = (isset($row["TABLE_COMMENT"]) ? $row["TABLE_COMMENT"] : ""); + if ($comment) { $xml .= ''.$comment.''; } + + $q = "SELECT * FROM COLUMNS WHERE TABLE_NAME = '".$table."' AND TABLE_SCHEMA = '".$db."'"; + $result2 = mysql_query($q); + while ($row = mysql_fetch_array($result2)) { + $name = $row["COLUMN_NAME"]; + $type = $row["COLUMN_TYPE"]; + $comment = (isset($row["COLUMN_COMMENT"]) ? $row["COLUMN_COMMENT"] : ""); + $null = ($row["IS_NULLABLE"] == "YES" ? "0" : "1"); + $def = $row["COLUMN_DEFAULT"]; + $ai = (preg_match("/auto_increment/i",$row["EXTRA"]) ? "1" : "0"); + if ($def == "NULL") { $def = ""; } + $xml .= ''; + $xml .= ''.strtoupper($type).''; + $xml .= ''.$def.''; + if ($comment) { $xml .= ''.$comment.''; } + + /* fk constraints */ + $q = "SELECT + REFERENCED_TABLE_NAME AS 'table', REFERENCED_COLUMN_NAME AS 'column' + FROM KEY_COLUMN_USAGE k + LEFT JOIN TABLE_CONSTRAINTS c + ON k.CONSTRAINT_NAME = c.CONSTRAINT_NAME + WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' + AND c.TABLE_SCHEMA = '".$db."' AND c.TABLE_NAME = '".$table."' + AND k.COLUMN_NAME = '".$name."'"; + $result3 = mysql_query($q); + + while ($row = mysql_fetch_array($result3)) { + $xml .= ''; + } + + $xml .= ''; + } + + /* keys */ + $q = "SELECT * FROM STATISTICS WHERE TABLE_NAME = '".$table."' AND TABLE_SCHEMA = '".$db."' ORDER BY SEQ_IN_INDEX ASC"; + $result2 = mysql_query($q); + $idx = array(); + + while ($row = mysql_fetch_array($result2)) { + $name = $row["INDEX_NAME"]; + if (array_key_exists($name, $idx)) { + $obj = $idx[$name]; + } else { + $type = $row["INDEX_TYPE"]; + $t = "INDEX"; + if ($type == "FULLTEXT") { $t = $type; } + if ($row["NON_UNIQUE"] == "0") { $t = "UNIQUE"; } + if ($name == "PRIMARY") { $t = "PRIMARY"; } + + $obj = array( + "columns" => array(), + "type" => $t + ); + } + + $obj["columns"][] = $row["COLUMN_NAME"]; + $idx[$name] = $obj; + } + + foreach ($idx as $name=>$obj) { + $xml .= ''; + for ($i=0;$i'; + } + $xml .= ''; + } + $xml .= ""; + } + $arr[] = $xml; + $arr[] = ''; + return implode("\n",$arr); + } +?> \ No newline at end of file diff --git a/resources/js/hayamiki_designer/backend/php-mysql/database.sql b/resources/js/hayamiki_designer/backend/php-mysql/database.sql new file mode 100644 index 0000000..ad05726 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-mysql/database.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS `wwwsqldesigner`; + +CREATE TABLE `wwwsqldesigner` ( + `keyword` varchar(30) NOT NULL default '', + `data` mediumtext, + `dt` timestamp, + PRIMARY KEY (`keyword`) +); diff --git a/resources/js/hayamiki_designer/backend/php-mysql/index.php b/resources/js/hayamiki_designer/backend/php-mysql/index.php new file mode 100644 index 0000000..2227eb9 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-mysql/index.php @@ -0,0 +1,220 @@ +setLink($conn); + if (!$this->getLink()){ + return false; + } + $res = mysqli_select_db($this->getLink(), DB); + if (!$res){ + // Data Base Not configured + echo "You have to configure the DataBase"; + return false; + } + return true; + } + function getLink(){ + return $this->_conn; + } + function setLink($conn){ + $this->_conn = $conn; + } + + function import() { + $db = (isset($_GET["database"]) ? $_GET["database"] : "information_schema"); + $db = mysqli_real_escape_string($this->getLink(), $db); + $xml = ""; + + $arr = array(); + @ $datatypes = file("../../db/mysql/datatypes.xml"); + $arr[] = $datatypes[0]; + $arr[] = ''; + for ($i=1;$igetLink(), "SELECT * FROM TABLES WHERE TABLE_SCHEMA = '".$db."'"); + while ($row = mysqli_fetch_array($result)) { + $table = $row["TABLE_NAME"]; + $xml .= ''; + $comment = (isset($row["TABLE_COMMENT"]) ? $row["TABLE_COMMENT"] : ""); + if ($comment) { $xml .= ''.htmlspecialchars($comment).''; } + + $q = "SELECT * FROM COLUMNS WHERE TABLE_NAME = '".$table."' AND TABLE_SCHEMA = '".$db."'"; + $result2 = mysqli_query($this->getLink(), $q); + while ($row = mysqli_fetch_array($result2)) { + $name = $row["COLUMN_NAME"]; + $type = $row["COLUMN_TYPE"]; + $comment = (isset($row["COLUMN_COMMENT"]) ? $row["COLUMN_COMMENT"] : ""); + $null = ($row["IS_NULLABLE"] == "YES" ? "1" : "0"); + + if (preg_match("/binary/i",$row["COLUMN_TYPE"])) { + $def = bin2hex($row["COLUMN_DEFAULT"]); + } else { + $def = $row["COLUMN_DEFAULT"]; + } + + $ai = (preg_match("/auto_increment/i",$row["EXTRA"]) ? "1" : "0"); + if ($def == "NULL") { $def = ""; } + $xml .= ''; + $xml .= ''.strtoupper($type).''; + $xml .= ''.$def.''; + if ($comment) { $xml .= ''.htmlspecialchars($comment).''; } + + /* fk constraints */ + $q = "SELECT + REFERENCED_TABLE_NAME AS 'table', REFERENCED_COLUMN_NAME AS 'column' + FROM KEY_COLUMN_USAGE k + LEFT JOIN TABLE_CONSTRAINTS c + ON k.CONSTRAINT_NAME = c.CONSTRAINT_NAME + WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' + AND c.TABLE_SCHEMA = '".$db."' AND c.TABLE_NAME = '".$table."' + AND k.COLUMN_NAME = '".$name."'"; + $result3 = mysqli_query($this->getLink(), $q); + + while ($row = mysqli_fetch_array($result3)) { + $xml .= ''; + } + + $xml .= ''; + } + + /* keys */ + $q = "SELECT * FROM STATISTICS WHERE TABLE_NAME = '".$table."' AND TABLE_SCHEMA = '".$db."' ORDER BY SEQ_IN_INDEX ASC"; + $result2 =mysqli_query($this->getLink(),$q); + $idx = array(); + + while ($row = mysqli_fetch_array($result2)) { + $name = $row["INDEX_NAME"]; + if (array_key_exists($name, $idx)) { + $obj = $idx[$name]; + } else { + $type = $row["INDEX_TYPE"]; + $t = "INDEX"; + if ($type == "FULLTEXT") { $t = $type; } + if ($row["NON_UNIQUE"] == "0") { $t = "UNIQUE"; } + if ($name == "PRIMARY") { $t = "PRIMARY"; } + + $obj = array( + "columns" => array(), + "type" => $t + ); + } + + $obj["columns"][] = $row["COLUMN_NAME"]; + $idx[$name] = $obj; + } + + foreach ($idx as $name=>$obj) { + $xml .= ''; + for ($i=0;$i'; + } + $xml .= ''; + } + $xml .= "
"; + } + $arr[] = $xml; + $arr[] = '
'; + return implode("\n",$arr); + } + } + + + $a = (isset($_GET["action"]) ? $_GET["action"] : false); + switch ($a) { + case "list": + setup_saveloadlist(); + $DBHandler = new mysqlDB(); + if (!$DBHandler->connect()) { + header("HTTP/1.0 503 Service Unavailable"); + break; + } + $result = mysqli_query($DBHandler->getLink(), "SELECT keyword FROM ".TABLE." ORDER BY dt DESC"); + while ($row = mysqli_fetch_assoc($result)) { + echo $row["keyword"]."\n"; + } + break; + case "save": + setup_saveloadlist(); + $DBHandler = new mysqlDB(); + if (!$DBHandler->connect()) { + header("HTTP/1.0 503 Service Unavailable"); + break; + } + $keyword = (isset($_GET["keyword"]) ? $_GET["keyword"] : ""); + $keyword = mysqli_real_escape_string($DBHandler->getLink(), $keyword); + $data = file_get_contents("php://input"); + if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) { + $data = stripslashes($data); + } + $data = mysqli_real_escape_string($DBHandler->getLink(), $data); + $r = mysqli_query($DBHandler->getLink(), "SELECT * FROM ".TABLE." WHERE keyword = '".$keyword."'"); + if (mysqli_num_rows($r) > 0) { + $res = mysqli_query($DBHandler->getLink(), "UPDATE ".TABLE." SET data = '".$data."' WHERE keyword = '".$keyword."'"); + } else { + $res = mysqli_query($DBHandler->getLink(), "INSERT INTO ".TABLE." (keyword, data) VALUES ('".$keyword."', '".$data."')"); + } + if (!$res) { + header("HTTP/1.0 500 Internal Server Error"); + } else { + header("HTTP/1.0 201 Created"); + } + break; + case "load": + setup_saveloadlist(); + $DBHandler = new mysqlDB(); + if (!$DBHandler->connect()) { + header("HTTP/1.0 503 Service Unavailable"); + break; + } + $keyword = (isset($_GET["keyword"]) ? $_GET["keyword"] : ""); + $keyword = mysqli_real_escape_string($DBHandler->getLink(), $keyword); + $result = mysqli_query($DBHandler->getLink(), "SELECT `data` FROM ".TABLE." WHERE keyword = '".$keyword."'"); + $row = mysqli_fetch_assoc($result); + if (!$row) { + header("HTTP/1.0 404 Not Found"); + } else { + header("Content-type: text/xml"); + echo $row["data"]; + } + break; + case "import": + setup_import(); + $DBHandler = new mysqlDB(); + if (!$DBHandler->connect()) { + header("HTTP/1.0 503 Service Unavailable"); + break; + } + + header("Content-type: text/xml"); + echo $DBHandler->import(); + break; + default: header("HTTP/1.0 501 Not Implemented"); + } + + + /* + list: 501/200 + load: 501/200/404 + save: 501/201 + import: 501/200 + */ +?> \ No newline at end of file diff --git a/resources/js/hayamiki_designer/backend/php-pdo/AbstractLayer.php b/resources/js/hayamiki_designer/backend/php-pdo/AbstractLayer.php new file mode 100644 index 0000000..085a560 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-pdo/AbstractLayer.php @@ -0,0 +1,27 @@ + diff --git a/resources/js/hayamiki_designer/backend/php-pdo/LayerMYSQL.php b/resources/js/hayamiki_designer/backend/php-pdo/LayerMYSQL.php new file mode 100644 index 0000000..a8af2e2 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-pdo/LayerMYSQL.php @@ -0,0 +1,181 @@ +prepare($req); + if($keyword) + $q->bindValue($keyword,'string'); + return $q->execute(); + } + public static function KeywordsInsert($table,$keyword,$data) + { + $req = ' + INSERT INTO '.self::protect($table).' + ('.self::protect('keyword').', '.self::protect('data').') + VALUES (?, ?) + '; + return self::$pdo->prepare($req)->bindValue($keyword,'string')->bindValue($data,'string')->execute(); + } + public static function KeywordsUpdate($table,$keyword,$data) + { + $req = ' + UPDATE '.self::protect($table).' + SET '.self::protect('data').' = ? + WHERE '.self::protect('keyword').' = ? + '; + return self::$pdo->prepare($req)->bindValue($data,'string')->bindValue($keyword,'string')->execute(); + } + + # datatypes + public static function DatatypesFile() + { + return dirname(__FILE__).'/../../db/mysql/datatypes.xml'; + } + + # model + public static $schema = NULL; + public static function Tables() + { + if(is_null(self::$schema)) + self::$schema = BackendPhpPdo::req('database'); + if(is_null(self::$schema)) + self::$schema = 'information_schema'; + + $req = ' + SELECT + '.self::protect('TABLE_NAME').' as '.self::protect('name').', + '.self::protect('TABLE_COMMENT').' as '.self::protect('comment').' + FROM '.self::protect('TABLES').' + WHERE + '.self::protect('TABLE_SCHEMA').' = ? + '; + return self::$pdo->prepare($req)->bindValue(self::$schema,'string')->execute()->fetchAll(); + } + private static $columns = array(); + public static function Columns($table) + { + if(isset(self::$columns[$table['name']])) + return self::$columns[$table['name']]; + if(!empty(self::$columns)) + return array(); + + $req = ' + SELECT + '.self::protect('TABLE_NAME').' as '.self::protect('table').', + '.self::protect('COLUMN_NAME').' as '.self::protect('name').', + '.self::protect('COLUMN_TYPE').' as '.self::protect('type').', + '.self::protect('IS_NULLABLE').' as '.self::protect('null').', + '.self::protect('COLUMN_DEFAULT').' as '.self::protect('default').', + '.self::protect('COLUMN_COMMENT').' as '.self::protect('comment').', + '.self::protect('EXTRA').' as '.self::protect('autoincrement').' + FROM '.self::protect('COLUMNS').' + WHERE + '.self::protect('TABLE_SCHEMA').' = ? + '; + $columns = self::$pdo->prepare($req)->bindValue(self::$schema,'string')->execute()->fetchAll(); + foreach($columns as $k=>$column) + { + $column['type'] = strtoupper($column['type']); + $column['null'] = ($column['null'] == 'YES' ? '1' : '0'); + $column['default'] = ($column['default'] == 'NULL' ? '' : $column['default']); + $column['autoincrement'] = preg_match('/auto_increment/i',$column['autoincrement']) ? '1' : '0'; + self::$columns[$column['table']][] = $column; + } + return self::$columns[$table['name']]; + } + private static $relations = array(); + public static function Relations($table,$column) + { + if(isset(self::$relations[$table['name']][$column['name']])) + return self::$relations[$table['name']][$column['name']]; + if(!empty(self::$relations)) + return array(); + + $req = ' + SELECT + '.self::protect('c.TABLE_NAME').' as '.self::protect('table_src').', + '.self::protect('k.COLUMN_NAME').' as '.self::protect('column_src').', + '.self::protect('REFERENCED_TABLE_NAME').' as '.self::protect('table').', + '.self::protect('REFERENCED_COLUMN_NAME').' as '.self::protect('column').' + FROM '.self::protect('KEY_COLUMN_USAGE','k').' + LEFT JOIN '.self::protect('TABLE_CONSTRAINTS','c').' + ON '.self::protect('k.CONSTRAINT_NAME').' = '.self::protect('c.CONSTRAINT_NAME').' + WHERE + '.self::protect('c.TABLE_SCHEMA').' = ? + '; + $relations = self::$pdo->prepare($req)->bindValue(self::$schema,'string')->execute()->fetchAll(); + foreach($relations as $relation) + self::$relations[$relation['table_src']][$relation['column_src']][] = $relation; + + if(isset(self::$relations[$table['name']][$column['name']])) + return self::$relations[$table['name']][$column['name']]; + return array(); + } + private static $keys = array(); + public static function Keys($table) + { + if(isset(self::$keys[$table['name']])) + return self::$keys[$table['name']]; + if(!empty(self::$keys)) + return array(); + + $req = ' + SELECT + '.self::protect('TABLE_NAME').' as '.self::protect('table').', + '.self::protect('INDEX_NAME').' as '.self::protect('name').', + '.self::protect('INDEX_TYPE').' as '.self::protect('type').', + '.self::protect('COLUMN_NAME').' as '.self::protect('column').', + '.self::protect('NON_UNIQUE').' as '.self::protect('non_unique').' + FROM '.self::protect('STATISTICS').' + WHERE + '.self::protect('TABLE_SCHEMA').' = ? + ORDER BY '.self::protect('SEQ_IN_INDEX').' + '; + $indexes = self::$pdo->prepare($req)->bindValue(self::$schema,'string')->execute()->fetchAll(); + + $keys = array(); + foreach($indexes as $index) + { + if($index['type'] != 'FULLTEXT') + $index['type'] = 'INDEX'; + if($index['non_unique'] == '0') + $index['type'] = 'UNIQUE'; + if($index['name'] == 'PRIMARY') + $index['type'] = 'PRIMARY'; + self::$keys[$index['table']][$index['name']]['type'] = $index['type']; + self::$keys[$index['table']][$index['name']]['columns'][] = $index['column']; + } + + if (isset(self::$keys[$table['name']])) { + return self::$keys[$table['name']]; + } else { + return array(); + } + } +} + +?> diff --git a/resources/js/hayamiki_designer/backend/php-pdo/LayerPGSQL.php b/resources/js/hayamiki_designer/backend/php-pdo/LayerPGSQL.php new file mode 100644 index 0000000..903c5a4 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-pdo/LayerPGSQL.php @@ -0,0 +1,201 @@ +prepare($req); + if($keyword) + $q->bindValue($keyword,'string'); + return $q->execute(); + } + public static function KeywordsInsert($table,$keyword,$data) + { + $req = ' + INSERT INTO '.self::protect($table).' + ('.self::protect('keyword').', '.self::protect('xmldata').') + VALUES (?, ?) + '; + return self::$pdo->prepare($req)->bindValue($keyword,'string')->bindValue($data,'string')->execute(); + } + public static function KeywordsUpdate($table,$keyword,$data) + { + $req = ' + UPDATE '.self::protect($table).' + SET '.self::protect('xmldata').' = ? + WHERE '.self::protect('keyword').' = ? + '; + return self::$pdo->prepare($req)->bindValue($data,'string')->bindValue($keyword,'string')->execute(); + } + + # datatypes + public static function DatatypesFile() + { + return dirname(__FILE__).'/../../db/postgresql/datatypes.xml'; + } + + # model + public static function Tables() + { + $req = ' + SELECT + '.self::protect('relname').' as '.self::protect('name').', + '.self::protect('c.oid').' as '.self::protect('oid').', + (SELECT pg_catalog.obj_description('.self::protect('c.oid').', \'pg_class\')) as '.self::protect('comment').' + FROM pg_catalog.pg_class '.self::protect('c').' + WHERE + '.self::protect('c.relname').' !~ \'^(pg_|sql_)\' + AND '.self::protect('c.relkind').' = \'r\' + '; + return self::$pdo->prepare($req)->execute()->fetchAll(); + } + private static $columns = array(); + public static function Columns($table) + { + if(isset(self::$columns[$table['name']])) + return self::$columns[$table['name']]; + if(!empty(self::$columns)) + return array(); + + $req = ' + SELECT + '.self::protect('table_name').' as '.self::protect('table').', + '.self::protect('column_name').' as '.self::protect('name').', + '.self::protect('data_type').' as '.self::protect('type').', + '.self::protect('is_nullable').' as '.self::protect('null').', + '.self::protect('column_default').' as '.self::protect('default')/*.', +* col_description(? ,ordinal_position) as '.self::protect('comment').'*/.' + FROM information_schema.columns + ORDER BY '.self::protect('ordinal_position').' + '; + $columns = self::$pdo->prepare($req)->execute()->fetchAll(); + foreach($columns as $k=>$column) + { + $column['type'] = strtoupper($column['type']); + $column['null'] = ($column['null'] == 'YES' ? '1' : '0'); + $column['default'] = ($column['default'] == 'NULL' ? '' : $column['default']); + $column['autoincrement'] = '0'; + self::$columns[$column['table']][] = $column; + } + return self::$columns[$table['name']]; + } + private static $relations = array(); + public static function Relations($table,$column) + { + if(isset(self::$relations[$table['name']][$column['name']])) + return self::$relations[$table['name']][$column['name']]; + if(!empty(self::$relations)) + return array(); + + $req = ' + SELECT + '.self::protect('kku.table_name').' as '.self::protect('table_src').', + '.self::protect('kku.column_name').' as '.self::protect('column_src').', + '.self::protect('ccu.table_name').' as '.self::protect('table').', + '.self::protect('ccu.column_name').' as '.self::protect('column').' + FROM '.self::protect('information_schema.table_constraints','tc').' + LEFT JOIN '.self::protect('information_schema.constraint_column_usage','ccu').' + ON '.self::protect('tc.constraint_name').' = '.self::protect('ccu.constraint_name').' + LEFT JOIN '.self::protect('information_schema.key_column_usage','kku').' + ON '.self::protect('kku.constraint_name').' = '.self::protect('ccu.constraint_name').' + WHERE + '.self::protect('constraint_type').' = ? + '; + $relations = self::$pdo->prepare($req)->bindValue('FOREIGN KEY','string')->execute()->fetchAll(); + foreach($relations as $relation) + self::$relations[$relation['table_src']][$relation['column_src']][] = $relation; + + if(isset(self::$relations[$table['name']][$column['name']])) + return self::$relations[$table['name']][$column['name']]; + return array(); + } + private static $keys = array(); + public static function Keys($table) + { + if(isset(self::$keys[$table['name']])) + return self::$keys[$table['name']]; + if(!empty(self::$keys)) + return array(); + + $req = ' + SELECT + '.self::protect('tc.table_name').' as '.self::protect('table').', + '.self::protect('tc.constraint_name').' as '.self::protect('name').', + '.self::protect('tc.constraint_type').' as '.self::protect('type').', + '.self::protect('kcu.column_name').' as '.self::protect('column').' + FROM '.self::protect('information_schema.table_constraints','tc').' + LEFT JOIN '.self::protect('information_schema.key_column_usage','kcu').' + ON '.self::protect('tc.constraint_catalog').' = '.self::protect('tc.constraint_catalog').' + AND '.self::protect('tc.constraint_schema').' = '.self::protect('kcu.constraint_schema').' + AND '.self::protect('tc.constraint_name').' = '.self::protect('kcu.constraint_name').' + WHERE + '.self::protect('constraint_type').' != ? + ORDER BY '.self::protect('tc.constraint_name').' + '; + $contraints = self::$pdo->prepare($req)->bindValue('FOREIGN KEY','string')->execute()->fetchAll(); + + $req = ' + SELECT + '.self::protect('pci.relname').' as '.self::protect('table').', + '.self::protect('pcx.relname').' as '.self::protect('name').', + '.self::protect('pa.attname').' as '.self::protect('column').', + '.self::protect('indisunique').' as '.self::protect('unique').', + '.self::protect('indisprimary').' as '.self::protect('primary').' + FROM '.self::protect('pg_index','pi').' + LEFT JOIN '.self::protect('pg_class','pcx').' + ON '.self::protect('pi.indexrelid').' = '.self::protect('pcx.oid').' + LEFT JOIN '.self::protect('pg_class','pci').' + ON '.self::protect('pi.indrelid').' = '.self::protect('pci.oid').' + LEFT JOIN '.self::protect('pg_attribute','pa').' + ON '.self::protect('pa.attrelid').' = '.self::protect('pci.oid').' + AND '.self::protect('pa.attnum').' = ANY('.self::protect('pi.indkey').') + ORDER BY '.self::protect('pa.attnum').' + '; + $indexes = self::$pdo->prepare($req)->execute()->fetchAll(); + + $keys = array(); + foreach($contraints as $constraint) + { + if($constraint['type'] == 'CHECK') + continue; + if($constraint['type'] == 'PRIMARY KEY') + $constraint['type'] = 'PRIMARY'; + self::$keys[$constraint['table']][$constraint['name']]['type'] = $constraint['type']; + self::$keys[$constraint['table']][$constraint['name']]['columns'][] = $constraint['column']; + } + foreach($indexes as $index) + { + if($index['unique'] == 't' || $index['primary'] == 't') + continue; + self::$keys[$index['table']][$index['name']]['type'] = 'INDEX'; + self::$keys[$index['table']][$index['name']]['columns'][] = $index['column']; + } + + return self::$keys[$table['name']]; + } + +} + +?> diff --git a/resources/js/hayamiki_designer/backend/php-pdo/index.php b/resources/js/hayamiki_designer/backend/php-pdo/index.php new file mode 100644 index 0000000..e0ed704 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-pdo/index.php @@ -0,0 +1,417 @@ +what = 'PDO'; + $obj->type = $type; + try { + $obj->pdo = new PDO($dsn,$user,$password); + } catch( Exception $e ) { + self::getException($e); + } + if(empty($obj->pdo)) + self::getException($obj); + return $obj; + } + public static function getPdoStatement($pdo=NULL,$pdo_statement=NULL,$req='',$in=NULL) + { + $obj = new BackendPhpPdo(); + $obj->what = 'PDO_STATEMENT'; + $obj->pdo = $pdo; + $obj->pdo_statement = $pdo_statement; + $obj->req = $req; + $obj->in = $in; + if(empty($obj->pdo_statement)) + self::getException($obj); + return $obj; + } + public static function getException($message) + { + $trace = debug_backtrace(); + if(is_object($message)) + { + if($message instanceOf Exception) + $trace = $message->getTrace(); + $message = $message->getMessage(); + } + $obj = new BackendPhpPdo(); + $obj->what = 'EXCEPTION'; + $obj->message = $message; + $obj->trace = $trace; + header("HTTP/1.0 500 Internal Server Error"); + echo $obj->getMessage(); + die(); + } + public static function getBench($in=NULL,$message='') + { + $t = microtime(true); + if(is_null($in)) + return $t; + $obj = new BackendPhpPdo(); + $obj->what = 'BENCH'; + $obj->in = $in; + $obj->out = $t; + $obj->message = $message; + self::$benchs[] = $obj; + return $t; + } + + # PDO + public function prepare($req) + { + $in = self::getBench(); + $args = func_get_args(); + try { + $pdo_statement = call_user_func_array(array($this->pdo,'prepare'),$args); + } catch (Exception $e) { + self::getException($e); + } + return self::getPDOStatement($this->pdo,$pdo_statement,$req,$in); + } + public function query($req) + { + $in = self::getBench(); + $args = func_get_args(); + try { + $pdo_statement = call_user_func_array(array($this->pdo,'query'),$args); + } catch (Exception $e) { + self::getException($e); + } + return self::getPDOStatement($this->pdo,$pdo_statement,$req,$in); + } + public static $dones = array(); + public function getClass() + { + if(empty(self::$dones)) + require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'AbstractLayer.php'); + AbstractLayer::$pdo = $this; + + $class = 'Layer'.strtoupper($this->type); + if(isset(self::$dones[$class])) + return $class; + + $file = dirname(__FILE__).DIRECTORY_SEPARATOR.$class.'.php'; + if(!file_exists($file)) + self::getException('Layer not implemented : '.$this->type); + require_once($file); + + self::$dones[$class] = 1; + return $class; + } + public function getLayer() + { + $class = $this->getClass(); + $args = func_get_args(); + $method = str_replace(' ','',ucwords(str_replace('-',' ',array_shift($args)))); + if(!method_exists($class,$method)) + self::getException($class.'::'.$method.' not implemented'); + return call_user_func_array(array($class,$method),$args); + } + + # PDO STATEMENT + public function execute() + { + $count = count(explode('?',$this->req))-1; + if($count != $this->pos) + self::getException('Not enough or too much bindValue in regards to the number of "?" : '.$this->req.' ('.$this->pos.';'.$count.')'); + $this->pos = 0; + $args = func_get_args(); + $status = call_user_func_array(array($this->pdo_statement,'execute'),$args); + self::getBench($this->in,'execute'); + if(!$status) + self::getException($this); + return $this; + } + public function fetchName() + { + $args = func_get_args(); + $args[] = PDO::FETCH_ASSOC; + $results = call_user_func_array(array($this->pdo_statement,'fetchAll'),$args); + return $results; + } + public function fetchNum() + { + $args = func_get_args(); + $args[] = PDO::FETCH_NUM; + $results = call_user_func_array(array($this->pdo_statement,'fetchAll'),$args); + return $results; + } + public function fetchOne() + { + $args = func_get_args(); + $results = call_user_func_array(array($this->pdo_statement,'fetchAll'),$args); + foreach($results as $k=>$result) + if(count($result) == 2) + $results[$k] = $result[0]; + return $results; + } + public function fetchAll() + { + $args = func_get_args(); + $results = call_user_func_array(array($this->pdo_statement,'fetchAll'),$args); + self::getBench($this->in,'fetch'); + return $results; + } + public function bindValue($value,$type) + { + switch($type) + { + case 'int': $type = PDO::PARAM_INT; break; + case 'string': $type = PDO::PARAM_STR; break; + case 'resource': $type = PDO::PARAM_LOB; break; + default: self::getException('Unknown type : '.$type); break; + } + $this->pdo_statement->bindValue(++$this->pos,$value,$type); + return $this; + } + + # General + public function getMessage() + { + switch($this->what) + { + case 'EXCEPTION': + $trace = array(); + foreach($this->trace as $e) + { + if(!isset($e['file'])) $e['file'] = 'user_func'; + if(!isset($e['line'])) $e['line'] = '0'; + if(!isset($e['class'])) $e['class'] = ''; + if(!isset($e['type'])) $e['type'] = ''; + $trace[] = ''.$e['file'].':'.$e['line'].' '.$e['class'].$e['type'].$e['function']; + } + return ''.$this->message.''."\n".'
'."\n".implode('
'."\n",$trace); + case 'PDO': + if(empty($this->pdo)) + return 'Fail to connect.'; + $error = $this->pdo->errorInfo(); + return $error[0].':'.$error[1].'
'.$error[2].'
'.$this->req.'
'; + case 'PDO_STATEMENT': + if(empty($this->pdo_statement)) + $error = $this->pdo->errorInfo(); + else + $error = $this->pdo_statement->errorInfo(); + return $error[0].':'.$error[1].'
'.$error[2].'
'.$this->req.'
'; + case 'BENCH': + return (round(($this->out-$this->in)*1000)/1000).'s '.$this->message; + } + } + public function getTrace() + { + switch($this->what) + { + case 'EXCEPTION': + return $this->trace; + default: + return array(); + } + } + + public static function fetchDatatypes($file) + { + if(!file_exists($file)) + { + $header = '<'.'?xml version="1.0" ?'.'>'; + $datatypes = ''; + } + else + { + $datatypes = file($file); + $header = array_shift($datatypes); + $datatypes = implode('',$datatypes); + } + return array($header,$datatypes); + } + public static function buildXML($pdo) + { + list($header,$datatypes) = self::fetchDatatypes($pdo->getLayer('datatypes-file')); + + $xml = array(); + $xml[] = $header; + $xml[] = ''; + $xml[] = $datatypes; + + $tables = $pdo->getLayer('tables'); + foreach($tables as $table) + { + $xmltable = ''; + if(!empty($table['comment'])) + $xmltable .= ''.$table['comment'].''; + + $columns = $pdo->getLayer('columns',$table); + foreach($columns as $column) + { + $xmlcolumn = ''; + $xmlcolumn .= ''.strtoupper($column['type']).''; + $xmlcolumn .= ''.$column['default'].''; + if(!empty($column['comment'])) + $xmlcolumn .= ''.$column['comment'].''; + + $relations = $pdo->getLayer('relations',$table,$column); + foreach($relations as $relation) + $xmlcolumn .= ''; + + $xmlcolumn .= ''; + $xmltable .= $xmlcolumn; + } + + $keys = $pdo->getLayer('keys',$table); + foreach($keys as $name=>$key) + { + $xmlkey = ''; + + foreach($key['columns'] as $column) + if(!empty($column)) + $xmlkey .= ''.$column.''; + + $xmlkey .= ''; + $xmltable .= $xmlkey; + } + + $xmltable .= '
'; + $xml[] = $xmltable; + } + + $xml[] = '
'; + + return implode("\n",$xml); + } + + public static function actionList() + { + list($type,$dsn,$user,$pass,$table) = self::getConfig('saveloadlist'); + $pdo = self::getPdo($type,$dsn,$user,$pass); + $r = $pdo->getLayer('keywords',$table)->fetchOne(); + foreach($r as $keyword) + echo $keyword."\n"; + } + public static function actionSave($key='keyword') + { + $keyword = self::req($key); + $data = file_get_contents("php://input"); + if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) + $data = stripslashes($data); + + list($type,$dsn,$user,$pass,$table) = self::getConfig('saveloadlist'); + $pdo = self::getPdo($type,$dsn,$user,$pass); + + $r = $pdo->getLayer('keywords',$table,$keyword)->fetchOne(); + if(count($r) > 0) + $pdo->getLayer('keywords-update',$table,$keyword,$data); + else + $pdo->getLayer('keywords-insert',$table,$keyword,$data); + + header("HTTP/1.0 201 Created"); + } + public static function actionLoad($key='keyword') + { + $keyword = self::req($key); + + list($type,$dsn,$user,$pass,$table) = self::getConfig('saveloadlist'); + $pdo = self::getPdo($type,$dsn,$user,$pass); + + $r = $pdo->getLayer('keywords',$table,$keyword)->fetchOne(); + if(count($r) > 0) + { + header("Content-type: text/xml"); + echo $r[0]; + } + else + header("HTTP/1.0 404 Not Found"); + die(); + } + public static function actionImport() + { + ob_start(); + + list($type,$dsn,$user,$pass) = self::getConfig('import'); + $pdo = self::getPdo($type,$dsn,$user,$pass); + + $xml = self::buildXML($pdo); + + if(!ob_get_contents()) + header("Content-type: text/xml"); + echo $xml; + die(); + } + + public static function req($key) + { + return isset($_REQUEST[$key])?$_REQUEST[$key]:NULL; + } + public static function controler($key='action') + { + $action = self::req($key); + switch(strtolower($action)) + { + case 'list': + return self::actionList(); + case 'save': + return self::actionSave(); + case 'load': + return self::actionLoad(); + case 'import': + return self::actionImport(); + default: + header("HTTP/1.0 501 Not Implemented"); + echo 'Action not implemented'; + die(); + } + } +} + +function bench() +{ + foreach(BackendPhpPdo::$benchs as $bench) + echo $bench->getMessage().'
'; +} +//register_shutdown_function('bench'); + +BackendPhpPdo::controler(); + +?> diff --git a/resources/js/hayamiki_designer/backend/php-postgresql/README b/resources/js/hayamiki_designer/backend/php-postgresql/README new file mode 100644 index 0000000..5f0fff4 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-postgresql/README @@ -0,0 +1,20 @@ +Postgresql server backend for wwwsqldesigner +version 0.1 beta + + +Instructions: + +If you want to save/load your diagrams in a database... + +1) Create a login role called 'wwwsqldesigner' using 'xxx' as password. +2) Create a databse called 'wwwsqldesigner' with... + owner as 'wwwsqldesigner', + UTF-8 encoding, + and template0 +3) Connect to this newly created database and run the database.sql script + located in this folder. +4) Edit config.js located in the js directory... + change default database to postgresql, + add postgresql to available backends +5) If you want to import the schema of an an already created database, + edit the index.php script located in this directory diff --git a/resources/js/hayamiki_designer/backend/php-postgresql/database.sql b/resources/js/hayamiki_designer/backend/php-postgresql/database.sql new file mode 100644 index 0000000..b4d1ce5 --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-postgresql/database.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS wwwsqldesigner; + +CREATE TABLE wwwsqldesigner ( + keyword varchar(30) NOT NULL, + xmldata text, + dt timestamp, + PRIMARY KEY (keyword) +); diff --git a/resources/js/hayamiki_designer/backend/php-postgresql/index.php b/resources/js/hayamiki_designer/backend/php-postgresql/index.php new file mode 100644 index 0000000..ff5ab7b --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-postgresql/index.php @@ -0,0 +1,281 @@ +'; + for ($i=1;$i'; + $comment = (isset($row["comment"]) ? $row["comment"] : ""); + if ($comment) { $xml .= ''.$comment.''; } + $qstr = " + SELECT *, col_description(".$table_oid.",ordinal_position) as column_comment + FROM information_schema.columns + WHERE table_name = '".$table."' + ORDER BY ordinal_position + ;"; + $result2 = pg_query($conn, $qstr); + while ($row = pg_fetch_array($result2)) { + $name = $row["column_name"]; + $type = $row["data_type"]; // maybe use "udt_name" instead to consider user types + $comment = (isset($row["column_comment"]) ? $row["column_comment"] : ""); + $null = ($row["is_nullable"] == "YES" ? "1" : "0"); + $def = $row["column_default"]; + // $ai:autoincrement... Not in postgresql, Ignore + $ai = "0"; + if ($def == "NULL") { $def = ""; } + $xml .= ''; + $xml .= ''.strtoupper($type).''; + $xml .= ''.$def.''; + if ($comment) { $xml .= ''.$comment.''; } + + /* fk constraints */ + $qstr = " + SELECT kku.column_name, + ccu.table_name AS references_table, + ccu.column_name AS references_field + FROM information_schema.table_constraints tc + LEFT JOIN information_schema.constraint_column_usage ccu + ON tc.constraint_name = ccu.constraint_name + LEFT JOIN information_schema.key_column_usage kku + ON kku.constraint_name = ccu.constraint_name + WHERE constraint_type = 'FOREIGN KEY' + AND kku.table_name = '".$table."' + AND kku.column_name = '".$name."' + ;"; + + $result3 = pg_query($conn, $qstr); + + while ($row = pg_fetch_array($result3)) { + $xml .= ''; + } + + $xml .= ''; + } + + // keys + $qstr = " + SELECT tc.constraint_name, + tc.constraint_type, + kcu.column_name + FROM information_schema.table_constraints tc + LEFT JOIN information_schema.key_column_usage kcu + ON tc.constraint_catalog = kcu.constraint_catalog + AND tc.constraint_schema = kcu.constraint_schema + AND tc.constraint_name = kcu.constraint_name + WHERE tc.table_name = '".$table."' AND constraint_type != 'FOREIGN KEY' + ORDER BY tc.constraint_name + ;"; + $result2 = pg_query($conn, $qstr); + $keyname1 = ""; + while ($row2 = pg_fetch_array($result2)){ + $keyname = $row2["constraint_name"]; + if ($keyname != $keyname1) { + if ($keyname1 != "") { $xml .= ''; } + if ($row2["constraint_type"] == "PRIMARY KEY") { $row2["constraint_type"] = "PRIMARY"; } + if (endsWith($keyname, '_not_null') and $row2["constraint_type"] === "CHECK") { + $keyname = ""; + continue; + } + $xml .= ''; + $xml .= isset($row2["column_name"]) ? ''.$row2["column_name"].'' : ""; + } else { + $xml .= isset($row2["column_name"]) ? ''.$row2["column_name"].'' : ""; + } + $keyname1 = $keyname; + } + if ($keyname1 != "") { $xml .= ''; } + + // index + $qstr = 'SELECT pcx."relname" as "INDEX_NAME", pa."attname" as + "COLUMN_NAME", * FROM "pg_index" pi LEFT JOIN "pg_class" pcx ON pi."indexrelid" = + pcx."oid" LEFT JOIN "pg_class" pci ON pi."indrelid" = pci."oid" LEFT JOIN + "pg_attribute" pa ON pa."attrelid" = pci."oid" AND pa."attnum" = ANY(pi."indkey") + WHERE pci."relname" = \''.$table.'\' order by pa."attnum"'; + $result2 = pg_query($conn, $qstr); + $idx = array(); + while ($row2 = pg_fetch_array($result2)) { + $name = $row2["INDEX_NAME"]; + if (array_key_exists($name, $idx)) { + $obj = $idx[$name]; + } else { + $t = "INDEX"; + if ($row2['indisunique'] == 't') { + $t = "UNIQUE"; + break; + } + if ($row2['indisprimary'] == 't') { + $t = "PRIMARY"; + break; + } + + $obj = array( + "columns" => array(), + "type" => $t + ); + } + + $obj["columns"][] = $row2["COLUMN_NAME"]; + $idx[$name] = $obj; + } + + foreach ($idx as $name=>$obj) { + $xmlkey = ''; + for ($i=0;$i'; + } + $xmlkey .= ''; + $xml .= $xmlkey; + } + + $xml .= ""; + + } + $arr[] = $xml; + $arr[] = ''; + return implode("\n",$arr); + } + + function endsWith($haystack, $needle) + { + return (substr($haystack, -strlen($needle)) === $needle); + } + + $a = (isset($_GET["action"]) ? $_GET["action"] : false); + switch ($a) { + case "list": + setup_saveloadlist(); + $conn = connect(); + $qstr = "SELECT keyword FROM ".TABLE." ORDER BY dt DESC"; + $result = pg_query($conn, $qstr); + while ($row = pg_fetch_assoc($result)) { + echo $row["keyword"]."\n"; + } + break; + case "save": + setup_saveloadlist(); + $conn = connect(); + $keyword = (isset($_GET["keyword"]) ? $_GET["keyword"] : ""); + $keyword = pg_escape_string($conn,$keyword); + $data = file_get_contents("php://input"); + if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) { + $data = stripslashes($data); + } + $data = pg_escape_string($conn,$data); + $qstr = "SELECT * FROM ".TABLE." WHERE keyword = '".$keyword."'"; + $r = pg_query($conn, $qstr); + if (pg_num_rows($r) > 0) { + $qstr = "UPDATE ".TABLE." SET xmldata = '".$data."' WHERE keyword = '".$keyword."'"; + $res = pg_query($conn, $qstr); + } else { + $qstr = "INSERT INTO ".TABLE." (keyword, xmldata) VALUES ('".$keyword."', '".$data."')"; + $res = pg_query($conn, $qstr); + } + if (!$res) { + header("HTTP/1.0 500 Internal Server Error"); + } else { + header("HTTP/1.0 201 Created"); + } + break; + case "load": + setup_saveloadlist(); + $conn = connect(); + $keyword = (isset($_GET["keyword"]) ? $_GET["keyword"] : ""); + $keyword = pg_escape_string($conn, $keyword); + $qstr = "SELECT xmldata FROM ".TABLE." WHERE keyword = '".$keyword."'"; + $result = pg_query($conn, $qstr); + $row = pg_fetch_assoc($result); + if (!$row) { + header("HTTP/1.0 404 Not Found"); + } else { + header("Content-type: text/xml"); + echo $row["xmldata"]; + } + break; + case "import": + setup_import(); + $conn = connect(); + header("Content-type: text/xml"); + echo import($conn); + break; + default: header("HTTP/1.0 501 Not Implemented"); + } + + + /* + list: 501/200 + load: 501/200/404 + save: 501/201 + import: 501/200 + */ +?> diff --git a/resources/js/hayamiki_designer/backend/php-sqlite/index.php b/resources/js/hayamiki_designer/backend/php-sqlite/index.php new file mode 100644 index 0000000..751fd6f --- /dev/null +++ b/resources/js/hayamiki_designer/backend/php-sqlite/index.php @@ -0,0 +1,113 @@ +exec( $initSQL ); + return ($res !== false); + } + return true; + } + function import() { + header( 'HTTP/1.0 501 Not Implemented' ); + } + + $a = (isset($_GET["action"]) ? $_GET["action"] : false); + switch( $a ) { + case 'list' : + setup_saveloadlist(); + if( !connect() ) { + header( 'HTTP/1.0 503 Service Unavailable' ); + break; + } + $result = $pdo->query( "SELECT keyword FROM ".TABLE); + $data = $result->fetchAll(); + if( count($data) > 0 ) { + foreach ($data as $row) { + echo $row['keyword']."\n"; + } + } else { + echo "--No Designs Saved"; + } + break; + case 'save' : + setup_saveloadlist(); + if( !connect() ) { + header( 'HTTP/1.0 503 Service Unavailable' ); + break; + } + + $keyword = ( isset( $_GET['keyword'] ) ? $_GET['keyword'] : '' ); + $data = file_get_contents( "php://input" ); + if( get_magic_quotes_gpc() + || get_magic_quotes_runtime() ) { + $data = stripslashes( $data ); + } + + $statement = $pdo->prepare("SELECT COUNT(*) AS c FROM ".TABLE." WHERE keyword = ?"); + $statement->execute(array($keyword)); + $result = $statement->fetchAll(); + if ($result[0]["c"] > 0) { + $result = $pdo->prepare( "UPDATE ".TABLE." SET data = ? WHERE keyword = ?")->execute(array($data, $keyword)); + } else { + $result = $pdo->prepare( "INSERT INTO ".TABLE." (keyword, data) VALUES (?, ?)")->execute(array($keyword, $data)); + } + + if( !$result ) { + header( 'HTTP/1.0 500 Internal Server Error' ); + } else { + header( 'HTTP/1.0 201 Created' ); + } + break; + case 'load' : + setup_saveloadlist(); + if ( !connect() ) { + header( 'HTTP/1.0 503 Service Unavailable' ); + break; + } + $keyword = ( isset( $_GET['keyword'] ) ? $_GET['keyword'] : '' ); + + $statement = $pdo->prepare( "SELECT data FROM ".TABLE." WHERE keyword = ?"); + $statement->execute(array($keyword)); + $data = $statement->fetchAll(); + + if( !count($data) ) { + header( 'HTTP/1.0 404 Not Found' ); + } else { + header( 'Content-type: text/xml' ); + echo $data[0]['data']; + } + break; + case 'import' : + setup_import(); + default: + header( 'HTTP/1.0 501 Not Implemented' ); + } + + + /* + list: 501/200 + load: 501/200/404 + save: 501/201 + import: 501/200 + */ +?> diff --git a/resources/js/hayamiki_designer/backend/php-sqlite/wwwsqldesigner.sqlite b/resources/js/hayamiki_designer/backend/php-sqlite/wwwsqldesigner.sqlite new file mode 100644 index 0000000..264a247 Binary files /dev/null and b/resources/js/hayamiki_designer/backend/php-sqlite/wwwsqldesigner.sqlite differ diff --git a/resources/js/hayamiki_designer/db/cubrid/datatypes.xml b/resources/js/hayamiki_designer/db/cubrid/datatypes.xml new file mode 100644 index 0000000..ca790cb --- /dev/null +++ b/resources/js/hayamiki_designer/db/cubrid/datatypes.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/js/hayamiki_designer/db/cubrid/output.xsl b/resources/js/hayamiki_designer/db/cubrid/output.xsl new file mode 100644 index 0000000..f1dbbae --- /dev/null +++ b/resources/js/hayamiki_designer/db/cubrid/output.xsl @@ -0,0 +1,152 @@ + + + + +-- +-- CUBRID SQL Script +-- + + + + + -- Table ` + + ` + + + + + + -- DROP TABLE ` + + `; + + + + + + CREATE TABLE ` + + ` ( + + + + ` + + ` + + + + + + NOT NULL + + + + AUTO_INCREMENT + + + + DEFAULT + + + + + + , + + + + + + + + , + + + + PRIMARY KEY ( + UNIQUE KEY ( + KEY ( + + + + `` + + , + + + ) + + + + ); + + + + + + + + +-- Foreign Keys + + + + + + + + + ALTER TABLE ` + + ` ADD FOREIGN KEY (` + + `) REFERENCES ` + + ` (` + + `); + + + + + + + + + + + +-- Test Data + + + + + + -- INSERT INTO ` + ` ( + + ` + + ` + + , + + + ) VALUES +-- ( + + '' + + , + + + ); + + + + + + + diff --git a/resources/js/hayamiki_designer/db/hayamiki/datatypes.xml b/resources/js/hayamiki_designer/db/hayamiki/datatypes.xml new file mode 100644 index 0000000..f8774c3 --- /dev/null +++ b/resources/js/hayamiki_designer/db/hayamiki/datatypes.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/resources/js/hayamiki_designer/db/hayamiki/output.xsl b/resources/js/hayamiki_designer/db/hayamiki/output.xsl new file mode 100644 index 0000000..971419b --- /dev/null +++ b/resources/js/hayamiki_designer/db/hayamiki/output.xsl @@ -0,0 +1,109 @@ + + + + + + + + CREATE TABLE ' + + ' ( + + + + + '' + + + + + NOT NULL + + + + + DEFAULT + + + + + + + + + PRIMARY KEY + + + + + + + AUTOINCREMENT + + + + + REFERENCES ' + + ' (' + + ') + + + + , + + + + + + + + , + + + PRIMARY KEY + UNIQUE + + ( + + + + + , + + + ) + + + + + +); + + + + + + + + + CREATE INDEX ' + + ' ON ' + + ' (' + + + + ', ' + + + '); + + + + + + + diff --git a/resources/js/hayamiki_designer/db/mssql/datatypes.xml b/resources/js/hayamiki_designer/db/mssql/datatypes.xml new file mode 100644 index 0000000..0bf5c23 --- /dev/null +++ b/resources/js/hayamiki_designer/db/mssql/datatypes.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/js/hayamiki_designer/db/mssql/output.xsl b/resources/js/hayamiki_designer/db/mssql/output.xsl new file mode 100644 index 0000000..1474fcf --- /dev/null +++ b/resources/js/hayamiki_designer/db/mssql/output.xsl @@ -0,0 +1,133 @@ + + + + + + + + + CREATE TABLE [ + + ] ( + + + [ + + ] + + + + + + NOT NULL + + + + IDENTITY (1, 1) + + + + , + + + + -- + + + + + + + + + + + + , + + + + CONSTRAINT + + + + PRIMARY KEY ( + FULLTEXT KEY ( + UNIQUE KEY ( + + + + + + + + [] + + , + + + ) + + + + + + + + + +) ON [PRIMARY] +GO + + + + + + + + + ALTER TABLE [ + + ] ADD FOREIGN KEY ( + + ) REFERENCES [ + + ] ([ + + ]); + + + + + + + + + + + CREATE INDEX + + ON [ + + ] ([ + + + ] + + , + + + ); + + + + + + + + \ No newline at end of file diff --git a/resources/js/hayamiki_designer/db/mysql/datatypes.xml b/resources/js/hayamiki_designer/db/mysql/datatypes.xml new file mode 100644 index 0000000..d433991 --- /dev/null +++ b/resources/js/hayamiki_designer/db/mysql/datatypes.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/js/hayamiki_designer/db/mysql/output.xsl b/resources/js/hayamiki_designer/db/mysql/output.xsl new file mode 100644 index 0000000..efc17c9 --- /dev/null +++ b/resources/js/hayamiki_designer/db/mysql/output.xsl @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +-- --- +-- Globals +-- --- + +-- SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; +-- SET FOREIGN_KEY_CHECKS=0; + + + + + + -- --- +-- Table ' + + ' +-- + + + + + + + + +-- --- + + + +DROP TABLE IF EXISTS ` + + `; + + + +CREATE TABLE ` + + ` ( + + + ` + + ` + + + + + + NOT NULL + NULL + + + + AUTO_INCREMENT + + + + DEFAULT + + + + + + COMMENT ' + + + + + + ' + + + + , + + + + + + + , + + + PRIMARY KEY ( + FULLTEXT KEY ( + UNIQUE KEY ( + KEY ( + + + + `` + + , + + + ) + + + + +) + + + + + COMMENT ' + + + + + +' + +; + + + + + +-- --- +-- Foreign Keys +-- --- + + + + + + + + ALTER TABLE ` + + ` ADD FOREIGN KEY ( + + ) REFERENCES ` + + ` (` + + `); + + + + + + +-- --- +-- Table Properties +-- --- + + + + -- ALTER TABLE ` + ` ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + + + + + + +-- --- +-- Test Data +-- --- + + + + -- INSERT INTO ` + ` ( + + ` + + ` + + , + + + ) VALUES +-- ( + + '' + + + , + + + + ); + + + + + + + diff --git a/resources/js/hayamiki_designer/db/oracle/datatypes.xml b/resources/js/hayamiki_designer/db/oracle/datatypes.xml new file mode 100644 index 0000000..45c803e --- /dev/null +++ b/resources/js/hayamiki_designer/db/oracle/datatypes.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/js/hayamiki_designer/db/oracle/output.xsl b/resources/js/hayamiki_designer/db/oracle/output.xsl new file mode 100644 index 0000000..0217256 --- /dev/null +++ b/resources/js/hayamiki_designer/db/oracle/output.xsl @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CREATE TABLE ` + + ` ( + + + ` + + ` + + + + + + NOT NULL + + + + + + DEFAULT + + + + + + , + + + + + + + , + + + PRIMARY KEY ( + FULLTEXT KEY ( + UNIQUE KEY ( + KEY ( + + + + `` + + , + + + ) + + + + +); + + + + COMMENT ON TABLE ` + + ` IS ' + + + + + + '; + + + + + + COMMENT ON COLUMN ` + + `.` + + ` IS ' + + + + + + '; + + + + + + + + + + + ALTER TABLE ` + + ` ADD FOREIGN KEY ( + + ) REFERENCES ` + + ` (` + + `); + + + + + + + \ No newline at end of file diff --git a/resources/js/hayamiki_designer/db/postgresql/datatypes.xml b/resources/js/hayamiki_designer/db/postgresql/datatypes.xml new file mode 100644 index 0000000..e493838 --- /dev/null +++ b/resources/js/hayamiki_designer/db/postgresql/datatypes.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/js/hayamiki_designer/db/postgresql/output.xsl b/resources/js/hayamiki_designer/db/postgresql/output.xsl new file mode 100644 index 0000000..4ca7866 --- /dev/null +++ b/resources/js/hayamiki_designer/db/postgresql/output.xsl @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CREATE TABLE " + + " ( + + + " + + " + + + + + SERIAL + + + + + + + + + NOT NULL + + + + + DEFAULT + + + + + + + /* + + */ + + + + , + + + + + + + , + + + PRIMARY KEY ( + UNIQUE ( + KEY ( + + + + "" + + , + + + ) + + + + +); + + + + COMMENT ON TABLE " + + " IS ' + + + + + + '; + + + + + + + COMMENT ON COLUMN " + + "." + + " IS ' + + + + + + '; + + + + + + + + + + + + + ALTER TABLE " + + " ADD FOREIGN KEY (" + + ") REFERENCES " + + " (" + + "); + + + + + + + diff --git a/resources/js/hayamiki_designer/db/sqlalchemy/datatypes.xml b/resources/js/hayamiki_designer/db/sqlalchemy/datatypes.xml new file mode 100644 index 0000000..75cee55 --- /dev/null +++ b/resources/js/hayamiki_designer/db/sqlalchemy/datatypes.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/js/hayamiki_designer/db/sqlalchemy/output.xsl b/resources/js/hayamiki_designer/db/sqlalchemy/output.xsl new file mode 100644 index 0000000..17d4d1f --- /dev/null +++ b/resources/js/hayamiki_designer/db/sqlalchemy/output.xsl @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + db_engine = sa.create_engine('sqlite:///db.sqlite') + metadata = sa.MetaData() + + + + + + # Mapping Objects + + + + class + + (): + def __init__(self + + , + + + ): + + self. + + = + + + + + def __repr__(self): + return "< + + ( + + '%s' + + , + + + + )>" % ( + + self. + + + , + + + ) + + + + # Declare mappings + + + mapper( + + , + + _table) + + + + # Create a session + session = sessionmaker(bind=db_engine) + + + + + + + + + # Table definition - + # + + + _table = sa.Table(" + + ", metadata, + + + + ) + + + + + + + + + + sa.Column(' + + + ' + + + + + + , nullable=True + + + + , autoincrement=True + + + + + , primary_key=True + + + + ) + + , + + + + + , + + + + + , length= + + + + + + + + + + + + + , sa.ForeignKey(" + + . + + ") + + + + # + + - + + + + + \ No newline at end of file diff --git a/resources/js/hayamiki_designer/db/sqlite/datatypes.xml b/resources/js/hayamiki_designer/db/sqlite/datatypes.xml new file mode 100644 index 0000000..5079b3c --- /dev/null +++ b/resources/js/hayamiki_designer/db/sqlite/datatypes.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/resources/js/hayamiki_designer/db/sqlite/output.xsl b/resources/js/hayamiki_designer/db/sqlite/output.xsl new file mode 100644 index 0000000..971419b --- /dev/null +++ b/resources/js/hayamiki_designer/db/sqlite/output.xsl @@ -0,0 +1,109 @@ + + + + + + + + CREATE TABLE ' + + ' ( + + + + + '' + + + + + NOT NULL + + + + + DEFAULT + + + + + + + + + PRIMARY KEY + + + + + + + AUTOINCREMENT + + + + + REFERENCES ' + + ' (' + + ') + + + + , + + + + + + + + , + + + PRIMARY KEY + UNIQUE + + ( + + + + + , + + + ) + + + + + +); + + + + + + + + + CREATE INDEX ' + + ' ON ' + + ' (' + + + + ', ' + + + '); + + + + + + + diff --git a/resources/js/hayamiki_designer/db/vfp9/datatypes.xml b/resources/js/hayamiki_designer/db/vfp9/datatypes.xml new file mode 100644 index 0000000..5629078 --- /dev/null +++ b/resources/js/hayamiki_designer/db/vfp9/datatypes.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/js/hayamiki_designer/db/vfp9/output.xsl b/resources/js/hayamiki_designer/db/vfp9/output.xsl new file mode 100644 index 0000000..4de2931 --- /dev/null +++ b/resources/js/hayamiki_designer/db/vfp9/output.xsl @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LPARAMETERS teLongName, tcCommand, tcPath + + * [teLongName] False: set llDbc=.F. and generates "FREE", Empty: generates without "FREE" and "NAME", otherwise generates "NAME teLongName" + + * [tcCommand] if used, &tcCommand command will run after CREATE TABLE, f.e. "= MyProc( ALIAS(), m.lcTableComment, @lacComments )" + + * [tcPath] path where tables will be created (if not used, tables will be created in current folder) + + + LOCAL ARRAY lacComments[1,2] + + LOCAL llDbc, lcFreeOrName, lcTableComment + + llDbc = VARTYPE( m.teLongName )=[C] + + * no special support for llDbc=True yet (you could improve db\vfp9\output.xsl and remove "xsl:if test=[1=2]" from it) + + lcFreeOrName = IIF( m.llDbc, IIF( EMPTY( m.teLongName ), [], [NAME "] + m.teLongName + ["] ), [FREE] ) + + tcPath = IIF( VARTYPE( m.tcPath )=[L], [], ADDBS( m.tcPath ) ) + + + + + + + + ERASE ' + + .dbf' + + + ERASE ' + + .fpt' + + + ERASE ' + + .cdx' + + + ERASE ' + + .bak' + + + ERASE ' + + .tbk' + + + + + CREATE TABLE (m.tcPath + ' + + ') &lcFreeOrName + ( ; + + + + + + + + + + + NOT NULL + + + NULL + + + + AutoInc + + + + + + + + + + + + COMMENT ' + + + + + + ' + + + + + , ; + + + + ; + + + + + + + + , + + + PRIMARY KEY ( + FULLTEXT KEY ( + UNIQUE KEY ( + KEY ( + + + + + + , + + + ) + + + + + ) + + + lcTableComment = ' + + + + + + ' + + + + + DIMENSION lacComments[FCOUNT(),2] + + + lacComments[ + + ,1] = ' + + ' + + lacComments[ + + ,2] = ' + + + + + + ' + + + + + IF NOT EMPTY( m.tcCommand ) + + &tcCommand + + ENDIF + + + + + + + + + + + + + ALTER TABLE + + ADD FOREIGN KEY ( + + ) REFERENCES + + ( + + ); + + + + + + + + + diff --git a/resources/js/hayamiki_designer/db/vfp9/readme_vfp9.txt b/resources/js/hayamiki_designer/db/vfp9/readme_vfp9.txt new file mode 100644 index 0000000..c3e3957 --- /dev/null +++ b/resources/js/hayamiki_designer/db/vfp9/readme_vfp9.txt @@ -0,0 +1,42 @@ +07.12.2009 + vfp9 support for WwwSQLDesigner + by zvolsky@seznam.cz + + +Installation: +------------- +vfp9 support is standard part of WwwSQLDesigner - simple choose database vfp9 in Settings. + +You can change the generated script by patch/replace of db\vfp9\output.xsl. + + +WwwSQLDesigner basics: +---------------------- +To start click Index.html. +Never use Page Refresh (F5) - data will be lost! +Use Save button to generate FoxPro script with CREATE TABLEs. +Use Save/Read and Save XML buttons to generate XML and copy-paste it into text file to save your work. +Use Save/Read and Read XML buttons to continue work. + + +Use of VFP9 support: +-------------------- +Textbox "Default" in Field adding has different meaning. Here you can enter all foxpro keywords, which follow field definition. +No word "DEFAULT" is added. To use some DEFAULT, write "DEFAULT value". If you let just "NULL" in Textbox "Default", +you will receive FoxPro error. Write "DEFAULT .NULL." instead. + +Data types Binary aren't in list. Use standard Varchar, Character, Memo instead and write "NOCPTRANS" into the "Default" textbox. + +Data type "Integer (not key)" differents (from the primary/foreign key) just in its color (but generates standard Integer). + + + +Generated VFP script contains (optional) parameters, which change behavior of CREATE TABLE commands: +teLongName gives a possibility to generate FREE or NAME keywords. +tcCommand can fire immediately after each CREATE TABLE (new table is selected). + F.e. "= MyProc( ALIAS(), m.lcTableComment, @lacComments )" gives access to alias and all comments from model inside MyProc() procedure. +tcPath can control path, where tables will be created. + +Comments aren't copied directly into target database. +Instead of this, they are prepared in lcTableComment variable (table comment) and in lacComments array (field comments) before &tcCommand call. +So you can work with comments in your user defined code as you want. diff --git a/resources/js/hayamiki_designer/db/web2py/datatypes.xml b/resources/js/hayamiki_designer/db/web2py/datatypes.xml new file mode 100644 index 0000000..2399140 --- /dev/null +++ b/resources/js/hayamiki_designer/db/web2py/datatypes.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/js/hayamiki_designer/db/web2py/output.xsl b/resources/js/hayamiki_designer/db/web2py/output.xsl new file mode 100644 index 0000000..26c2450 --- /dev/null +++ b/resources/js/hayamiki_designer/db/web2py/output.xsl @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dbOBJECT.define_table(" + + ", + + + + + + Field(" + + " + + + , + + + " + + ", length= + + + + , + + + " + + ", + + + + notnull=True, + + + + default= + + + None + + + + + + + + default=None + + + + + , "reference + + + + " + + + + + + , unique=True + + + ) + + + + + , + + + + + ) + + + + + + """ database class object creation (initialization) """ + if request.env.web2py_runtime_gae: # if running on Google App Engine + dbOBJECT = DAL('gae') # connect to Google BigTable + session.connect(request, response, db=dbOBJECT) # and store sessions and tickets there + else: # else use a normal relational database + dbOBJECT = DAL("sqlite://dbOBJECT.db") + + + + + + + + + + + + + + + + + + + + """ Relations between tables (remove fields you don't need from requires) """ + + + + + + + + dbOBJECT. + + . + + .requires=IS_IN_DB( dbOBJECT, ' + + .id', ' + + + + + + + + %( + + )s + + + + + ') + + + + + diff --git a/resources/js/hayamiki_designer/dropbox-oauth-receiver.html b/resources/js/hayamiki_designer/dropbox-oauth-receiver.html new file mode 100644 index 0000000..fd16bad --- /dev/null +++ b/resources/js/hayamiki_designer/dropbox-oauth-receiver.html @@ -0,0 +1,14 @@ + + + + + + + +

Dropbox sign-in successful

+ +

Please close this window.

+ + \ No newline at end of file diff --git a/resources/js/hayamiki_designer/images/ScreenLayout.png b/resources/js/hayamiki_designer/images/ScreenLayout.png new file mode 100644 index 0000000..310cb4f Binary files /dev/null and b/resources/js/hayamiki_designer/images/ScreenLayout.png differ diff --git a/resources/js/hayamiki_designer/images/addingKeys.png b/resources/js/hayamiki_designer/images/addingKeys.png new file mode 100644 index 0000000..ddb5be9 Binary files /dev/null and b/resources/js/hayamiki_designer/images/addingKeys.png differ diff --git a/resources/js/hayamiki_designer/images/back.png b/resources/js/hayamiki_designer/images/back.png new file mode 100644 index 0000000..ce52e1d Binary files /dev/null and b/resources/js/hayamiki_designer/images/back.png differ diff --git a/resources/js/hayamiki_designer/images/columnDetail.png b/resources/js/hayamiki_designer/images/columnDetail.png new file mode 100644 index 0000000..4eb9ba7 Binary files /dev/null and b/resources/js/hayamiki_designer/images/columnDetail.png differ diff --git a/resources/js/hayamiki_designer/images/constrained.png b/resources/js/hayamiki_designer/images/constrained.png new file mode 100644 index 0000000..04a6133 Binary files /dev/null and b/resources/js/hayamiki_designer/images/constrained.png differ diff --git a/resources/js/hayamiki_designer/images/down.gif b/resources/js/hayamiki_designer/images/down.gif new file mode 100644 index 0000000..3c188e6 Binary files /dev/null and b/resources/js/hayamiki_designer/images/down.gif differ diff --git a/resources/js/hayamiki_designer/images/editTable.png b/resources/js/hayamiki_designer/images/editTable.png new file mode 100644 index 0000000..1d8dfe6 Binary files /dev/null and b/resources/js/hayamiki_designer/images/editTable.png differ diff --git a/resources/js/hayamiki_designer/images/finalExample.png b/resources/js/hayamiki_designer/images/finalExample.png new file mode 100644 index 0000000..72203c2 Binary files /dev/null and b/resources/js/hayamiki_designer/images/finalExample.png differ diff --git a/resources/js/hayamiki_designer/images/selectedColumn.png b/resources/js/hayamiki_designer/images/selectedColumn.png new file mode 100644 index 0000000..ac0a388 Binary files /dev/null and b/resources/js/hayamiki_designer/images/selectedColumn.png differ diff --git a/resources/js/hayamiki_designer/images/throbber.gif b/resources/js/hayamiki_designer/images/throbber.gif new file mode 100644 index 0000000..cce32f2 Binary files /dev/null and b/resources/js/hayamiki_designer/images/throbber.gif differ diff --git a/resources/js/hayamiki_designer/images/up.gif b/resources/js/hayamiki_designer/images/up.gif new file mode 100644 index 0000000..1ac1a4c Binary files /dev/null and b/resources/js/hayamiki_designer/images/up.gif differ diff --git a/resources/js/hayamiki_designer/index.html b/resources/js/hayamiki_designer/index.html new file mode 100644 index 0000000..2f18564 --- /dev/null +++ b/resources/js/hayamiki_designer/index.html @@ -0,0 +1,282 @@ + + + + + WWW SQL Designer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ + + + + + + + +
+ + + + + + + + + +
+ + + +
+ +
+ +
+ +
+ +
+
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ * + + +
+ * + + +
+ + + + +
+ + + + +
+ + + +
+ * + + +
+ * + + +
+ * + + +
+ +
+ + * +
+ +
+ + + + + + + + + + +
+
+ +
+ + +
+
+ + + +
+
+ + + +
+
+ +
+
+
+ + +
+ + + + + +
+
+
+ + +
+
+
+ +
+
+ + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + +

+
+ +
+
+
+
+
+ +
+
+
+ +
+ + + + + + + + + + + +
+ + + +
+ + + +
+
+ + + diff --git a/resources/js/hayamiki_designer/js/config.js b/resources/js/hayamiki_designer/js/config.js new file mode 100644 index 0000000..f0e2440 --- /dev/null +++ b/resources/js/hayamiki_designer/js/config.js @@ -0,0 +1,30 @@ +var CONFIG = { + AVAILABLE_DBS: ["hayamiki"], + DEFAULT_DB: "hayamiki", + + AVAILABLE_LOCALES: ["ar", "cs", "de", "el", "en", "eo", "es", "fr", "hu", "it", "ja", "nl", "pl", "pt_BR", "ro", "ru", "sv", "zh"], + DEFAULT_LOCALE: "en", + + AVAILABLE_BACKENDS: ["php-mysql", "php-blank", "php-file", "php-sqlite", "php-mysql+file", "php-postgresql", "php-pdo", "perl-file", "php-cubrid", "asp-file"], + DEFAULT_BACKEND: ["php-mysql"], + + RELATION_THICKNESS: 2, + RELATION_SPACING: 15, + RELATION_COLORS: ["#000", "#800", "#080", "#008", "#088", "#808", "#088"], + + STATIC_PATH: "", + XHR_PATH: "", + + /* + * The key below needs to be set individually by you if you want to use the Dropbox load/save feature. + * To do that, first sign up with Dropbox (may require a specific developer / SDK sign-up), go to + * https://www.dropbox.com/developers/apps and use "Create app" to add a new "Dropbox API app". + * Limit the app to its own folder. Call it, for instance, "wwwsqldesigner". + * Under "OAuth 2", "Redirect URIs", add the URL to the "dropbox-oauth-receiver.html" file on your server. + * E.g, if you install wwwsqldesigner on your local web server under "http://localhost/sqldesigner/", then add + * http://localhost/sqldesigner/dropbox-oauth-receiver.html as a Redirection URI. + * Copy the shown "App key" and paste it here below instead of the null value: + */ + DROPBOX_KEY: null // such as: "d6stdscwewhl6sa" + +} diff --git a/resources/js/hayamiki_designer/js/globals.js b/resources/js/hayamiki_designer/js/globals.js new file mode 100644 index 0000000..46c7699 --- /dev/null +++ b/resources/js/hayamiki_designer/js/globals.js @@ -0,0 +1,65 @@ +function _(str) { /* getText */ + if (!(str in window.LOCALE)) { return str; } + return window.LOCALE[str]; +} + +if (typeof String.prototype.endsWith !== 'function') { + String.prototype.endsWith = function(suffix) { + return this.indexOf(suffix, this.length - suffix.length) !== -1; + }; +} + +if (!String.prototype.trim) { + String.prototype.trim = function() { + return this.match(/^\s*([\s\S]*?)\s*$/)[1]; + } +} + +if (!String.trim) { + String.trim = function(obj) { return String.prototype.trim.call(obj);} +} + +if (!Object.create) { + Object.create = function (o) { + if (arguments.length > 1) { throw new Error("Object.create polyfill only accepts the first parameter"); } + var tmp = function() {}; + tmp.prototype = o; + return new tmp(); + }; +} + +var DATATYPES = false; +var LOCALE = {}; +var SQL = { + _subscribers: {}, + + publish: function(message, publisher, data) { + var subscribers = this._subscribers[message] || []; + var obj = { + target: publisher, + data: data + } + subscribers.forEach(function(subscriber) { subscriber(obj); }); + }, + + subscribe: function(message, subscriber) { + if (!(message in this._subscribers)) { + this._subscribers[message] = []; + } + var index = this._subscribers[message].indexOf(subscriber); + if (index == -1) { this._subscribers[message].push(subscriber); } + }, + + unsubscribe: function(message, subscriber) { + var index = this._subscribers[message].indexOf(subscriber); + if (index > -1) { this._subscribers[message].splice(index, 1); } + }, + + escape: function(str) { + return str.replace(/&/g, "&").replace(/>/g, ">").replace(/= (5*1024*1024)/2) { /* this is a very big db structure... */ + alert("Warning: your database structure is above 5 megabytes in size, this is above the localStorage single key limit allowed by some browsers, example Mozilla Firefox 10"); + return; + } + + var key = this.promptName("serversaveprompt"); + if (!key) { return; } + + key = "wwwsqldesigner_databases_" + (key || "default"); + + try { + localStorage.setItem(key, xml); + if (localStorage.getItem(key) != xml) { throw new Error("Content verification failed"); } + } catch (e) { + alert("Error saving database structure to localStorage! ("+e.message+")"); + } +} + +SQL.IO.prototype.clientlocalload = function() { + if (!window.localStorage) { + alert("Sorry, your browser does not seem to support localStorage."); + return; + } + + var key = this.promptName("serverloadprompt"); + if (!key) { return; } + + key = "wwwsqldesigner_databases_" + (key || "default"); + + try { + var xml = localStorage.getItem(key); + if (!xml) { throw new Error("No data available"); } + } catch (e) { + alert("Error loading database structure from localStorage! ("+e.message+")"); + return; + } + + this.fromXMLText(xml); +} + +SQL.IO.prototype.clientlocallist = function() { + if (!window.localStorage) { + alert("Sorry, your browser does not seem to support localStorage."); + return; + } + + /* --- Define some useful vars --- */ + var baseKeysName = "wwwsqldesigner_databases_"; + var localLen = localStorage.length; + var data = ""; + var schemasFound = false; + var code = 200; + + /* --- work --- */ + try { + for (var i = 0; i< localLen; ++i) { + var key = localStorage.key(i); + if((new RegExp(baseKeysName)).test(key)) { + var result = key.substring(baseKeysName.length); + schemasFound = true; + data += result + "\n"; + } + } + if (!schemasFound) { + throw new Error("No data available"); + } + } catch (e) { + alert("Error loading database names from localStorage! ("+e.message+")"); + return; + } + this.listresponse(data, code); +} + +/* ------------------------- Dropbox start ------------------------ */ + +/** + * The following code uses this lib: https://github.com/dropbox/dropbox-js + */ +SQL.IO.prototype.dropBoxInit = function() { + if (CONFIG.DROPBOX_KEY) { + this.dropboxClient = new Dropbox.Client({ key: CONFIG.DROPBOX_KEY }); + } else { + this.dropboxClient = null; + // Hide the Dropbox buttons + var elems = document.querySelectorAll("[id^=dropbox]"); // gets all tags whose id start with "dropbox" + [].slice.call(elems).forEach( + function(elem) { elem.style.display = "none"; } + ); + } +} + +SQL.IO.prototype.showDropboxError = function(error) { + var prefix = _("Dropbox error")+": "; + var msg = error.status; + + switch (error.status) { + case Dropbox.ApiError.INVALID_TOKEN: + // If you're using dropbox.js, the only cause behind this error is that + // the user token expired. + // Get the user through the authentication flow again. + msg = _("Token expired - retry the operation, authenticating again with Dropbox"); + this.dropboxClient.reset(); + break; + + case Dropbox.ApiError.NOT_FOUND: + // The file or folder you tried to access is not in the user's Dropbox. + // Handling this error is specific to your application. + msg = _("File not found"); + break; + + case Dropbox.ApiError.OVER_QUOTA: + // The user is over their Dropbox quota. + // Tell them their Dropbox is full. Refreshing the page won't help. + msg = _("Dropbox is full"); + break; + + case Dropbox.ApiError.RATE_LIMITED: + // Too many API requests. Tell the user to try again later. + // Long-term, optimize your code to use fewer API calls. + break; + + case Dropbox.ApiError.NETWORK_ERROR: + // An error occurred at the XMLHttpRequest layer. + // Most likely, the user's network connection is down. + // API calls will not succeed until the user gets back online. + msg = _("Network error"); + break; + + case Dropbox.ApiError.INVALID_PARAM: + case Dropbox.ApiError.OAUTH_ERROR: + case Dropbox.ApiError.INVALID_METHOD: + default: + // Caused by a bug in dropbox.js, in your application, or in Dropbox. + // Tell the user an error occurred, ask them to refresh the page. + } + + alert (prefix+msg); +}; + +SQL.IO.prototype.showDropboxAuthenticate = function(connectedCallBack) { + if (!this.dropboxClient) return false; + + // We want to use a popup window for authentication as the default redirection won't work for us as it'll make us lose our schema data + var href = window.location.href; + var prefix = href.substring(0, href.lastIndexOf('/')) + "/"; + this.dropboxClient.authDriver(new Dropbox.AuthDriver.Popup({ receiverUrl: prefix+"dropbox-oauth-receiver.html" })); + + // Now let's authenticate us + var sql_io = this; + sql_io.dropboxClient.authenticate( function(error, client) { + if (error) { + sql_io.showDropboxError(error); + } else { + // We're authenticated + connectedCallBack(); + } + return; + }); + + return true; +} + +SQL.IO.prototype.dropboxsave = function() { + var sql_io = this; + sql_io.showDropboxAuthenticate( function() { + var key = sql_io.promptName("serversaveprompt", ".xml"); + if (!key) { return; } + + var filename = (key || "default") + ".xml"; + + sql_io.listresponse("Saving...", 200); + var xml = sql_io.owner.toXML(); + sql_io.dropboxClient.writeFile(filename, xml, function(error, stat) { + if (error) { + sql_io.listresponse("", 200); + return sql_io.showDropboxError(error); + } + sql_io.listresponse(filename+" "+_("was saved to Dropbox"), 200); + }); + }); +} + +SQL.IO.prototype.dropboxload = function() { + var sql_io = this; + sql_io.showDropboxAuthenticate( function() { + var key = sql_io.promptName("serverloadprompt", ".xml"); + if (!key) { return; } + + var filename = (key || "default") + ".xml"; + + sql_io.listresponse("Loading...", 200); + sql_io.dropboxClient.readFile(filename, function(error, data) { + sql_io.listresponse("", 200); + if (error) { + return sql_io.showDropboxError(error); + } + sql_io.fromXMLText(data); + }); + }); +} + +SQL.IO.prototype.dropboxlist = function() { + var sql_io = this; + sql_io.showDropboxAuthenticate( function() { + sql_io.listresponse("Loading...", 200); + sql_io.dropboxClient.readdir("/", function(error, entries) { + if (error) { + sql_io.listresponse("", 200); + return sql_io.showDropboxError(error); + } + var data = entries.join("\n")+"\n"; + sql_io.listresponse(data, 200); + }); + }); +} + + +/* ------------------------- Dropbox end ------------------------ */ + +SQL.IO.prototype.clientsql = function() { + var bp = this.owner.getOption("staticpath"); + var path = bp + "db/"+window.DATATYPES.getAttribute("db")+"/output.xsl"; + this.owner.window.showThrobber(); + OZ.Request(path, this.finish.bind(this), {xml:true}); +} + +SQL.IO.prototype.finish = function(xslDoc) { + this.owner.window.hideThrobber(); + var xml = this.owner.toXML(); + var sql = ""; + try { + if (window.XSLTProcessor && window.DOMParser) { + var parser = new DOMParser(); + var xmlDoc = parser.parseFromString(xml, "text/xml"); + var xsl = new XSLTProcessor(); + xsl.importStylesheet(xslDoc); + var result = xsl.transformToDocument(xmlDoc); + sql = result.documentElement.textContent; + } else if (window.ActiveXObject || "ActiveXObject" in window) { + var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); + xmlDoc.loadXML(xml); + sql = xmlDoc.transformNode(xslDoc); + } else { + throw new Error("No XSLT processor available"); + } + } catch(e) { + alert(_("xmlerror")+': '+e.message); + return; + } + this.dom.ta.value = sql.trim(); +} + +SQL.IO.prototype.serversave = function(e, keyword) { + var name = keyword || prompt(_("serversaveprompt"), this._name); + if (!name) { return; } + this._name = name; + var xml = this.owner.toXML(); + var bp = this.owner.getOption("xhrpath"); + var url = bp + "backend/"+this.dom.backend.value+"/?action=save&keyword="+encodeURIComponent(name); + var h = {"Content-type":"application/xml"}; + this.owner.window.showThrobber(); + this.owner.setTitle(name); + OZ.Request(url, this.saveresponse, {xml:true, method:"post", data:xml, headers:h}); +} + +SQL.IO.prototype.quicksave = function(e) { + this.serversave(e, this._name); +} + +SQL.IO.prototype.serverload = function(e, keyword) { + var name = keyword || prompt(_("serverloadprompt"), this._name); + if (!name) { return; } + this._name = name; + var bp = this.owner.getOption("xhrpath"); + var url = bp + "backend/"+this.dom.backend.value+"/?action=load&keyword="+encodeURIComponent(name); + this.owner.window.showThrobber(); + this.name = name; + OZ.Request(url, this.loadresponse, {xml:true}); +} + +SQL.IO.prototype.serverlist = function(e) { + var bp = this.owner.getOption("xhrpath"); + var url = bp + "backend/"+this.dom.backend.value+"/?action=list"; + this.owner.window.showThrobber(); + OZ.Request(url, this.listresponse); +} + +SQL.IO.prototype.serverimport = function(e) { + var name = prompt(_("serverimportprompt"), ""); + if (!name) { return; } + var bp = this.owner.getOption("xhrpath"); + var url = bp + "backend/"+this.dom.backend.value+"/?action=import&database="+name; + this.owner.window.showThrobber(); + OZ.Request(url, this.importresponse, {xml:true}); +} + +SQL.IO.prototype.check = function(code) { + switch (code) { + case 201: + case 404: + case 500: + case 501: + case 503: + var lang = "http"+code; + this.dom.ta.value = _("httpresponse")+": "+_(lang); + return false; + break; + default: return true; + } +} + +SQL.IO.prototype.saveresponse = function(data, code) { + this.owner.window.hideThrobber(); + this.check(code); +} + +SQL.IO.prototype.loadresponse = function(data, code) { + this.owner.window.hideThrobber(); + if (!this.check(code)) { return; } + this.fromXML(data); + this.owner.setTitle(this.name); +} + +SQL.IO.prototype.listresponse = function(data, code) { + this.owner.window.hideThrobber(); + if (!this.check(code)) { return; } + this.dom.ta.value = data; +} + +SQL.IO.prototype.importresponse = function(data, code) { + this.owner.window.hideThrobber(); + if (!this.check(code)) { return; } + if (this.fromXML(data)) { + this.owner.alignTables(); + } +} + +SQL.IO.prototype.press = function(e) { + switch (e.keyCode) { + case 113: + if (OZ.opera) { + e.preventDefault(); + } + this.quicksave(e); + break; + } +} diff --git a/resources/js/hayamiki_designer/js/key.js b/resources/js/hayamiki_designer/js/key.js new file mode 100644 index 0000000..c1eb8b2 --- /dev/null +++ b/resources/js/hayamiki_designer/js/key.js @@ -0,0 +1,72 @@ +/* --------------------- db index ------------ */ +SQL.Key = function(owner, type, name) { + this.owner = owner; + this.rows = []; + this.type = type || "INDEX"; + this.name = name || ""; + SQL.Visual.apply(this); +} +SQL.Key.prototype = Object.create(SQL.Visual.prototype); + +SQL.Key.prototype.setName = function(n) { + this.name = n; +} + +SQL.Key.prototype.getName = function() { + return this.name; +} + +SQL.Key.prototype.setType = function(t) { + if (!t) { return; } + this.type = t; + for (var i=0;i\n'; + for (var i=0;i\n'; + } + xml += '\n'; + return xml; +} + +SQL.Key.prototype.fromXML = function(node) { + this.setType(node.getAttribute("type")); + this.setName(node.getAttribute("name")); + var parts = node.getElementsByTagName("part"); + for (var i=0;i=0;i--) { + var k = this.table.keys[i]; + if (!k.rows.length) { this.table.removeKey(k); } + } +} + +SQL.KeyManager.prototype.sync = function(table) { /* sync content with given table */ + this.table = table; + this.dom.listlabel.innerHTML = _("keyslistlabel").replace(/%s/,table.getTitle()); + + OZ.DOM.clear(this.dom.list); + for (var i=0;i 1) { return; } + var event = e.touches[0]; + } else { + var event = e; + } + + var dx = event.clientX - this.x; + var dy = event.clientY - this.y; + if (this.l + dx < 0) { dx = -this.l; } + if (this.t + dy < 0) { dy = -this.t; } + if (this.l + this.w + 4 + dx > this.width) { dx = this.width - 4 - this.l - this.w; } + if (this.t + this.h + 4 + dy > this.height) { dy = this.height - 4 - this.t - this.h; } + + + this.x += dx; + this.y += dy; + + this.l += dx; + this.t += dy; + + var coefX = this.width / this.owner.width; + var coefY = this.height / this.owner.height; + var left = this.l / coefX; + var top = this.t / coefY; + + if (OZ.webkit) { + document.body.scrollLeft = Math.round(left); + document.body.scrollTop = Math.round(top); + } else { + document.documentElement.scrollLeft = Math.round(left); + document.documentElement.scrollTop = Math.round(top); + } + + this.redraw(); +} + +SQL.Map.prototype.up = function(e) { /* mouseup */ + this.flag = false; + this.dom.container.style.cursor = ""; + OZ.Event.remove(this.documentMove); + OZ.Event.remove(this.documentUp); +} + +SQL.Map.prototype.sync = function() { /* when window changes, adjust map */ + var dims = OZ.DOM.win(); + var scroll = OZ.DOM.scroll(); + var scaleX = this.width / this.owner.width; + var scaleY = this.height / this.owner.height; + + var w = dims[0] * scaleX - 4 - 0; + var h = dims[1] * scaleY - 4 - 0; + var x = scroll[0] * scaleX; + var y = scroll[1] * scaleY; + + this.w = Math.round(w); + this.h = Math.round(h); + this.l = Math.round(x); + this.t = Math.round(y); + + this.redraw(); +} + +SQL.Map.prototype.redraw = function() { + this.dom.port.style.width = this.w+"px"; + this.dom.port.style.height = this.h+"px"; + this.dom.port.style.left = this.l+"px"; + this.dom.port.style.top = this.t+"px"; +} diff --git a/resources/js/hayamiki_designer/js/options.js b/resources/js/hayamiki_designer/js/options.js new file mode 100644 index 0000000..90854e5 --- /dev/null +++ b/resources/js/hayamiki_designer/js/options.js @@ -0,0 +1,76 @@ +/* --------------------- options ------------ */ + +SQL.Options = function(owner) { + this.owner = owner; + this.dom = { + container:OZ.$("opts"), + btn:OZ.$("options") + } + this.dom.btn.value = _("options"); + this.save = this.save.bind(this); + this.build(); +} + +SQL.Options.prototype.build = function() { + this.dom.optionlocale = OZ.$("optionlocale"); + this.dom.optiondb = OZ.$("optiondb"); + this.dom.optionsnap = OZ.$("optionsnap"); + this.dom.optionpattern = OZ.$("optionpattern"); + this.dom.optionhide = OZ.$("optionhide"); + this.dom.optionvector = OZ.$("optionvector"); + this.dom.optionshowsize = OZ.$("optionshowsize"); + this.dom.optionshowtype = OZ.$("optionshowtype"); + + var ids = ["language","db","snap","pattern","hide","vector","showsize","showtype","optionsnapnotice","optionpatternnotice","optionsnotice"]; + for (var i=0;i-1;i--) { + if (i in this && this[i] === item) { return i; } + } + return -1; + } +} +if (!Array.lastIndexOf) { + Array.lastIndexOf = function(obj, item, from) { return Array.prototype.lastIndexOf.call(obj, item, from); } +} + +if (!Array.prototype.forEach) { + Array.prototype.forEach = function(cb, _this) { + var len = this.length; + for (var i=0;i\n'; + + var elm = this.getDataType(); + var t = elm.getAttribute("sql"); + if (this.data.size.length) { t += "("+this.data.size+")"; } + xml += ""+t+"\n"; + + if (this.data.def || this.data.def === null) { + var q = elm.getAttribute("quote"); + var d = this.data.def; + if (d === null) { + d = "NULL"; + } else if (d != "CURRENT_TIMESTAMP") { + d = q+d+q; + } + xml += ""+SQL.escape(d)+""; + } + + for (var i=0;i\n'; + } + + if (this.data.comment) { + xml += ""+SQL.escape(this.data.comment)+"\n"; + } + + xml += "\n"; + return xml; +} + +SQL.Row.prototype.fromXML = function(node) { + var name = node.getAttribute("name"); + + var obj = { type:0, size:"" }; + obj.nll = (node.getAttribute("null") == "1"); + obj.ai = (node.getAttribute("autoincrement") == "1"); + + var cs = node.getElementsByTagName("comment"); + if (cs.length && cs[0].firstChild) { obj.comment = cs[0].firstChild.nodeValue; } + + var d = node.getElementsByTagName("datatype"); + if (d.length && d[0].firstChild) { + var s = d[0].firstChild.nodeValue; + var r = s.match(/^([^\(]+)(\((.*)\))?.*$/); + var type = r[1]; + if (r[3]) { obj.size = r[3]; } + var types = window.DATATYPES.getElementsByTagName("type"); + for (var i=0;i 0; +} + +SQL.Row.prototype.enter = function(e) { + if (e.keyCode == 13) { + this.collapse(); + } +} diff --git a/resources/js/hayamiki_designer/js/rowmanager.js b/resources/js/hayamiki_designer/js/rowmanager.js new file mode 100644 index 0000000..baa643d --- /dev/null +++ b/resources/js/hayamiki_designer/js/rowmanager.js @@ -0,0 +1,188 @@ +/* --------------------- row manager ------------ */ +SQL.RowManager = function(owner) { + this.owner = owner; + this.dom = {}; + this.selected = null; + this.creating = false; + this.connecting = false; + + var ids = ["editrow","removerow","uprow","downrow","foreigncreate","foreignconnect","foreigndisconnect"]; + for (var i=0;i=0;i--) { + var r = rels[i]; + if (r.row2 == this.selected) { this.owner.removeRelation(r); } + } + this.redraw(); +} + +SQL.RowManager.prototype.endCreate = function() { + this.creating = false; + this.dom.foreigncreate.value = _("foreigncreate"); +} + +SQL.RowManager.prototype.endConnect = function() { + this.connecting = false; + this.dom.foreignconnect.value = _("foreignconnect"); +} + +SQL.RowManager.prototype.up = function(e) { + this.selected.up(); + this.redraw(); +} + +SQL.RowManager.prototype.down = function(e) { + this.selected.down(); + this.redraw(); +} + +SQL.RowManager.prototype.remove = function(e) { + var result = confirm(_("confirmrow")+" '"+this.selected.getTitle()+"' ?"); + if (!result) { return; } + var t = this.selected.owner; + this.selected.owner.removeRow(this.selected); + + var next = false; + if (t.rows) { next = t.rows[t.rows.length-1]; } + this.select(next); +} + +SQL.RowManager.prototype.redraw = function() { + this.endCreate(); + this.endConnect(); + if (this.selected) { + var table = this.selected.owner; + var rows = table.rows; + this.dom.uprow.disabled = (rows[0] == this.selected); + this.dom.downrow.disabled = (rows[rows.length-1] == this.selected); + this.dom.removerow.disabled = false; + this.dom.editrow.disabled = false; + this.dom.foreigncreate.disabled = !(this.selected.isUnique()); + this.dom.foreignconnect.disabled = !(this.selected.isUnique()); + + this.dom.foreigndisconnect.disabled = true; + var rels = this.selected.relations; + for (var i=0;i\n'; + for (var i=0;i\n"; + } + xml += "\n"; + return xml; +} + +SQL.Table.prototype.fromXML = function(node) { + var name = node.getAttribute("name"); + this.setTitle(name); + var x = parseInt(node.getAttribute("x")) || 0; + var y = parseInt(node.getAttribute("y")) || 0; + this.moveTo(x, y); + var rows = node.getElementsByTagName("row"); + for (var i=0;i 1) { return; } + var event = e.touches[0]; + } else { + var event = e; + } + + for (var i=0;i 1) { this.dom.removetable.value = _("removetables"); } + } else { + this.dom.removetable.disabled = true; + this.dom.removetable.value = _("removetable"); + } + for (var i=0;i=x && tx=x && tx1x1)) && + ((ty>=y && ty=y && ty1y1))) + { this.selection.push(t); } + } + this.processSelection(); +} + +SQL.TableManager.prototype.click = function(e) { /* finish adding new table */ + var newtable = false; + if (this.adding) { + this.adding = false; + OZ.DOM.removeClass("area","adding"); + this.dom.addtable.value = this.oldvalue; + var scroll = OZ.DOM.scroll(); + var x = e.clientX + scroll[0]; + var y = e.clientY + scroll[1]; + newtable = this.owner.addTable(_("newtable"),x,y); + var r = newtable.addRow("id",{ai:true}); + var k = newtable.addKey("PRIMARY",""); + k.addRow(r); + } + this.select(newtable); + this.owner.rowManager.select(false); + if (this.selection.length == 1) { this.edit(e); } +} + +SQL.TableManager.prototype.preAdd = function(e) { /* click add new table */ + if (this.adding) { + this.adding = false; + OZ.DOM.removeClass("area","adding"); + this.dom.addtable.value = this.oldvalue; + } else { + this.adding = true; + OZ.DOM.addClass("area","adding"); + this.oldvalue = this.dom.addtable.value; + this.dom.addtable.value = "["+_("addpending")+"]"; + } +} + +SQL.TableManager.prototype.clear = function(e) { /* remove all tables */ + if (!this.owner.tables.length) { return; } + var result = confirm(_("confirmall")+" ?"); + if (!result) { return; } + this.owner.clearTables(); +} + +SQL.TableManager.prototype.remove = function(e) { + var titles = this.selection.slice(0); + for (var i=0;i 1) { this.dom.title.removeChild(this.dom.title.childNodes[1]); } + + var txt = OZ.DOM.text(title); + this.dom.title.appendChild(txt); + this.dom.background.style.visibility = "visible"; + OZ.DOM.clear(this.dom.content); + this.dom.content.appendChild(content); + + var win = OZ.DOM.win(); + var scroll = OZ.DOM.scroll(); + this.dom.container.style.left = Math.round(scroll[0] + (win[0] - this.dom.container.offsetWidth)/2)+"px"; + this.dom.container.style.top = Math.round(scroll[1] + (win[1] - this.dom.container.offsetHeight)/2)+"px"; + + this.dom.cancel.style.visibility = (this.callback ? "" : "hidden"); + this.dom.container.style.visibility = "visible"; + + var formElements = ["input","select","textarea"]; + var all = this.dom.container.getElementsByTagName("*"); + for (var i=0;i max) { max = z; } + } + + OZ.$("controls").style.zIndex = max+5; + return max; +} + +SQL.Designer.prototype.addTable = function(name, x, y) { + var max = this.getMaxZ(); + var t = new SQL.Table(this, name, x, y, max+1); + this.tables.push(t); + this.dom.container.appendChild(t.dom.container); + return t; +} + +SQL.Designer.prototype.removeTable = function(t) { + this.tableManager.select(false); + this.rowManager.select(false); + var idx = this.tables.indexOf(t); + if (idx == -1) { return; } + t.destroy(); + this.tables.splice(idx,1); +} + +SQL.Designer.prototype.addRelation = function(row1, row2) { + var r = new SQL.Relation(this, row1, row2); + this.relations.push(r); + return r; +} + +SQL.Designer.prototype.removeRelation = function(r) { + var idx = this.relations.indexOf(r); + if (idx == -1) { return; } + r.destroy(); + this.relations.splice(idx,1); +} + +SQL.Designer.prototype.getCookie = function() { + var c = document.cookie; + var obj = {}; + var parts = c.split(";"); + for (var i=0;i old) { t.setZ(t.getZ()-1); } + } + var m = table.dom.mini; + m.parentNode.appendChild(m); +} + +SQL.Designer.prototype.clearTables = function() { + while (this.tables.length) { this.removeTable(this.tables[0]); } + this.setTitle(false); +} + +SQL.Designer.prototype.alignTables = function() { + var win = OZ.DOM.win(); + var avail = win[0] - OZ.$("bar").offsetWidth; + var x = 10; + var y = 10; + var max = 0; + + this.tables.sort(function(a,b){ + return b.getRelations().length - a.getRelations().length; + }); + + for (var i=0;i avail) { + x = 10; + y += 10 + max; + max = 0; + } + t.moveTo(x,y); + x += 10 + w; + if (h > max) { max = h; } + } + + this.sync(); +} + +SQL.Designer.prototype.findNamedTable = function(name) { /* find row specified as table(row) */ + for (var i=0;i\n'; + xml += '\n'; + + /* serialize datatypes */ + if (window.XMLSerializer) { + var s = new XMLSerializer(); + xml += s.serializeToString(window.DATATYPES); + } else if (window.DATATYPES.xml) { + xml += window.DATATYPES.xml; + } else { + alert(_("errorxml")+': '+e.message); + } + + for (var i=0;i + + + إنشاء جدول + تحرير جدول + حذف جدول + محاذاة الجداول + حذف جميع البيانات + هل أنت متأكد من أنك تريد حذف جميع البيانات + new table + اختر المنطقة المحددة + اسم الجول + وصف الجدول + + + إنشاء حقل + تحرير حقل + حذف حقل + أعلى + أسفل + new field + إنشاء مفتاح خارجي + اختر الجدول المطلوب + ربط حقل بمفتاح خارجي + اختر الحقل المطلوب + حذف مفتاح خارجي + هل أنت متأكد من أنك تريد حذف الجدول + هل أنت متأكد من أنك تريد حذف الحقل + + + الإسم + النوع + الحجم + الإفتراضي + NOT NULL + NULL + ترقيم تلقائي + تحرير تعليق + اكتب تعليقاً لهذا الحقل + + + موافق + إلغاء + يرجى الإنتظار ... + الخيارات + لغة العرض + قاعدة البيانات المستخدمة لحفظ التصاميم + بعض الخيارات يتم تفعيلها بعد تحديث الصفحة مع ملاحظة أنه يجب تفعيل (الكوكيز) لتعمل هذه الخيارات + Table snap distance + In pixels, 0 = disable snapping + طريقة تنسيق أسماء المفاتيح الخارجية + %T = الجدول الرئيسي, %R = المفتاح الرئيسي, %t = الجدول الخارجي + إخفاء الخطوط عند تحريك الجدول؟ + رسم خطوط ناعمة (إذا كان المتصفح يدعم ذلك) ؟ + + + + المفاتيح + المفاتيح في الجدول "%s" + الأنواع: + الإسم: + مفاتيح الجدول + الحقول المتاحة + تحرير مفتاح + إنشاء مفتاح + حذف مفتاح + + + حفظ / تحميل + قم بوضع بيانات نموذج XML في المربع أدناه، ثم حاول مرّة أخرى. + العميل + الخادم + المدخلات / المخرجات + حفظ كنموذح XML + إستيراد نموذج XML + حفظ كنموذج SQL + Server backend: + حفظ + تحميل + List items + إستيراد من قاعدة بيانات + Enter keyword under which your design was saved: + Enter keyword under which your design will be saved: + أدخل إسم قاعدة البيانات التي تريد إستيرادها: + رد الخادم + تم الحفظ بنجاح + لم يتم العثور عليه + خطأ داخلي في الخادم + الخاصية غير موجودة + الخدمة غير متوفرة + + + خطأ في نموذح XML + التوثيق + + diff --git a/resources/js/hayamiki_designer/locale/cs.xml b/resources/js/hayamiki_designer/locale/cs.xml new file mode 100644 index 0000000..177d2d4 --- /dev/null +++ b/resources/js/hayamiki_designer/locale/cs.xml @@ -0,0 +1,101 @@ + + + + Přidat tabulku + Upravit tabulku + Smazat tabulku + Smazat tabulky + Srovnat tabulky + Zrušit tabulky + Opravdu zrušit všechny tabulky + nová tabulka + umístit tabulku + Jméno + Komentář + + + Přidat položku + Upravit položku + Smazat položku + Nahoru + Dolů + nová položka + Vyrobit cizí klíč + klikni na cílovou tabulku + Propojit cizí klíč + klikni na cílové pole + Smazat cizí klíč + Opravdu smazat tabulku + Opravdu smazat položku + + + Jméno + Typ + Velikost + Výchozí + NOT NULL + NULL + Autoincrement + Upravit komentář + VLožte komentář pro tuto položku + + + OK + Storno + Prosím čekejte... + Nastavení + Jazyk + Databáze pro nová schémata + Některá nastavení se projeví až po znovunačtení stránky. Aby nastavení fungovala, je nutné mít zapnuté cookies. + Vzdálenost přichytávání tabulek + V pixelech, 0 = bez přichytávání + Vzor pro cizí jména + %T = primární tabulka, %R = primární klíč, %t = cizí tabulka + Schovat spojovníky při tažení tabulkou? + Vykreslovat oblé spojovníky (pakliže to prohlížeč podporuje)? + Zobrazovat velikost polí v tabulce? + Zobrazovat datový typ polí v tabulce? + + + Klíče + Klíče v tabulce "%s" + Typ: + Název: + Položky v klíči + Dostupné položky + Upravit klíč + Přidat klíč + Smazat klíč + + + Uložit / Načíst + Prosím vložte XML data do textového pole níže. + Klient + Server + Vstup / Výstup + Uložit XML + Načíst XML + Uložit v prohlížeči + Načíst z prohlížeče + Generovat SQL + Server backend: + Uložit + Rychle uložit + Načíst + Vypsat položky + Importovat z databáze + Zadejte označení, pod kterým bylo vaše schéma uloženo: + Zadejte označení, pod kterým bude vaše schéma uloženo: + Zadejte název databáze k importu: + Odpověď od serveru + Uloženo + Neexistuje + Vnitřní chyba serveru + Není implementováno + Služba není dostupná + + + XML chyba + Dokumentace + + diff --git a/resources/js/hayamiki_designer/locale/de.xml b/resources/js/hayamiki_designer/locale/de.xml new file mode 100644 index 0000000..46d4f23 --- /dev/null +++ b/resources/js/hayamiki_designer/locale/de.xml @@ -0,0 +1,97 @@ + + + + Tabelle hinzufügen + Tabelle bearbeiten + Tabelle entfernen + Tabellen entfernen + Tabellen ausrichten + Tabellen löschen + Wirklich alle Tabellen löschen + Neue Tabelle + Tabelle plazieren + Name + Kommentar + + + Feld hinzufügen + Feld bearbeiten + Feld entfernen + Hoch + Runter + Neues Feld + Fremdschlüssel erstellen + Ziel-Tabelle wählen + Fremdschlüssel Verknüpfung + Ziel-Zeile auswählen + Ziel-Zeile entfernen + Tabelle wirklich löschen + Feld wirklich löschen + + + Name + Typ + Größe + Default + NOT NULL + NULL + Autoincrement + Kommentar bearbeiten + Kommentar zu diesem Feld eintragen: + + + OK + Abbrechen + Bitte warten... + Einstellungen + Sprache + Datenbank für neue Diagramme + Einige Optionen werden erst nach einem erneutem Seitenaufruf wirksam. Cookies müssen erlaubt sein. + Tabellen Ausrichtungsabstand + in Pixel, 0 = einrasten deaktivieren + Format für die Namen der Fremdschlüssel + %T = Primärtabelle, %R = Primärschlüssel, %t = Fremdtabelle + Verstecke Verbindungslinien beim bewegen von Tabellen? + Zeichne gegrümmte Verbindungslinien (Browser-abhängig)? + + + + Schlüssel + Schlüssel in Tabelle "%s" + Typ: + Name: + Felder im Schlüssel + Verfügbare Felder + Schlüssel bearbeiten + Schlüssel hinzufügen + Schlüssel entfernen + + + Speichern / Laden + Bitte fügen Sie die XML-Daten in das untere Textfeld ein und versuchen es erneut. + Client + Server + Eingabe / Ausgabe + XML speichern + XML laden + SQL erzeugen + Server Basis: + Speichern + Laden + Einträge listen + Import aus DB + Geben Sie das Stichwort ihres Diagramms ein, unter dem es gespeichert wurde: + Geben Sie das Stichwort ihres Diagramms ein, unter dem es gespeichert werden soll: + Geben Sie den Namen der zuimportierenden Datenbank ein: + Server Antwort + gespeichert + Nicht gefunden + Interner Server Fehler + Nicht implementiert + Dienst nicht erreichbar + + + XML Fehler + Dokumentation + + diff --git a/resources/js/hayamiki_designer/locale/el.xml b/resources/js/hayamiki_designer/locale/el.xml new file mode 100644 index 0000000..f157dfd --- /dev/null +++ b/resources/js/hayamiki_designer/locale/el.xml @@ -0,0 +1,97 @@ + + + + Προσθήκη πίνακα + Επεξεργασία πίνακα + Διαγραφή πίνακα + Διαγραφή πινάκων + Στοίχιση Πινάκων + Καθαρισμός πινάκων + Διαγραφή όλων των πινάκων + Νέος πίνακας + τοποθέτηση πίνακα + Όνομα + Σχόλιο + + + Προσθήκη πεδίου + Επεξεργασία πεδίου + Διαγραφή πεδίου + Πάνω + Κάτω + νέο πεδίο + Δημιουργία ξένου κλειδιού + Κάντε κλικ στο άλλο πίνακα + Σένδεση ξένου κλειδιού + Κάντε κλικ στη γραμμή + Κάντε κλικ πεδίου + Διαγραφή πίνακα. Είστε σίγουρος + Διαγραφή πεδίου. Είστε σίγουρος + + + Όνομα + Τύπος + Μέγεθος + Προεπιλογή + NOT NULL + NULL + Autoincrement + Επεξεργασία σχολίου + Σχολιάστε γι' αυτό το πεδίο + + + OK + Άκυρο + Παρακαλώ περιμένετε... + Επιλογές + Γλώσσα + Βάση δεδομένων για νέα σχέδιαγράμματα + Μερικές επιλογές ενεργοποιούνται μόνο μετά από καθολική ανανέωση της σελίδας.Τα Cookies πρέπει να είναι ενεργοποιημένα για να λειτουργούν οι επιλογές. + Απόσταση πινάκων + Σε pixels, 0 = απενεργοποίηση απόστασης + Πρότυπο για ξένα κλειδιά + %T = πρωτεύων πίνακας, %R = προτεύον κλειδί, %t = ξένος πίνακας + Απόκρυψη συνδέσμων όταν σύρονται οι πίνακες; + Διάγραμμα με ομαλούς συνδέσμους(αν παρέχεται από τον περιηγητή); + + + + Κλειδιά + Κλειδιά στον πίνακα "%s" + Τύπος: + Όνομα: + Πεδία σε κλειδιά + Διαθέσιμα πεδία + Επεξεργασία κλειδιού + Προσθήκη κλειδιού + Διαγραφή κλειδιού + + + Αποθήκ./Άνοιγμα + Κάντε επικόλληση των δεδομένων XML στο πεδίο κειμένου παρακάτω και δοκιμάστε ξανά. + Πελάτης + Διακομιστής + Εισαγωγή/Εξαγωγή + Αποθήκευση XML + Άνοιγμα XML + Δημιουργία SQL + Διακομιστής: + Αποθήκευση + Άνοιγμα + Εμφάνιση λίστας + Εισαγωγή από βάση δεδομένων + Πληκτρολογήστε το τίτλο του αποθηκευμένου σχεδιαγράμματος: + Πληκτρολογήστε το τίτλο για την αποθήκευση του σχεδιαγράμματος: + Δώστς όνομα βάσης δεδομένων για εισαγωγή: + Απάντηση διακομιστή + Αποθηκεύθηκε + Δεν βρέθηκε + Εσωτερικό σφάλμα διακομιστή + Χωρίς σχεδίαση + Μη-διαθέσιμη Παροχή + + + Σφάλμα XML + Οδηγίες + + diff --git a/resources/js/hayamiki_designer/locale/en.xml b/resources/js/hayamiki_designer/locale/en.xml new file mode 100644 index 0000000..51c42b6 --- /dev/null +++ b/resources/js/hayamiki_designer/locale/en.xml @@ -0,0 +1,105 @@ + + + + Add table + Edit table + Remove table + Remove tables + Align tables + Clear tables + Really delete all tables + new table + place table + Name + Comment + + + Add field + Edit field + Remove field + Up + Down + new field + Create foreign key + click target table + Connect foreign key + click target row + Remove foreign key + Really delete table + Really delete field + + + Name + Type + Size + Default + NOT NULL + NULL + Autoincrement + Edit comment + Enter comment for this field + + + OK + Cancel + Please wait... + Options + Language + Database for new designs + Some options are applied only after full page reload. Cookies must be enabled for options to work. + Table snap distance + In pixels, 0 = disable snapping + Pattern for foreign names + %T = primary table, %R = primary key, %t = foreign table + Hide connectors on table drag? + Draw smooth connectors (if supported by browser)? + Show field size in table design? + Show field datatype in table design? + + + Keys + Keys in table "%s" + Type: + Name: + Fields in key + Available fields + Edit key + Add key + Remove key + + + Save / Load + Please paste XML data into the text area below and try again. + Client + Server + Input / Output + Save XML + Load XML + Save in Browser + Load from Browser + List from Browser + Save to Dropbox + Load from Dropbox + List from Dropbox + Generate SQL + Server backend: + Save + Quicksave + Load + List items + Import from DB + Enter keyword under which your design was saved: + Enter keyword under which your design will be saved: + Enter name of database to be imported: + Server response + Saved + Not Found + Internal Server Error + Not Implemented + Service Unavailable + + + XML error + Documentation + + diff --git a/resources/js/hayamiki_designer/locale/eo.xml b/resources/js/hayamiki_designer/locale/eo.xml new file mode 100644 index 0000000..cb5b3d3 --- /dev/null +++ b/resources/js/hayamiki_designer/locale/eo.xml @@ -0,0 +1,99 @@ + + + + Aldoni tabelon + Modifi la tabelon + Forigi la tabelon + Forigi la tabelojn + Ĝisrandigi la tabelojn + Vakigi la tabelon + Ja forigi ĉiujn tabelojn + nova tabelo + pozicii la tabelon + Nomo + Komento + + + Aldoni kampon + Modifi la kampon + Forigi la kampon + Supre + Sube + nova kampo + Krei fremdan ŝlosilon + alklaki la celan tabelon + Konekti fremdan ŝlosilon + alklaki la celan atributon + Forigi fremdan ŝlosilon + Ja forigi la tabelon + Ja forigi la kampon + + + Nomo + Tipo + Grandeco + Defaŭlte + NE NUL + Senvalora + Memalkremento + Modifi la komenton + Entajpi komenton por tiu kampo + + + Jes + Rezigni + Bonvolu atendi... + Agordoj + Lingvo + Datumbazoj por novaj kreoj + Kelkaj agordoj estas aplikotaj post plena ŝarĝo de paĝo. Kuketoj devas esti ebligataj por ke la agordoj funkcias. + Kapto-distanco de tabelo + En rastrumeroj, 0 = malebligi kapton + Motivo por fremdaj nomoj + %T = ĉefa tabelo, %R = ĉefa ŝlosilo, %t = fremda tabelo + Ĉu kaŝi konektiloj dum treno de tabelo? + Desegni glatajn konektilojn (se subtenata de retumilo)? + Show field size in table design? + Show field datatype in table design? + + + Klavoj + Ŝlosiloj en la tabelo "%s" + Tipo: + Nomo: + Kampoj en klavo + Disponeblaj kampoj + Modifi ŝlosilon + Aldoni ŝlosilon + Forigi ŝlosilon + + + Konservi / Ŝargi + Bonvolu alglui XML datumon en la tekst-zono sube kaj provi de nove. + Kliento + Servilo + Enigo / Eligo + Konservi XML + Ŝargi XML + Krei SQL + Servila administro: + Konservi + Quicksave + Ŝargi + Listigi erojn + Importi el datumbazo + Entajpi ŝlosilvorton per kiu via fasonado estis konservita: + Entajpi ŝlosilvorton per kiu via fasonado estos konservita: + Entajpi la nomon de datumbazo importenda: + Respondo de servilo + Konservita + Netrovita + Interna Servilo Eraro + Ne funkciigata + Servo Nedisponebla + + + XML-eraro + Dokumentaro + + diff --git a/resources/js/hayamiki_designer/locale/es.xml b/resources/js/hayamiki_designer/locale/es.xml new file mode 100644 index 0000000..c895d59 --- /dev/null +++ b/resources/js/hayamiki_designer/locale/es.xml @@ -0,0 +1,98 @@ + + + + Agregar tabla + Editar tabla + Remover tabla + Remover tablas + Alinear tablas + Limpiar tablas + Realmente borrar todas las tablas + Nueva tabla + Posicionar tabla + Nombre + Comentario + + + Agregar campo + Editar campo + Remover campo + Arriba + Abajo + Nuevo campo + Crear llave foránea + Conectar llave foránea + Conectar llave foránea + Hacer clic en el registro + Remover llave foránea + Realmente borrar tabla + Realmente borrar campo + + + Nombre + Tipo + Tamaño + Valor por predeterminado + NOT NULL + NULL + Auto incremento + Editar comentario + Entrar comentario para este campo + + + Aceptar + Cancelar + Por favor esperar... + Opciones + Lenguaje + Base de datos para nuevos diseños + Algunas opciones son aplicadas solo despúes de recargar totalmente la pagina. Las cookies deben estar +habilitadas para opciones de trabajo. + Tabla acceso remoto + En píxeles, 0 = deshabilitar acceso remoto + Patrón para nombres foráneos + %T = tabla primaria, %R = llave primaria, %t = tabla foránea + Esconder conectores en la tabla al arrastrar? + Dibujar conectores suave (si son soportados por el navegador)? + + + + Llaves + Llaves en la tabla "%s" + Tipo: + Nombre: + Campos en la llave + Campos disponibles + Editar llave + Agregar llave + Remover llave + + + Guardar / Cargar + Favor de pegar el XML dentro del área de texto siguiente e intentar nuevamente. + Cliente + Servidor + Entrada / Salida + Guardar XML + Cargar XML + Generar SQL + Servidor backend: + Guardar + Cargar + Lista de articulos + Importar desde BD + Entrar palabra bajo la cual tu diseño fue guardado: + Entrar palabra bajo la cual tu diseño va a ser guardado: + Entrar nombre de base de datos a ser importada: + Respuesta del servidor + Guardado + No Encontrado + Error Interno del Servidor + No Implementado + Servicio No Disponible + + + XML error + Documentación + + diff --git a/resources/js/hayamiki_designer/locale/fr.xml b/resources/js/hayamiki_designer/locale/fr.xml new file mode 100644 index 0000000..e7d3302 --- /dev/null +++ b/resources/js/hayamiki_designer/locale/fr.xml @@ -0,0 +1,102 @@ + + + + Ajouter une table + Éditer la table + Supprimer la table + Supprimer les tables + Aligner les tables + Supprimer les tables + Vraiment supprimer toutes les tables + nouvelle table + positionner la table + Nom + Commentaire + + + Ajouter un champ + Éditer un champ + Supprimer le champ + Remonter + Descendre + Éditer un champ + Créer une clé étrangère + Cliquez la destination + Connecter une clé étrangère + Cliquez la propriété cible + Supprimer la clé étrangère + Voulez-vous vraiment supprimer cette table ? + Voulez-vous vraiment supprimer ce champ ? + + + Nom + Type + Taille + Défaut + NON NUL + valeur nulle + Auto-incrémental + Éditer le commentaire + Saisir un commentaire à propos de ce champ + + + OK + Annuler + Veuillez patienter... + Options + Langue + Format des nouvelles base de données + Ces options ne seront appliquées qu'après le rafraichissement complet de la page. Les cookies doivent être autorisés. + Magnétisme des tables + En pixels, 0 = magnétisme désactivé + Motif pour les noms de clés étrangères + %T = table primaire, %R = clé primaire, %t = table étrangère + Cacher les connecteurs lors du déplacement des tables ? + Dessiner des connecteurs « adoucis » (si le navigateur le supporte) ? + Afficher la taille du champ dans le schéma de table ? + Afficher le type du champ dans le schéma de table ? + + + Clés + Clés dans la table « %s » + Type : + Nom : + Champs de clé + Champs disponibles + Éditer la clé + Ajouter une clé + Supprimer la clé + + + Enregistrer / Charger + Merci de coller les données XML dans le champs prévu avant de ré-essayer. + Client + Serveur + Entrée / Sortie + Enregistrer XML + Charger XML + Enregistrer dans le navigateur + Charger depuis le navigateur + Lister depuis le navigateur + Génerer SQL + Méthode du serveur : + Enregistrer + Enregistrer rapidement + Charger + Éléments disponibles + Importer d'une base de données + Saisir le mot-clé de votre schéma : + Saisir un mot-clé pour sauvegarder votre schéma : + Saisir le nom de la base de données à importer : + Réponse du serveur + Sauvegardé + Introuvable + Erreur interne du serveur + Non Implementé + Service indisponible + + + Erreur XML + Documentation + + diff --git a/resources/js/hayamiki_designer/locale/hu.xml b/resources/js/hayamiki_designer/locale/hu.xml new file mode 100644 index 0000000..c6ca773 --- /dev/null +++ b/resources/js/hayamiki_designer/locale/hu.xml @@ -0,0 +1,97 @@ + + + + Tábla létrehozása + Tábla módosítása + Tábla törlése + Táblak törlése + Táblák rendezése + Táblák törlése + Valóban töröljem az összes táblát + tábla létrehozása + tábla elhelyezése + Név + Megjegyzés + + + Mező létrehozása + Mező módosítása + Mező törlése + Fel + Le + új mező + Idegen kulcs létrehozása + kattintson a cél-táblára + Idegen kulcs kapcsolása + kattintson a cél-mezőre + Mező kulcs létrehozása + Valóban töröljem a táblát + Valóban töröljem a mezőt + + + Név + Típus + Méret + Alapérték + NOT NULL + NULL + Automatikus növelés + Megjegyzés módosítása + Írjon megjegyzést ehhez a mezőhöz + + + OK + Mégsem + Kérem várjon... + Beállítások + Nyelv + Adatbázis az új terveknek + Egyes beállítások csak az oldal teljes újratöltése után érvényesülnek. A munkához szükséges engedélyezni a sütiket (cooky-kat). + Táblák illesztési távolsága + Pixel-ben megadva, 0 = illesztés tiltása + Idegen nevek sablonja + %T = elsődleges tábla, %R = elsődleges kulcs, %t = idegen tábla + Elrejtsem a kapcsolókat a rajztáblán? + Kapcsolók finom kirajzolása (ha a böngésző lehetővé teszi)? + + + + Kulcsok + Kulcsok a "%s" táblában + Típus: + Név: + A kulcs mezői + Elérhető mezők + Kulcs módosítása + Kulcs létrehozása + Kulcs törlése + + + Mentés / Beolvasás + Kérem illessze be az XML-tartalmat az alábbi szöveges mezőbe, és próbálja újra. + Kliens + Szerver + Bemenet / Kimenet + XML mentése + XML beolvasása + SQL generálása + Szerver végpont: + Mentés + Betöltés + Tételek listázása + Importálás adatbázisból + Írja be a kulcsszót, amely alapján a tervet elmentette: + Írja be a kulcsszót, amely alapján a tervet el szeretné menteni: + Írja be az importálandó adatbázis nevét: + A szerver válasza + Elmentve + Nem találom + Belső szerver hiba + Nem lett végrehajtva + Szolgáltatás nem elérhető + + + XML hiba + Dokumentáció + + diff --git a/resources/js/hayamiki_designer/locale/it.xml b/resources/js/hayamiki_designer/locale/it.xml new file mode 100644 index 0000000..69e929d --- /dev/null +++ b/resources/js/hayamiki_designer/locale/it.xml @@ -0,0 +1,99 @@ + + + + Aggiungi tabella + Modifica tabella + Elimina tabella + Elimina tabelle + Allinea tabelle + Cancella tabelle + Eliminare veramente le tabelle + nuova tabella + posiziona la tabella + Nome + Oggetto + + + Aggiungi campo + Modifica campo + Elimina campo + Su + Giù + nuovo campo + Crea chiave esterna + fai clic sulla destinazione + Connetti chiave esterna + fai clic sulla riga di destinazione + Rimuovi chiave esterna + Cancellare veramente la tabella + Cancellare veramente la riga + + + Nome + Tipo + Dimensione + Predefinito + QUALCOSA + NULL + Autoincremento + Modifica commento + Inserisci commento per questo campo + + + Conferma + Annulla + Attendere... + Opzioni + Lingua + Database per nuovi progetti + Alcune opzioni diventano attive solo dopo il ricaricamento della pagina. Affinché le opzioni vengano mantenute, devono essere abilitati i cookies. + Griglia magnetica + In pixel, 0 = magnetismo disabilitato + Modello per le chiavi esterne + %T = tabella principale, %R = chiave primaria, %t = tabella secondaria + Nascondi i connettori durante il trascinamento? + Disegna connettori arrotondati (se supportato dal browser)? + Show field size in table design? + Show field datatype in table design? + + + Chiavi + Chiavi nella tabella "%s" + Tipo: + Nome: + Campi nella chiave + Campi disponibili + Modifica chiave + Aggiungi chiave + Rimuovi chiave + + + Salva / Carica + Reincolla i dati XML nell'area sottostante e prova di nuovo. + Intestatario + Server + Ingresso / Uscita + Salva XML + Carica XML + Genera SQL + Server di backend: + Salva + Quicksave + Carica + Elenca elementi + Importa dal DB + Inserisci la parola chiave con cui è stato salvato il progetto: + Inserisci la parola chiave con cui salvare il progetto: + Inserisci il nome del database da importare + Risposta del server + Salvato + Non trovato + Errore interno del server + Non implementato + Servizio non disponibile + + + Errore XML + Documentazione + + diff --git a/resources/js/hayamiki_designer/locale/ja.xml b/resources/js/hayamiki_designer/locale/ja.xml new file mode 100644 index 0000000..be5abcc --- /dev/null +++ b/resources/js/hayamiki_designer/locale/ja.xml @@ -0,0 +1,96 @@ + + + + テーブルを追加 + テーブルを編集 + テーブルを削除 + テーブルを整列 + 全テーブルを削除 + 全テーブルを削除しますか + 新規テーブル + テーブルを配置 + テーブル名 + コメント + + + 列を追加 + 列を編集 + 列を削除 + 上に + 下に + 新規列 + 外部キーとして移動 + 対象テーブルを選択 + 外部キーを接続 + 対象列を選択 + 外部キーを削除 + テーブルを削除しますか + 列を削除しますか + + + 列名 + 型 + サイズ + デフォルト値 + NOT NULL + NULL + 自動採番 + コメントを編集 + 列のコメントを入力 + + + OK + キャンセル + しばらくお待ちください... + オプション + 言語 + 新しい設計で使用するデータベース + 印は再読込後に反映されるオプションです。これらを動作させるにはクッキーを有効にしてください。 + テーブルのスナップ単位 + ピクセル(0 = スナップ無効) + 外部キーの命名規則 + %T = 親テーブル, %R = プライマリーキー, %t = 子テーブル + テーブルをドラッグ中は線を隠す + 滑らかな線を使う(要ブラウザのサポート) + + + + キーの設定 + テーブル"%s"のキー + 種類: + キー名: + キーの対象列 + 選択可能な列 + キーを編集 + キーを追加 + キーを削除 + + + 保存/読み込み + 下の入出力欄にXMLデータを貼りつけてから実行してください。 + クライアント + サーバ + 入力出欄 + XMLを出力 + XMLを読込 + SQLを生成 + サーバのバックエンド: + 保存 + 読込 + 一覧 + DBからインポート + 読み込む設計名を入力してください: + 保存する設計名を入力してください: + インポートするDB名を入力してください: + サーバレスポンス + Saved + Not Found + Internal Server Error + Not Implemented + Service Unavailable + + + XMLエラー + ドキュメント + + diff --git a/resources/js/hayamiki_designer/locale/nl.xml b/resources/js/hayamiki_designer/locale/nl.xml new file mode 100644 index 0000000..b236de7 --- /dev/null +++ b/resources/js/hayamiki_designer/locale/nl.xml @@ -0,0 +1,101 @@ + + + + Tabel toevoegen + Bewerk tabel + Verwijder tabel + Verwijder tabellen + Uitlijnen tabellen + Tabellen schonen + Wilt u echt alle tabellen verwijderen + Nieuwe tabel + Positioneer tabel + Naam + Opmerkingen + + + Veld toevoegen + Veld bewerken + Veld verwijderen + Op + Neer + nieuwe veld + Maak relatie + Click op doeltabel + Verbind relatie + Click op doelveld + Verwijder relatie + Tabel verwijderen? + Veld verwijderen? + + + Naam + Type + Omvang + Standaard + NOT NULL + NULL + Autoincrement + Bewerk opmerkingen + Geef opmerkingen voor dit veld + + + OK + Annuleer + Even geduld... + Opties + Taal + Database voor nieuwe ontwerpen + Sommige opties worden pas geldig na het volledig opnieuw laden van de pagina. Cookies moeten zijn toegestaan voor een juiste werking. + Tabel snap afstand + In pixels, 0 = uitzetten snap + Patroon voor relatie velden + %T = primaire tabel, %R = primaire sleutel, %t = verwezen tabel. + Verberg relaties tijdens verplaatsen van de tabel? + Teken gekromde relaties (als de browser dit ondersteund)? + Toon veld omvang in tabelontwerp? + Toon veld type in tabelontwerp? + + + Sleutels + Sleutels in tabel "%s" + Type: + Naam: + Velden in sleutel + Beschikbare velden + Bewerk sleutel + Voeg sleutel toe + Verwijder sleutel + + + Opslaan / laden + Please paste XML data into the text area below and try again. + Lokaal + Server + Input / Output + XML Opslaan + XML Laden + Opslaan in Browser + Laden uit Browser + Genereer SQL + Server: + Opslaan + Snel opslaan + Laden + Toon lijst + Import uit DB + Enter keyword under which your design was saved: + Enter keyword under which your design will be saved: + Enter name of database to be imported: + Reactie van server + Opgeslagen + Niet gevonden + Interne Server Fout + Niet geimplementeerd + Niet beschikbaar + + + XML fout + Documentatie + + diff --git a/resources/js/hayamiki_designer/locale/pl.xml b/resources/js/hayamiki_designer/locale/pl.xml new file mode 100644 index 0000000..7350c40 --- /dev/null +++ b/resources/js/hayamiki_designer/locale/pl.xml @@ -0,0 +1,99 @@ + + + + Dodaj tabelę + Edytuj tabelę + Usuń tabelę + Usuń tabele + Wyrównaj tabele + Wyczyść tabele + Czy na pewno usunąć wszystkie tabele + nowa tabela + miejsce tabeli + Nazwa + Opis + + + Dodaj pole + Edytuj pole + Usuń pole + W górę + W dół + nowe pole + Utwórz klucz zewnętrzny + kliknij w docelową tabelę + Utwórz klucz zewnętrzny + kliknij w docelową tabelę + Smazat cizí klíč + Czy na pewno usunąć tabelę + Czy na pewno usunąć pole + + + Nazwa + Typ + Rozmiar + Domyślnie + Niepuste + Zerowy + Automatyczne zwiększanie o 1 + Edytuj komentarz + Wpisz komentarz dla tego pola + + + OK + Anuluj + Proszę czekać... + Opcje + Język + Bazy danych dla nowych projektów + Niektóre opcje są zatwierdzane wyłącznie po kompletnym przeładowaniu strony. Ciasteczka muszą być akceptowane dla działania opcji. + Ustalana odległość tabel + W pikselach, 0 = wyłącznie ustalania + Wzorzec dla zewnętrznych nazw + %T = główna tabela, %R = klucz główny, %t = zewnętrzna tabela + Ukryć złącza w tabeli podczas przeciągania? + Rysuj pływające złącza (jesli wsperane jest przez przeglądarkę)? + Show field size in table design? + Show field datatype in table design? + + + Klucze + Klucze w tabeli "%s" + Typ: + Nazwa: + Pola w kluczu + Dostępne pola + Edytuj klucz + Dodaj klucz + Usuń klucz + + + Zapisz / Otwórz + Proszę wklej kod XML w poniższe pole tekstowe i spróbuj ponownie. + Klient + Serwer + Wejście / Wyjście + Zapisz XML + Załaduj XML + Generuj SQL + Serwer wejściowy: + Zapisz + Quicksave + Otwórz + Lista pozycji + Importuj z DB + Wpisz słowo kluczowe pod którym twój projekt został zapisany: + Wpisz słowo kluczowe pod którym twój projekt ma zostać zapisany: + Wpisz nazwę bazy danych do zaimportowania: + Odpowiedź serwera + Zapisano + Nie znaleziono + Wewnętrzny błąd serwera + Niezaimplementowane + Serwer niedostępny + + + Błąd XML + Dokumentacja + + diff --git a/resources/js/hayamiki_designer/locale/pt_BR.xml b/resources/js/hayamiki_designer/locale/pt_BR.xml new file mode 100644 index 0000000..3d6df03 --- /dev/null +++ b/resources/js/hayamiki_designer/locale/pt_BR.xml @@ -0,0 +1,97 @@ + + + + Adicionar tabela + Editar tabela + Remover tabela + Remover tabelas + Alinhar tabelas + Limpar tabelas + Realmente excluir todas as tabelas + Nova tabela + Clique p/ adicionar + Nome + Comentário + + + Adicionar campo + Editar campo + Remover campo + Para cima + Para baixo + Novo campo + Criar chave estrangeira + Selecione a tabela alvo(destino) + Conectar chave estrangeira + Clique na linha alvo + Remover chave estrangeira + Deseja realmente deletar a tabela + Deseja realmente deletar o campo + + + Nome + Tipo + Tamanho + Default + NOT NULL + NULL + Auto incrementar + Editar comentário + Digite o comentário para este campo + + + OK + Cancelar + Por favor espere... + Opções + Linguagem + Base de Dados para os novos designs + Algumas opções serão aplicadas somente depois da página totalmente regarrecada. Cookies devem ser ativados para as opções funcionarem. + Distância entre as tabelas + Em pixels, 0 = desativar snapping + Padrão p/ nomes estrangeiros + %T = tabela primária, %R = chave primária, %t = tabela estrangeira + Esconder connectores na tela? + Desenhar conectores suaves (se suportado pelo navegador)? + + + + Chaves + Chaves na tabela "%s" + Tipo: + Nome: + Campos na chave + Campos disponíveis + Editar chave + Adicionar chave + Remover chave + + + Salvar / Carregar + Por favor cole os dados XML na área de texto abaixo e tente novamente. + Cliente + Servidor + Entrada / Saída + Salvar XML + Carregar XML + Gerar SQL + Parâmetros do Servidor: + Salvar + Carregar + Listar itens + Importar do BD + Digite o nome o qual seu design foi salvo: + Digite o nome com qual seu design será salvo: + Digite o nome da base de dados à ser importada: + Resposta do servidor + Salvo + Não Encontrado + Erro Interno do Servidor + Não Implementado + Serviço Indisponível + + + Erro de XML + Documentação + + diff --git a/resources/js/hayamiki_designer/locale/ro.xml b/resources/js/hayamiki_designer/locale/ro.xml new file mode 100644 index 0000000..6b1ffdd --- /dev/null +++ b/resources/js/hayamiki_designer/locale/ro.xml @@ -0,0 +1,97 @@ + + + + Adauga tabela + Editeaza tabela + Sterge tabela + Sterge tabelele + Aliniaza tabelele + Sterge tabelele + Sterge toate tabelele + (nume tabela) + plaseaza tabela + Nume + Comentariu + + + Adauga coloana + Editeaza coloana + Sterge coloana + Sus + Jos + coloana noua + Creaza FK + alege destinatie + Conexiune FK + alege destinatie + Sterge FK + Sterge tabela + Sterge coloana + + + Nume + Tip + Dimensiune + Valoare default + NOT NULL + NULL + Auto increment + Editare comentariu + Introduceti comentariul pentru aceasta coloana: + + + OK + Anuleaza + Asteptati va rog... + Optiuni + Limbaj + Baza de date pentru design + Anumite optiuni devin active numai dupa o reincarcare completa a paginii. Cookies trebuie sa fie activate pentru browser. + Distanta automata intre tabele + In pixeli, 0 = dezactiveaza asezarea automata + Modelul pentru nume de Foreign Keys + %T = Tabela primara, %R = Primary key, %t = Tabela cu Foreign key + Ascunde conexiunile la mutarea tabelei? + Deseneaza folosind "smooth connectors" (daca browserul suporta)? + + + + Keys / Indexes + Keys / Indexes in tabela "%s" + Tip: + Nume: + Campuri selectate + Campuri disponibile + Editeaza + Adauga + Sterge + + + Salveaza / Incarca + Introduceti codul XML si re-incercati. + Client + Server + Input / Output + Genereaza XML + Incarca din XML + Genereaza SQL + Server backend: + Salveaza + Incarca + Lista de salvari + Import tabele din baza de date + Introduceti numele sub care a fost salvat design-ul: + Introduceti numele sub care va fi salvat design-ul: + Introduceti numele bazei de date care va fi importata: + Server response + Salvare efectuata + Not Found + Internal Server Error + Not Implemented + Service Unavailable + + + Eroare XML + Documentatie + + diff --git a/resources/js/hayamiki_designer/locale/ru.xml b/resources/js/hayamiki_designer/locale/ru.xml new file mode 100644 index 0000000..4248c7a --- /dev/null +++ b/resources/js/hayamiki_designer/locale/ru.xml @@ -0,0 +1,97 @@ + + + + Добавить таблицу + Редактировать таблицу + Удалить таблицу + Удалить таблицы + Выровнять таблицы + Очистить таблицы + Действительно удалить все таблицы + новая таблица + расположите таблицу + Имя + Коментарий + + + Добавить поле + Редактировать поле + Удалить поле + Вверх + Вниз + новое поле + Создать внешний ключь + щелкните по целевой таблице + ? + ? + ? + Действительно удалить таблицу + Действительно удалить поле + + + Имя + Тип + Размер + По умолчанию + NOT NULL + NULL + Autoincrement + Изменить коментарий + Введите коментарий для этого поля + + + OK + Отменить + Пожалуйста подождите... + Опции + Язык + База данных для новых дизайнов + Некоторые опции заработают только после полной перезагрузки страницы. Cookie должны быть включены. + Table snap distance + В пикселях, 0 = disable snapping + Pattern for foreign names + %T = primary table, %R = primary key, %t = foreign table + Прятать связи при перетаскивании таблиц? + Рисовать сглаженные связи (если поддерживается браузером)? + + + + Ключи + Ключи в таблице "%s" + Тип: + Имя: + Поля в ключе + Доступные поля + Редактировать ключь + Добавить ключь + Удалить ключь + + + Сохранить / Загрузить + Пожалуйста, вставьте XML данные в поле ниже и попробуйте ещё раз. + Клиент + Сервер + Ввод / Вывод + Сохранить XML + Загрузить XML + Генерировать SQL + Использовать для сохранения сервис: + Сохранить + Загрузить + Список items + Импортировать из БД + Введите ключевое слово под которым ваш дизайн сохранен: + Введите ключевое слово под которым ваш дизайн будет сохранен: + Введите имя импортируемой базы данных: + Ответ сервера + Saved + Not Found + Internal Server Error + Not Implemented + Service Unavailable + + + Ошибка XML + Документация + + diff --git a/resources/js/hayamiki_designer/locale/sv.xml b/resources/js/hayamiki_designer/locale/sv.xml new file mode 100644 index 0000000..583b5bf --- /dev/null +++ b/resources/js/hayamiki_designer/locale/sv.xml @@ -0,0 +1,97 @@ + + + + Skapa tabell + Redigera tabell + Ta bort tabell + Ta bort tabeller + Räta upp tabeller + Ta bort alla tabeller + Vill du verkligen ta bort alla tabeller + Ny tabell + Placera tabell + Namn + Kommentar + + + Lägg till fält + Redigera fält + Ta bort field + Upp + Ner + Ny field + Skapa främmande nyckel + Klicka på motsvarande tabell + Anslut främmande nycke + Välj motsvarande rad + Ta bort främmande nyckel + Vill du verkligen ta bort denna tabell? + Vill du verkligen ta bort detta fält? + + + Namn + Typ + Storlek + Standard + NOT NULL + NULL + Autoincrement + Redigera kommentar + Ange kommentar för detta fält + + + OK + Avbryt + Var god vänta... + Alternativ + Språk + Databas for nya designer + Vissa alternativ ändras bara efter att du laddat om sidan. Cookies krävs för att alternativ ska fungera. + Tabellers fästavstånd + Ange pixlar, 0 = stäng av fästning + Mönster för främmande namn + %T = primär tabell, %R = primär nycke, %t = främmande tabell + Dölj anslutningar när du drar i tabellen? + Rita mjuka anslutningar (om din webbläsare stöder det)? + + + + Nycklar + Nycklar i tabellen "%s" + Typ: + Namn: + Fields in nyckel + Available fields + Edit nyckel + Add key + Ta bort key + + + Spara / Ladda + Vänligen klistra in XML i textrutan nedan och försök igen. + Klient + Server + Input / Output + Spara XML + Ladda XML + Generera SQL + Server backend: + Spara + Ladda + Lista innehåll + Importera från DB + Ange vilket nyckelord din design sparades under: + Ange vilket nyckelord din design ska sparas under: + Ange namnet på databasen som ska importeras: + Serversvar + Sparad + Ej funnen + Intert serverfel + Ej implementerat + Service Unavailable + + + XML error + Dokumentation + + diff --git a/resources/js/hayamiki_designer/locale/zh.xml b/resources/js/hayamiki_designer/locale/zh.xml new file mode 100644 index 0000000..5e8f71b --- /dev/null +++ b/resources/js/hayamiki_designer/locale/zh.xml @@ -0,0 +1,101 @@ + + + + 添加表 + 修改表 + 移除表 + 重组表格位置 + 删除所有表 + 真的要删除所有表么 + 表名称 + 放置表格…… + 表名 + 注释 + + + 添加列 + 修改列 + 删除列 + 上移 + 下移 + newfield + 创建外连表格列 + 点击选择目标表 + 连接到外部列 + 点击选择目标列 + 断开外部连接 + 真的删除表么 + 真的删除列么 + + + 列名 + 类型 + 大小 + 默认 + 不能为空 + 可留空 + 自增长 + 改备注 + 输入此列备注 + + + 搞定 + 不要了 + 请等待... + 选项设置 + 语言 + 新建的数据库设为: + 有些属性需要刷新页面后才能起作用,所以,浏览器的Cookies必须启用。 + 表格捕捉距离 + 像素, 0 = 关闭捕捉 + 外连名称规则 + %T = 主表, %R = 主键, %t = 外连表 + 在表格移动时不显示连接? + 绘制平滑的连接 (如果浏览器支持)? + 设计表格时显示字段大小? + 设计表格时显示字段数据类型? + + + + 设置表键 + 在 "%s" 表中可用列属性 + 类型: + 属性名称: + 此属性中的列 + 可用列 + 修改属性 + 添加属性 + 删除属性 + + + 登录 + 注销 + 保存 / 载入 + 请先粘帖一个XML文件内容到文本框中,然后再导入。 + 客户端 + 服务端 + 输入 / 输出 + 保存为XML + 载入XML + 传化为数据库脚本 + 服务后台: + 保存 + 载入 + 显示清单 + 快速保存 + 从数据库中导入 + 输入你所保存的名字: + 输入所要保存的名字: + 输入所要导入的数据库名称: + 服务器反馈 + 已存 + 找不到 + 网络服务错误 + 未执行 + 服务暂不可用 + + + XML 错误 + 文档 + + diff --git a/resources/js/hayamiki_designer/styles/ie6.css b/resources/js/hayamiki_designer/styles/ie6.css new file mode 100644 index 0000000..2e56ff6 --- /dev/null +++ b/resources/js/hayamiki_designer/styles/ie6.css @@ -0,0 +1,62 @@ +v\:* { + behavior:url(#default#VML); +} + +#bar { + position: absolute; + right: auto; + left: expression(eval(document.documentElement.scrollLeft)+document.documentElement.clientWidth-eval(this.offsetWidth)); + top: expression(eval(document.documentElement.scrollTop)); +} + +#bar .shadow-corner { + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/bar_corner.png',sizingMethod='crop'); + overflow: hidden; +} + +#bar .shadow-left { + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/bar_left.png',sizingMethod='crop'); + height: expression(eval(this.parentNode.offsetHeight)); + overflow: hidden; +} + +#bar .shadow-bottom { + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/bar_bottom.png',sizingMethod='crop'); + width: expression(eval(this.parentNode.offsetWidth)); + overflow: hidden; +} + +.table .shadow-corner { + background-image: none; +} + +.table .shadow-right { + background-image: none; +} + +.table .shadow-bottom { + background-image: none; +} + +#minimap { + filter: alpha(opacity=90); + position: absolute; + right: auto; + left: expression(eval(document.documentElement.scrollLeft)+document.documentElement.clientWidth-eval(this.offsetWidth)); + top: expression(eval(document.documentElement.scrollTop)+document.documentElement.clientHeight-eval(this.offsetHeight)); +} + +#background { + filter: alpha(opacity=50); +} + +#keys, #opts { + width: expression(eval(document.documentElement.clientWidth)/2); +} + +#rubberband { + filter: alpha(opacity=50); +} \ No newline at end of file diff --git a/resources/js/hayamiki_designer/styles/ie7.css b/resources/js/hayamiki_designer/styles/ie7.css new file mode 100644 index 0000000..876bba7 --- /dev/null +++ b/resources/js/hayamiki_designer/styles/ie7.css @@ -0,0 +1,19 @@ +v\:* { + behavior:url(#default#VML); +} + +#minimap { + filter: alpha(opacity=90); +} + +#background { + filter: alpha(opacity=50); +} + +#keys, #opts { + width: expression(eval(document.documentElement.clientWidth)/2); +} + +#rubberband { + filter: alpha(opacity=50); +} diff --git a/resources/js/hayamiki_designer/styles/print.css b/resources/js/hayamiki_designer/styles/print.css new file mode 100644 index 0000000..98fddfa --- /dev/null +++ b/resources/js/hayamiki_designer/styles/print.css @@ -0,0 +1,23 @@ +#bar, #background, #minimap { + display: none; +} + +.table { + border:1px solid #000000; + background-color:none; +} + +.row { + background-color:none; +} + +.table .shadow-corner, .shadow-right, .shadow-bottom { + display:none; +} + +.table_title { + font-weight:bold; + font-size:115%; + background-color:none; +} + diff --git a/resources/js/hayamiki_designer/styles/style.css b/resources/js/hayamiki_designer/styles/style.css new file mode 100644 index 0000000..4a8f8e0 --- /dev/null +++ b/resources/js/hayamiki_designer/styles/style.css @@ -0,0 +1,247 @@ +body { + font-family: verdana, sans serif; + font-size: small; + padding: 0px; + margin: 0px; + background: #FFF; + visibility: hidden; + -moz-user-select: -moz-none; + -khtml-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +#area { + position: relative; + background: transparent url(../images/back.png); + width: 2000px; + height: 2000px; +} + +#controls { + position: absolute; + left: 0px; + top: 0px; +} + +#bar { + text-align: center; + background-color: #ccc; + position: fixed; + top: 0px; + right: 0px; + width: 150px; + padding: 0px 5px 5px; + -moz-box-shadow: -4px 4px 8px #888; /* FF 3.5+ */ + -webkit-box-shadow: -4px 4px 8px #888; /* Safari 3.0+, Chrome */ + box-shadow: -4px 4px 8px #888; /* Opera 10.5, IE 9.0 */ + filter: progid:DXImageTransform.Microsoft.Shadow(Strength=5, Direction=215, Color='#888888'); /* IE 6, IE 7 */ + -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=5, Direction=215, Color='#888888')"; /* IE 8 */ +} + +#bar input { + display: block; + width: 90%; + margin: auto; +} + +#bar input.small { + width: 45%; + display: inline; +} + +#toggle { + padding: 5px 0px; + margin-bottom: 5px; + cursor: pointer; + background-position: 50% 5px; + background-repeat: no-repeat; + height: 5px; +} + +#toggle:hover { + background-color: #bbb; +} + +#toggle.on { + background-image: url(../images/up.gif); +} + +#toggle.off { + background-image: url(../images/down.gif); +} + +#minimap { + position: fixed; + width: 100px; + height: 100px; + right: 0px; + bottom: 0px; + background-color: #fff; + border: 1px solid #000; + opacity: 0.9; + overflow: hidden; +} + +.mini { + position: absolute; + border: 1px solid #000; + background-color: #eea; + font-size: 1px; + line-height: 1px; +} + +.mini_selected { + background-color: #f85; +} + +.port { + position: absolute; + border: 2px solid #f00; +} + +.table { + position: absolute; + border: 1px solid #000; + background-color: #ddd; + cursor: pointer; + -moz-box-shadow: 4px 4px 8px #888; /* FF 3.5+ */ + -webkit-box-shadow: 4px 4px 8px #888; /* Safari 3.0+, Chrome */ + box-shadow: 4px 4px 8px #888; /* Opera 10.5, IE 9.0 */ + filter: progid:DXImageTransform.Microsoft.Shadow(Strength=5, Direction=135, Color='#888888'); /* IE 6, IE 7 */ + -ms-filter: progid:DXImageTransform.Microsoft.Shadow(Strength=5, Direction=135, Color='#888888'); /* IE 8 */ + border-radius: 3px; +} + +.table table { + border-collapse: collapse; +} + +.table.selected { + border: 2px solid #000; +} + +.table thead .title { + text-align: center; + padding: 3px 30px; +} + +.table tbody { + border-top: 1px dotted #888; +} + +.table tbody td { + padding: 3px; +} + +.table tbody .selected { + font-weight: bold; + color: #f00; + display: inline-block; +} + +.table tbody .title { + display: inline-block; +} + +.primary { + font-weight: bold; +} + +.key { + font-style: italic; +} + +.primary.key { + font-style: normal; +} + +.typehint { + font-size: 80%; + color: gray; +} + +.comment { + font-size: 80%; + font-weight: normal; + margin-right: 0.5em; +} + +.adding { + cursor: crosshair; +} + +.relation { + overflow: hidden; +} + +#background { + position: absolute; + background-color: #000; + opacity: 0.5; + visibility: hidden; +} + +#window { + position: absolute; + visibility: hidden; + background-color: #fff; + border: 6px double #333; +} + +#windowtitle { + border-bottom: 2px solid #333; + padding: 2px; + padding-left: 1em; + font-weight: bold; + background-color: rgb(238, 238, 170); +} + +#windowcontent { + padding: 1em; +} + +#windowok, #windowcancel { + margin: 0em 1em 1em; +} + +.small { + font-size: 85%; +} + +#textarea { + width: 650px; + height: 200px; +} + +#opts { + width: 700px; +} + +#keys { + white-space: nowrap; + text-align: center; +} + +legend { + font-weight: bold; +} + +label, input, select { + vertical-align: middle; +} + +#throbber { + position: absolute; + top: 2px; + right: 3px; +} + +#rubberband { + position: absolute; + border: 1px solid #000; + background: #888; + opacity: 0.5; + visibility: hidden; +} diff --git a/src/main.anubis b/src/main.anubis index febbb7c..7e59a29 100644 --- a/src/main.anubis +++ b/src/main.anubis @@ -19,7 +19,7 @@ read calexium_lib/database/model/db_model.anubis read model.3.0.0.anubis global define One - db_model_manager + hayamiki ( List(String) args ) = diff --git a/src/model.3.0.0.anubis b/src/model.3.0.0.anubis index 097e2eb..8831e52 100644 --- a/src/model.3.0.0.anubis +++ b/src/model.3.0.0.anubis @@ -7,45 +7,48 @@ public define DB_Table mf_serial_table = db_model( [ - db_column("serial", char_field(30), []), - db_column("mac", char_field(30), []), - db_column("app_id", char_field(50), []), - db_column("enabled",boolean_field, [], help_text("Is enabled?")), - db_column("free_domain",boolean_field, [], help_text("Free domain available?")), - db_column("max_domains",integer_field, [], help_text("Maximum number of domains")), - db_column("is_demo",boolean_field, [], help_text("Is demo?")), - db_column("is_test", boolean_field, [], help_text("Is test?")), - db_column("date_created", datetime_field(auto_now_add), []), - db_column("last_updated", datetime_field(none), []), - db_column("last_ping", datetime_field(none), []), - db_column("current_ip", char_field(20), []), - db_column("mf_version", char_field(20), [], help_text("MF version")), - db_column("vm_version", char_field(20), [], help_text_TAG("ANUBIS_VM_VER")), - db_column("os_version", char_field(20), [], help_text("OS version")), - db_column("ipkg_list", text_field, []), - db_column("ifconfig", text_field, []), - db_column("dmesg", text_field, []), - db_column("memory", text_field, []), - db_column("vm_memory", text_field, []), - db_column("status", text_field, []), - db_column("disks", text_field, []), - db_column("isp_smtp", text_field, []), - db_column("description", text_field, []), - db_column("comments", text_field, []), - db_column("alert_received",boolean_field, [], help_text("Alert received?")), - db_column("alert_date", datetime_field(none), []), - db_column("alert_msg", text_field, []), + db_column("serial", char_field(30), []), + db_column("mac", char_field(30), []), + db_column("app_id", char_field(50), []), + db_column("enabled", boolean_field, [], help_text("Is enabled?")), + db_column("free_domain", boolean_field, [], help_text("Free domain available?")), + db_column("max_domains", integer_field, [], help_text("Maximum number of domains")), + db_column("is_demo", boolean_field, [], help_text("Is demo?")), + db_column("is_test", boolean_field, [], help_text("Is test?")), + db_column("date_created", datetime_field(auto_now_add), []), + db_column("last_updated", datetime_field(none), []), + db_column("last_ping", datetime_field(none), []), + db_column("current_ip", char_field(20), []), + db_column("mf_version", char_field(20), [], help_text("MF version")), + db_column("vm_version", char_field(20), [], help_text_TAG("ANUBIS_VM_VER")), + db_column("os_version", char_field(20), [], help_text("OS version")), + db_column("ipkg_list", text_field, []), + db_column("ifconfig", text_field, []), + db_column("dmesg", text_field, []), + db_column("memory", text_field, []), + db_column("vm_memory", text_field, []), + db_column("status", text_field, []), + db_column("disks", text_field, []), + db_column("isp_smtp", text_field, []), + db_column("description", text_field, []), + db_column("comments", text_field, []), + db_column("alert_received", boolean_field, [], help_text("Alert received?")), + db_column("alert_date", datetime_field(none), []), + db_column("alert_msg", text_field, []), db_column("alert_mf_version", char_field(20), []), ], "obj.serial" ), db_display( - //list_view - [ "serial", "mf_version", "mac", "app_id", "is_demo", "is_test", "last_updated", "last_ping", "mf_version", ], + views( + [ + //list_view + list_view([ "serial", "mf_version", "mac", "app_id", "is_demo", "is_test", "last_updated", "last_ping", "mf_version", ]), + ]), //list edit - ["serial", "mac", "app_id", "enabled", "free_domain", "max_domains", "is_demo", "is_test", "date_created", "last_updated", "last_ping", "current_ip", "mf_version", + list_edit(["serial", "mac", "app_id", "enabled", "free_domain", "max_domains", "is_demo", "is_test", "date_created", "last_updated", "last_ping", "current_ip", "mf_version", "os_version", "ipkg_list", "ifconfig", "dmesg", "memory", "vm_memory", "status", "disks", "isp_smtp", "description", "comments", "alert_received", "alert_date", - "alert_msg", "alert_mf_version"] + "alert_msg", "alert_mf_version"]) ) ). -- libgit2 0.21.4