diff --git a/examples/demo/demo-safe.ecf b/examples/demo/demo-safe.ecf index f8bee78..f7a4714 100644 --- a/examples/demo/demo-safe.ecf +++ b/examples/demo/demo-safe.ecf @@ -19,7 +19,8 @@ - + + @@ -38,6 +39,7 @@ + diff --git a/examples/demo/modules/blog/cms_blog_module.e b/examples/demo/modules/blog/cms_blog_module.e index 27b9b3b..ecbba0d 100644 --- a/examples/demo/modules/blog/cms_blog_module.e +++ b/examples/demo/modules/blog/cms_blog_module.e @@ -68,10 +68,10 @@ feature {CMS_API} -- Module management if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then if not l_sql_storage.sql_table_exists ("blog_post_nodes") then sql := "[ -CREATE TABLE "blog_post_nodes"( - "nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0), - "revision" INTEGER, - "tags" VARCHAR(255) +CREATE TABLE blog_post_nodes( + `nid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK("nid">=0), + `revision` INTEGER, + `tags` VARCHAR(255) ); ]" l_sql_storage.sql_execute_script (sql) diff --git a/examples/demo/modules/demo/cms_demo_module.e b/examples/demo/modules/demo/cms_demo_module.e index 0ab359e..0bef50d 100644 --- a/examples/demo/modules/demo/cms_demo_module.e +++ b/examples/demo/modules/demo/cms_demo_module.e @@ -63,10 +63,10 @@ feature {CMS_API} -- Module management if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then if not l_sql_storage.sql_table_exists ("tb_demo") then sql := "[ -CREATE TABLE "tb_demo"( - "demo_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("demo_id">=0), - "name" VARCHAR(100) NOT NULL, - "value" TEXT +CREATE TABLE tb_demo( + `demo_id` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK("demo_id">=0), + `name` VARCHAR(100) NOT NULL, + `value` TEXT ); ]" l_sql_storage.sql_execute_script (sql) diff --git a/examples/demo/site/config/application_configuration.json b/examples/demo/site/config/application_configuration.json index 0ccf9d5..a4109cb 100644 --- a/examples/demo/site/config/application_configuration.json +++ b/examples/demo/site/config/application_configuration.json @@ -1,15 +1,18 @@ { "database": { "datasource": { - "driver": "sqlite", - "environment": "sqlite" + "driver": "odbc", + "environment": "odbc-sqlite" }, "environments": { - "sqlite": { + "odbc-sqlite": { "connection_string":"Driver=SQLite3 ODBC Driver;Database=./site/database.sqlite;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;" }, - "test": { - "connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;" + "odbc-mysql": { + "connection_string":"Driver=mysql ODBC Driver;Server=localhost;Port=3306;Database=roc;Uid=roc;Pwd=roc;" + }, + "mysql": { + "connection_string":"Driver=mysql;Server=localhost;Port=3306;Database=roc;Uid=roc;Pwd=roc;" }, "development": { "connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;" diff --git a/examples/demo/site/scripts/core.sql b/examples/demo/site/scripts/core.sql index 4a48224..5b5d0fe 100644 --- a/examples/demo/site/scripts/core.sql +++ b/examples/demo/site/scripts/core.sql @@ -1,28 +1,23 @@ -BEGIN; - - -CREATE TABLE "logs"( - "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0), - "category" VARCHAR(255) NOT NULL, - "level" INTEGER NOT NULL CHECK("level">=1), - "uid" INTEGER, - "message" TEXT NOT NULL, - "info" TEXT, - "link" TEXT, - "date" DATETIME NOT NULL +CREATE TABLE `logs`( + `id` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, + `category` VARCHAR(255) NOT NULL, + `level` INTEGER NOT NULL, + `uid` INTEGER, + `message` TEXT NOT NULL, + `info` TEXT, + `link` TEXT, + `date` DATETIME NOT NULL ); -CREATE TABLE "custom_values"( - "type" VARCHAR(255) NOT NULL, - "name" VARCHAR(255) NOT NULL, - "value" TEXT +CREATE TABLE `custom_values`( + `type` VARCHAR(255) NOT NULL, + `name` VARCHAR(255) NOT NULL, + `value` TEXT ); -CREATE TABLE "path_aliases"( - "pid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("pid">=0), - "source" VARCHAR(255) NOT NULL, - "alias" VARCHAR(255) NOT NULL, - "lang" VARCHAR(12) +CREATE TABLE `path_aliases`( + `pid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, + `source` VARCHAR(255) NOT NULL, + `alias` VARCHAR(255) NOT NULL, + `lang` VARCHAR(12) ); - -COMMIT; diff --git a/examples/demo/site/scripts/node.sql b/examples/demo/site/scripts/node.sql index 0c99eef..43078f9 100644 --- a/examples/demo/site/scripts/node.sql +++ b/examples/demo/site/scripts/node.sql @@ -1,24 +1,22 @@ -BEGIN; -CREATE TABLE "nodes" ( - "nid" INTEGER NOT NULL CHECK("nid" > 0) PRIMARY KEY AUTOINCREMENT UNIQUE, - "revision" INTEGER, - "type" TEXT NOT NULL, - "title" VARCHAR(255) NOT NULL, - "summary" TEXT, - "content" TEXT, - "format" VARCHAR(128), - "author" INTEGER, - "publish" DATETIME, - "created" DATETIME NOT NULL, - "changed" DATETIME NOT NULL, - "status" INTEGER +CREATE TABLE nodes ( + `nid` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE, + `revision` INTEGER, + `type` TEXT NOT NULL, + `title` VARCHAR(255) NOT NULL, + `summary` TEXT, + `content` TEXT, + `format` VARCHAR(128), + `author` INTEGER, + `publish` DATETIME, + `created` DATETIME NOT NULL, + `changed` DATETIME NOT NULL, + `status` INTEGER ); CREATE TABLE page_nodes( - "nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0), - "revision" INTEGER, - "parent" INTEGER + `nid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, + `revision` INTEGER, + `parent` INTEGER ); -COMMIT; diff --git a/examples/demo/site/scripts/user.sql b/examples/demo/site/scripts/user.sql index 707dbc2..64c2f9e 100644 --- a/examples/demo/site/scripts/user.sql +++ b/examples/demo/site/scripts/user.sql @@ -1,34 +1,32 @@ -BEGIN; -CREATE TABLE "users"( - "uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0), - "name" VARCHAR(100) NOT NULL, - "password" VARCHAR(100) NOT NULL, - "salt" VARCHAR(100) NOT NULL, - "email" VARCHAR(250) NOT NULL, - "status" INTEGER, - "created" DATETIME NOT NULL, - "signed" DATETIME, - CONSTRAINT "name" - UNIQUE("name") +CREATE TABLE `users`( + `uid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, + `name` VARCHAR(100) NOT NULL, + `password` VARCHAR(100) NOT NULL, + `salt` VARCHAR(100) NOT NULL, + `email` VARCHAR(250) NOT NULL, + `status` INTEGER, + `created` DATETIME NOT NULL, + `signed` DATETIME, + CONSTRAINT `name` + UNIQUE(`name`) ); -CREATE TABLE "roles"( - "rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0), - "name" VARCHAR(100) NOT NULL, - CONSTRAINT "name" - UNIQUE("name") +CREATE TABLE `roles`( + `rid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, + `name` VARCHAR(100) NOT NULL, + CONSTRAINT `name` + UNIQUE(`name`) ); -CREATE TABLE "users_roles"( - "uid" INTEGER NOT NULL CHECK("uid">=0), - "rid" INTEGER NOT NULL CHECK("rid">=0) +CREATE TABLE `users_roles`( + `uid` INTEGER NOT NULL CHECK(`uid`>=0), + `rid` INTEGER NOT NULL CHECK(`rid`>=0) ); -CREATE TABLE "role_permissions"( - "rid" INTEGER NOT NULL CHECK("rid">=0), - "permission" VARCHAR(255) NOT NULL, - "module" VARCHAR(255) +CREATE TABLE `role_permissions`( + `rid` INTEGER NOT NULL, + `permission` VARCHAR(255) NOT NULL, + `module` VARCHAR(255) ); -COMMIT; diff --git a/examples/demo/src/ewf_roc_server_execution.e b/examples/demo/src/ewf_roc_server_execution.e index 4256ef5..22a937a 100644 --- a/examples/demo/src/ewf_roc_server_execution.e +++ b/examples/demo/src/ewf_roc_server_execution.e @@ -46,8 +46,8 @@ feature -- CMS setup debug ("refactor_fixme") to_implement ("To implement custom storage") end --- a_setup.storage_drivers.force (create {CMS_STORAGE_MYSQL_BUILDER}.make, "mysql") - a_setup.storage_drivers.force (create {CMS_STORAGE_SQLITE_BUILDER}.make, "sqlite") +-- a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_MYSQL_BUILDER}.make, "mysql") + a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_ODBC_BUILDER}.make, "odbc") end setup_modules (a_setup: CMS_SETUP) diff --git a/library/persistence/implementation/store/database/database_config.e b/library/persistence/implementation/store/database/database_config.e index 0409013..64ff6f5 100644 --- a/library/persistence/implementation/store/database/database_config.e +++ b/library/persistence/implementation/store/database/database_config.e @@ -8,16 +8,16 @@ deferred class feature -- Database access - hostname: STRING = "" + default_hostname: STRING = "" -- Database hostname. - username: STRING = "" + default_username: STRING = "" -- Database username. - password: STRING = "" + default_password: STRING = "" -- Database password. - database_name: STRING = "EiffelDB" + default_database_name: STRING = "EiffelDB" -- Database name. is_keep_connection: BOOLEAN diff --git a/library/persistence/implementation/store/database/database_connection.e b/library/persistence/implementation/store/database/database_connection.e index 5f0e9f7..0d3d826 100644 --- a/library/persistence/implementation/store/database/database_connection.e +++ b/library/persistence/implementation/store/database/database_connection.e @@ -12,27 +12,7 @@ inherit feature {NONE} -- Initialization - make_common - -- Create a database handler with common settings. - deferred - ensure - db_application_not_void: db_application /= Void - db_control_not_void: db_control /= Void - end - - make_basic ( a_database_name: STRING) - -- Create a database handler with common settings and - -- set database_name with `a_database_name'. - require - database_name_not_void: a_database_name /= Void - database_name_not_empty: not a_database_name.is_empty - deferred - ensure - db_application_not_void: db_application /= Void - db_control_not_void: db_control /= Void - end - - make (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN) + login (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN) -- Create a database handler with user `a_username', password `a_password', -- host `a_hostname', database_name `a_database_name', and keep_connection `connection'. @@ -59,6 +39,26 @@ feature {NONE} -- Initialization db_control_not_void: db_control /= Void end + login_with_default + -- Create a database handler with common settings. + deferred + ensure + db_application_not_void: db_application /= Void + db_control_not_void: db_control /= Void + end + + login_with_database_name ( a_database_name: STRING) + -- Create a database handler with common settings and + -- set database_name with `a_database_name'. + require + database_name_not_void: a_database_name /= Void + database_name_not_empty: not a_database_name.is_empty + deferred + ensure + db_application_not_void: db_application /= Void + db_control_not_void: db_control /= Void + end + feature -- Database Setup db_application: DATABASE_APPL [DATABASE] @@ -168,7 +168,7 @@ feature -- Error Handling database_error_handler: DATABASE_ERROR_HANDLER -- Error handler. - + feature -- Status Report has_error: BOOLEAN @@ -179,11 +179,11 @@ feature -- Status Report feature -- Helper - exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception) - -- Record exception as an error. + exception_as_error (a_exception: like {EXCEPTION_MANAGER}.last_exception) + -- Record exception `a_exception' as an error. do - if attached a_e as l_e and then attached l_e.trace as l_trace then - database_error_handler.add_error_details (l_e.code, once "Exception", l_trace.as_string_32) + if a_exception /= Void and then attached a_exception.trace as l_trace then + database_error_handler.add_error_details (a_exception.code, once "Exception", l_trace) end end diff --git a/library/persistence/implementation/store/database/database_connection_odbc.e b/library/persistence/implementation/store/database/database_connection_odbc.e index c9c2512..b74f547 100644 --- a/library/persistence/implementation/store/database/database_connection_odbc.e +++ b/library/persistence/implementation/store/database/database_connection_odbc.e @@ -7,117 +7,97 @@ class DATABASE_CONNECTION_ODBC inherit - DATABASE_CONNECTION redefine db_application end - SHARED_LOGGER - create - make, make_common, make_basic, login_with_connection_string + login, login_with_default, login_with_database_name, login_with_connection_string feature -- Initialization - make_common - -- Create a database handler for ODBC with common settings. - local - l_retried: BOOLEAN - do - create db_application.login (username, password) - create database_error_handler.make - if not l_retried then - db_application.set_hostname (hostname) - db_application.set_data_source (database_name) - db_application.set_base - create db_control.make - keep_connection := is_keep_connection - if keep_connection then - connect - end - else - create db_control.make - end - rescue - create db_control.make --- set_last_error_from_exception ("Connection execution") --- write_critical_log (generator + ".make_common:" + last_error_message) - if is_connected then - disconnect - end - l_retried := True - retry - end - - make_basic (a_database_name: STRING) - -- Create a database handler and - -- set database_name to `a_database_name'. - local - l_retried: BOOLEAN - do - create db_application.login (username, password) - create database_error_handler.make - if not l_retried then - db_application.set_hostname (hostname) - db_application.set_data_source (a_database_name) - db_application.set_base - create db_control.make - keep_connection := is_keep_connection - if keep_connection then - connect - end - else - create db_control.make - end - rescue - create db_control.make --- set_last_error_from_exception ("Connection execution") --- write_critical_log (generator + ".make_common:" + last_error_message) - if is_connected then - disconnect - end - l_retried := True - retry - end - - make (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN) + login (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; a_keep_connection: BOOLEAN) -- Create a database handler for ODBC and set `username' to `a_username', -- `password' to `a_password' -- `database_name' to `a_database_name' - -- `connection' to `a_connection' + -- `keep_connection' to `a_keep_connection' + local + retried: BOOLEAN + l_database_error_handler: detachable like database_error_handler do - create database_error_handler.make + create l_database_error_handler.make + database_error_handler := l_database_error_handler create db_application.login (a_username, a_password) - db_application.set_hostname (a_hostname) - db_application.set_data_source (a_database_name) - db_application.set_base - create db_control.make - keep_connection := connection - if keep_connection then - connect + if not retried then + db_application.set_hostname (a_hostname) + db_application.set_data_source (a_database_name) + db_application.set_base + create db_control.make + keep_connection := a_keep_connection + if keep_connection then + connect + end + else + create db_control.make + if is_connected then + disconnect + end end + rescue + if l_database_error_handler = Void then + create l_database_error_handler.make + end + database_error_handler := l_database_error_handler + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + retried := True + retry + end + + login_with_default + -- Create a database handler for ODBC with common settings. + do + login_with_database_name (default_database_name) + end + + login_with_database_name (a_database_name: STRING) + -- Create a database handler and + -- set database_name to `a_database_name'. + do + login (default_username, default_password, default_hostname, default_database_name, is_keep_connection) end login_with_connection_string (a_string: STRING) -- Login with `a_connection_string'and immediately connect to database. + local + retried: BOOLEAN + l_database_error_handler: detachable like database_error_handler do - write_debug_log (generator +".login_with_connection_string") + create l_database_error_handler.make + database_error_handler := l_database_error_handler create db_application.login_with_connection_string (a_string) - create database_error_handler.make - db_application.set_base - create db_control.make - write_debug_log (generator +".login_with_connection_string, is_keep_connection? "+ is_keep_connection.out ) - keep_connection := is_keep_connection - if keep_connection then - connect - if not db_control.is_ok then - write_critical_log (generator +".login_with_connection_string:"+ db_control.error_code.out ) - write_critical_log (generator +".login_with_connection_string:"+ db_control.error_message_32 ) + if not retried then + db_application.set_base + create db_control.make + keep_connection := is_keep_connection + if keep_connection then + connect + end + else + create db_control.make + if is_connected then + disconnect end - write_debug_log (generator +".login_with_connection_string, After connect, is_connected? "+ is_connected.out) end + rescue + if l_database_error_handler = Void then + create l_database_error_handler.make + end + database_error_handler := l_database_error_handler + exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) + retried := True + retry end feature -- Databse Connection diff --git a/library/persistence/mysql/scripts/Readme.md b/library/persistence/mysql/scripts/Readme.md deleted file mode 100644 index f731947..0000000 --- a/library/persistence/mysql/scripts/Readme.md +++ /dev/null @@ -1,3 +0,0 @@ -To build the MySQL schema use the schema.sql script. -The other script will be deleted soon. - diff --git a/library/persistence/mysql/scripts/Readme.txt b/library/persistence/mysql/scripts/Readme.txt deleted file mode 100644 index 04064dc..0000000 --- a/library/persistence/mysql/scripts/Readme.txt +++ /dev/null @@ -1 +0,0 @@ -Added Stored Procedures \ No newline at end of file diff --git a/library/persistence/mysql/scripts/create_database.sql b/library/persistence/mysql/scripts/create_database.sql deleted file mode 100644 index a78dd4e..0000000 --- a/library/persistence/mysql/scripts/create_database.sql +++ /dev/null @@ -1,163 +0,0 @@ -SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; -SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; -SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES'; - --- ----------------------------------------------------- --- Schema mydb --- ----------------------------------------------------- --- ----------------------------------------------------- --- Schema cms_dev --- ----------------------------------------------------- -CREATE SCHEMA IF NOT EXISTS `cms_dev` DEFAULT CHARACTER SET latin1 ; -USE `cms_dev` ; - --- ----------------------------------------------------- --- Table `cms_dev`.`users` --- ----------------------------------------------------- -CREATE TABLE IF NOT EXISTS `cms_dev`.`users` ( - `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `username` VARCHAR(100) NOT NULL, - `password` VARCHAR(100) NOT NULL, - `salt` VARCHAR(100) NOT NULL, - `email` VARCHAR(250) NOT NULL, - `creation_date` DATETIME NULL DEFAULT NULL, - `last_login_date` DATETIME NULL DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE INDEX `username` (`username` ASC)) -ENGINE = InnoDB -AUTO_INCREMENT = 2 -DEFAULT CHARACTER SET = latin1; - - --- ----------------------------------------------------- --- Table `cms_dev`.`nodes` --- ----------------------------------------------------- -CREATE TABLE IF NOT EXISTS `cms_dev`.`nodes` ( - `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `publication_date` DATE NOT NULL, - `creation_date` DATE NOT NULL, - `modification_date` DATE NOT NULL, - `title` VARCHAR(255) NOT NULL, - `summary` TEXT NOT NULL, - `content` MEDIUMTEXT NOT NULL, - `author_id` INT(10) UNSIGNED NULL DEFAULT NULL, - `version` INT(10) UNSIGNED ZEROFILL NULL DEFAULT NULL, - `editor_id` INT(10) UNSIGNED NULL DEFAULT NULL, - PRIMARY KEY (`id`), - INDEX `fk_nodes_users1_idx` (`author_id` ASC), - INDEX `fk_nodes_users2_idx` (`editor_id` ASC), - CONSTRAINT `fk_nodes_users1` - FOREIGN KEY (`author_id`) - REFERENCES `cms_dev`.`users` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION, - CONSTRAINT `fk_nodes_users2` - FOREIGN KEY (`editor_id`) - REFERENCES `cms_dev`.`users` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION) -ENGINE = InnoDB -AUTO_INCREMENT = 11 -DEFAULT CHARACTER SET = latin1; - - --- ----------------------------------------------------- --- Table `cms_dev`.`roles` --- ----------------------------------------------------- -CREATE TABLE IF NOT EXISTS `cms_dev`.`roles` ( - `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `role` VARCHAR(100) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE INDEX `role` (`role` ASC)) -ENGINE = InnoDB -DEFAULT CHARACTER SET = latin1; - - --- ----------------------------------------------------- --- Table `cms_dev`.`permissions` --- ----------------------------------------------------- -CREATE TABLE IF NOT EXISTS `cms_dev`.`permissions` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `name` VARCHAR(45) NOT NULL, - `roles_id` INT(10) UNSIGNED NOT NULL, - PRIMARY KEY (`id`), - UNIQUE INDEX `name_UNIQUE` (`name` ASC), - INDEX `fk_permissions_roles1_idx` (`roles_id` ASC), - CONSTRAINT `fk_permissions_roles1` - FOREIGN KEY (`roles_id`) - REFERENCES `cms_dev`.`roles` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION) -ENGINE = InnoDB -DEFAULT CHARACTER SET = latin1; - - --- ----------------------------------------------------- --- Table `cms_dev`.`profiles` --- ----------------------------------------------------- -CREATE TABLE IF NOT EXISTS `cms_dev`.`profiles` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `key` VARCHAR(45) NOT NULL, - `value` VARCHAR(100) NULL DEFAULT NULL, - `users_id` INT(10) UNSIGNED NOT NULL, - PRIMARY KEY (`id`), - UNIQUE INDEX `key_UNIQUE` (`key` ASC), - INDEX `fk_profiles_users1_idx` (`users_id` ASC), - CONSTRAINT `fk_profiles_users1` - FOREIGN KEY (`users_id`) - REFERENCES `cms_dev`.`users` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION) -ENGINE = InnoDB -DEFAULT CHARACTER SET = latin1; - - --- ----------------------------------------------------- --- Table `cms_dev`.`users_nodes` --- ----------------------------------------------------- -CREATE TABLE IF NOT EXISTS `cms_dev`.`users_nodes` ( - `users_id` INT(10) UNSIGNED NOT NULL, - `nodes_id` INT(10) UNSIGNED NOT NULL, - PRIMARY KEY (`users_id`, `nodes_id`), - INDEX `fk_users_has_nodes_nodes1_idx` (`nodes_id` ASC), - INDEX `fk_users_has_nodes_users_idx` (`users_id` ASC), - CONSTRAINT `fk_users_has_nodes_nodes1` - FOREIGN KEY (`nodes_id`) - REFERENCES `cms_dev`.`nodes` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION, - CONSTRAINT `fk_users_has_nodes_users` - FOREIGN KEY (`users_id`) - REFERENCES `cms_dev`.`users` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION) -ENGINE = InnoDB -DEFAULT CHARACTER SET = latin1; - - --- ----------------------------------------------------- --- Table `cms_dev`.`users_roles` --- ----------------------------------------------------- -CREATE TABLE IF NOT EXISTS `cms_dev`.`users_roles` ( - `users_id` INT(10) UNSIGNED NOT NULL, - `roles_id` INT(10) UNSIGNED NOT NULL, - PRIMARY KEY (`users_id`, `roles_id`), - INDEX `fk_users_has_roles_roles1_idx` (`roles_id` ASC), - INDEX `fk_users_has_roles_users1_idx` (`users_id` ASC), - CONSTRAINT `fk_users_has_roles_roles1` - FOREIGN KEY (`roles_id`) - REFERENCES `cms_dev`.`roles` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION, - CONSTRAINT `fk_users_has_roles_users1` - FOREIGN KEY (`users_id`) - REFERENCES `cms_dev`.`users` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION) -ENGINE = InnoDB -DEFAULT CHARACTER SET = latin1; - - -SET SQL_MODE=@OLD_SQL_MODE; -SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; -SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/library/persistence/mysql/scripts/schema.sql b/library/persistence/mysql/scripts/schema.sql deleted file mode 100644 index 382707e..0000000 --- a/library/persistence/mysql/scripts/schema.sql +++ /dev/null @@ -1,72 +0,0 @@ -SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; -SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; -SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES'; - --- ----------------------------------------------------- --- Schema mydb --- ----------------------------------------------------- --- ----------------------------------------------------- --- Schema roc_cms --- ----------------------------------------------------- -DROP SCHEMA IF EXISTS `roc_cms` ; -CREATE SCHEMA IF NOT EXISTS `roc_cms` DEFAULT CHARACTER SET latin1 ; -USE `roc_cms` ; - --- ----------------------------------------------------- --- Table `roc_cms`.`nodes` --- ----------------------------------------------------- -DROP TABLE IF EXISTS `roc_cms`.`nodes` ; - -CREATE TABLE IF NOT EXISTS `roc_cms`.`nodes` ( - `nid` INT(11) NOT NULL AUTO_INCREMENT, - `version` INT(11) NULL DEFAULT NULL, - `type` INT(11) NULL DEFAULT NULL, - `title` VARCHAR(255) NOT NULL, - `summary` TEXT NOT NULL, - `content` MEDIUMTEXT NOT NULL, - `author` INT(11) NULL DEFAULT NULL, - `publish` DATETIME NULL DEFAULT NULL, - `created` DATETIME NOT NULL, - `changed` DATETIME NOT NULL, - PRIMARY KEY (`nid`)) -ENGINE = InnoDB -DEFAULT CHARACTER SET = latin1; - - --- ----------------------------------------------------- --- Table `roc_cms`.`users` --- ----------------------------------------------------- -DROP TABLE IF EXISTS `roc_cms`.`users` ; - -CREATE TABLE IF NOT EXISTS `roc_cms`.`users` ( - `uid` INT(11) NOT NULL AUTO_INCREMENT, - `name` VARCHAR(100) NOT NULL, - `password` VARCHAR(100) NOT NULL, - `salt` VARCHAR(100) NOT NULL, - `email` VARCHAR(250) NOT NULL, - `status` INT(11) NULL DEFAULT NULL, - `created` DATETIME NOT NULL, - `signed` DATETIME NULL DEFAULT NULL, - PRIMARY KEY (`uid`), - UNIQUE INDEX `name` (`name` ASC)) -ENGINE = InnoDB -DEFAULT CHARACTER SET = latin1; - - --- ----------------------------------------------------- --- Table `roc_cms`.`users_roles` --- ----------------------------------------------------- -DROP TABLE IF EXISTS `roc_cms`.`users_roles` ; - -CREATE TABLE IF NOT EXISTS `roc_cms`.`users_roles` ( - `rid` INT(11) NOT NULL AUTO_INCREMENT, - `role` VARCHAR(100) NOT NULL, - PRIMARY KEY (`rid`), - UNIQUE INDEX `role` (`role` ASC)) -ENGINE = InnoDB -DEFAULT CHARACTER SET = latin1; - - -SET SQL_MODE=@OLD_SQL_MODE; -SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; -SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/library/persistence/mysql/scripts/tables.sql b/library/persistence/mysql/scripts/tables.sql deleted file mode 100644 index 4b1a4ba..0000000 --- a/library/persistence/mysql/scripts/tables.sql +++ /dev/null @@ -1,14 +0,0 @@ -DROP TABLE IF EXISTS nodes; - -CREATE TABLE nodes -( - id smallint unsigned NOT NULL auto_increment, - publication_date date NOT NULL, #When the article was published - creation_date date NOT NULL, #When the article was created - modification_date date NOT NULL, #When the article was updated - title varchar(255) NOT NULL, #Full title of the article - summary text NOT NULL, #A short summary of the articule - content mediumtext NOT NULL, #The HTML content of the article - - PRIMARY KEY (ID) -); \ No newline at end of file diff --git a/library/persistence/mysql/scripts/triggers.sql b/library/persistence/mysql/scripts/triggers.sql deleted file mode 100644 index b3e10a4..0000000 --- a/library/persistence/mysql/scripts/triggers.sql +++ /dev/null @@ -1,8 +0,0 @@ -DELIMITER $$ -CREATE TRIGGER update_editor -AFTER INSERT ON `users_nodes` FOR EACH ROW - UPDATE Nodes - SET editor_id = NEW.users_id - WHERE id = NEW.nodes_id; -$$ -DELIMITER ; \ No newline at end of file diff --git a/library/persistence/mysql/tests/roles/role_test_set.e- b/library/persistence/mysql/tests/roles/role_test_set.e- deleted file mode 100644 index bac254a..0000000 --- a/library/persistence/mysql/tests/roles/role_test_set.e- +++ /dev/null @@ -1,100 +0,0 @@ -note - description: "Summary description for {ROLE_TEST_SET}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - ROLE_TEST_SET -inherit - EQA_TEST_SET - redefine - on_prepare, - on_clean - select - default_create - end - ABSTRACT_DB_TEST - rename - default_create as default_db_test - end - - -feature {NONE} -- Events - - on_prepare - -- - do - (create {CLEAN_DB}).clean_db(connection) - end - - on_clean - -- - do - end - -feature -- Test routines - - test_roles_empty - do - assert ("Not elements",role_provider.roles.after) - assert ("Count = 0", role_provider.count = 0) - end - - test_roles_by_id_not_exist - do - assert ("Void", role_provider.role (1) = Void) - end - - test_roles_by_name_not_exist - do - assert ("Void", role_provider.role_by_name ("admin") = Void) - end - - test_new_role - do - assert ("Count = 0", role_provider.count = 0) - role_provider.new_role ("admin") - assert ("Count = 1", role_provider.count = 1) - assert ("Expected role", attached role_provider.role (1) as l_role and then l_role.name ~ "admin") - assert ("Expected role", attached role_provider.role_by_name ("admin") as l_role and then l_role.id = 1) - end - - test_permissions_empty_not_exist_role - do - assert ("Not elements",role_provider.permission_by_role (1).after) - end - - test_permissions_empty_exist_role - do - assert ("Count = 0", role_provider.count = 0) - role_provider.new_role ("admin") - assert ("Count = 1", role_provider.count = 1) - assert ("Exist role",not role_provider.roles.after) - assert ("Not permission by role 1 elements",role_provider.permission_by_role (1).after) - end - - test_new_role_with_permissions - do - assert ("Count = 0", role_provider.count = 0) - role_provider.new_role ("admin") - role_provider.save_role_permission (1, "Create Page") - role_provider.save_role_permission (1, "Edit Page") - role_provider.save_role_permission (1, "Delete Page") - assert ("Count = 1", role_provider.count = 1) - assert ("Exist role",not role_provider.roles.after) - assert ("Exist role permissions",not role_provider.permission_by_role (1).after) - assert ("Not Exist role permissions, for id 2",role_provider.permission_by_role (2).after) - end - - - - -feature {NONE} -- Implementation - - role_provider: ROLE_DATA_PROVIDER - -- role provider. - once - create Result.make (connection) - end -end diff --git a/library/persistence/mysql/src/cms_storage_mysql.e b/library/persistence/store_mysql/src/cms_storage_store_mysql.e similarity index 61% rename from library/persistence/mysql/src/cms_storage_mysql.e rename to library/persistence/store_mysql/src/cms_storage_store_mysql.e index 2cc5535..80f5586 100644 --- a/library/persistence/mysql/src/cms_storage_mysql.e +++ b/library/persistence/store_mysql/src/cms_storage_store_mysql.e @@ -1,10 +1,10 @@ note - description: "Summary description for {CMS_STORAGE_MYSQL}." + description: "Summary description for {CMS_STORAGE_STORE_MYSQL}." date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $" revision: "$Revision: 96596 $" class - CMS_STORAGE_MYSQL + CMS_STORAGE_STORE_MYSQL inherit CMS_STORAGE_STORE_SQL @@ -26,4 +26,12 @@ feature -- Status report Result := has_user end +feature -- Conversion + + sql_statement (a_statement: STRING): STRING + -- + do + Result := a_statement + end + end diff --git a/library/persistence/mysql/src/cms_storage_mysql_builder.e b/library/persistence/store_mysql/src/cms_storage_store_mysql_builder.e similarity index 84% rename from library/persistence/mysql/src/cms_storage_mysql_builder.e rename to library/persistence/store_mysql/src/cms_storage_store_mysql_builder.e index 2249df3..b3af541 100644 --- a/library/persistence/mysql/src/cms_storage_mysql_builder.e +++ b/library/persistence/store_mysql/src/cms_storage_store_mysql_builder.e @@ -1,13 +1,13 @@ note description: "[ - Interface responsible to instantiate CMS_STORAGE_MYSQL object. + Interface responsible to instantiate CMS_STORAGE_STORE_MYSQL object. ]" author: "$Author: jfiat $" date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $" revision: "$Revision: 96542 $" class - CMS_STORAGE_MYSQL_BUILDER + CMS_STORAGE_STORE_MYSQL_BUILDER inherit CMS_STORAGE_STORE_SQL_BUILDER @@ -26,7 +26,7 @@ feature {NONE} -- Initialization feature -- Factory - storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_MYSQL + storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_STORE_MYSQL local conn: DATABASE_CONNECTION do diff --git a/library/persistence/mysql/src/database/database_connection_mysql.e b/library/persistence/store_mysql/src/database/database_connection_mysql.e similarity index 52% rename from library/persistence/mysql/src/database/database_connection_mysql.e rename to library/persistence/store_mysql/src/database/database_connection_mysql.e index 05776f6..1a95b6a 100644 --- a/library/persistence/mysql/src/database/database_connection_mysql.e +++ b/library/persistence/store_mysql/src/database/database_connection_mysql.e @@ -14,66 +14,24 @@ inherit end create - make, make_common, make_basic, login_with_connection_string, login_with_schema + login, login_with_default, login_with_database_name, login_with_connection_string, login_with_schema feature -- Initialization - make_common + login_with_default -- Create a database handler for MYSQL with common settings. - local - l_retried: BOOLEAN do - create database_error_handler.make - create db_application.login (username, password) - - if not l_retried then - db_application.set_hostname (hostname) - db_application.set_data_source (database_name) - db_application.set_base - create db_control.make - keep_connection := is_keep_connection - if keep_connection then - connect - end - else - create db_control.make - end - rescue - create database_error_handler.make - exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) - l_retried := True - retry + login_with_database_name (default_database_name) end - make_basic (a_database_name: STRING) + login_with_database_name (a_database_name: STRING) -- Create a database handler and -- set database_name to `a_database_name'. - local - l_retried: BOOLEAN do - create database_error_handler.make - create db_application.login (username, password) - - if not l_retried then - db_application.set_hostname (hostname) - db_application.set_data_source (a_database_name) - db_application.set_base - create db_control.make - keep_connection := is_keep_connection - if keep_connection then - connect - end - else - create db_control.make - end - rescue - create database_error_handler.make - exception_as_error ((create {EXCEPTION_MANAGER}).last_exception) - l_retried := True - retry + login (default_username, default_password, default_hostname, a_database_name, is_keep_connection) end - make (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN) + login (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN) -- Create a database handler for ODBC and set `username' to `a_username', -- `password' to `a_password' @@ -93,26 +51,23 @@ feature -- Initialization end login_with_connection_string (a_string: STRING) - -- Login with `a_connection_string'and immediately connect to database. + -- Login with `a_connection_string' and immediately connect to database. local - l_string: LIST[STRING] l_server: STRING l_port: STRING - l_schema: STRING + l_database: STRING l_user: STRING l_password: STRING do create database_error_handler.make - - l_string := a_string.split (';') - l_server := l_string.at (2).split ('=').at (2) - l_port := l_string.at (3).split ('=').at (2) - l_schema := l_string.at (4).split ('=').at (2) - l_user := l_string.at (5).split ('=').at (2) - l_password := l_string.at (6).split ('=').at (2) + l_server := connection_string_item (a_string, "Server", default_hostname) + l_database := connection_string_item (a_string, "Database", default_database_name) + l_port := connection_string_item (a_string, "Port", "3306") + l_user := connection_string_item (a_string, "Uid", default_username) + l_password := connection_string_item (a_string, "Pwd", default_password) create db_application - db_application.set_application (l_schema) + db_application.set_application (l_database) db_application.set_hostname (l_server + ":" + l_port) db_application.login_and_connect (l_user, l_password) db_application.set_base @@ -120,6 +75,26 @@ feature -- Initialization keep_connection := is_keep_connection end + connection_string_item (a_connection_string: STRING; k: STRING; dft: STRING): STRING + local + i,j: INTEGER + do + i := a_connection_string.substring_index (k + "=", 1) + if i = 0 then + i := a_connection_string.substring_index (k.as_lower + "=", 1) + end + if i > 0 then + i := i + k.count + 1 + j := a_connection_string.index_of (';', i) + if j = 0 then + j := a_connection_string.count + 1 + end + Result := a_connection_string.substring (i, j - 1) + else + Result := dft + end + end + login_with_schema (a_schema: STRING; a_username: STRING; a_password: STRING) -- Login with `a_connection_string'and immediately connect to database. do diff --git a/library/persistence/mysql/persistence_mysql-safe.ecf b/library/persistence/store_mysql/store_mysql-safe.ecf similarity index 90% rename from library/persistence/mysql/persistence_mysql-safe.ecf rename to library/persistence/store_mysql/store_mysql-safe.ecf index 77f0d6b..b397e9c 100644 --- a/library/persistence/mysql/persistence_mysql-safe.ecf +++ b/library/persistence/store_mysql/store_mysql-safe.ecf @@ -1,6 +1,6 @@ - - + + - + /EIFGENs$ /CVS$ diff --git a/library/persistence/mysql/tests/application.e b/library/persistence/store_mysql/tests/application.e similarity index 100% rename from library/persistence/mysql/tests/application.e rename to library/persistence/store_mysql/tests/application.e diff --git a/library/persistence/mysql/tests/handler/database_handler_test.e b/library/persistence/store_mysql/tests/handler/database_handler_test.e similarity index 100% rename from library/persistence/mysql/tests/handler/database_handler_test.e rename to library/persistence/store_mysql/tests/handler/database_handler_test.e diff --git a/library/persistence/mysql/tests/nodes/node_test_set.e b/library/persistence/store_mysql/tests/nodes/node_test_set.e similarity index 100% rename from library/persistence/mysql/tests/nodes/node_test_set.e rename to library/persistence/store_mysql/tests/nodes/node_test_set.e diff --git a/library/persistence/mysql/tests/storage/storage_test_set.e b/library/persistence/store_mysql/tests/storage/storage_test_set.e similarity index 100% rename from library/persistence/mysql/tests/storage/storage_test_set.e rename to library/persistence/store_mysql/tests/storage/storage_test_set.e diff --git a/library/persistence/mysql/tests/tests.ecf b/library/persistence/store_mysql/tests/tests.ecf similarity index 100% rename from library/persistence/mysql/tests/tests.ecf rename to library/persistence/store_mysql/tests/tests.ecf diff --git a/library/persistence/mysql/tests/transactions/transaction_test_set.e b/library/persistence/store_mysql/tests/transactions/transaction_test_set.e similarity index 100% rename from library/persistence/mysql/tests/transactions/transaction_test_set.e rename to library/persistence/store_mysql/tests/transactions/transaction_test_set.e diff --git a/library/persistence/mysql/tests/users/user_test_set.e b/library/persistence/store_mysql/tests/users/user_test_set.e similarity index 100% rename from library/persistence/mysql/tests/users/user_test_set.e rename to library/persistence/store_mysql/tests/users/user_test_set.e diff --git a/library/persistence/mysql/tests/util/abstract_db_test.e b/library/persistence/store_mysql/tests/util/abstract_db_test.e similarity index 100% rename from library/persistence/mysql/tests/util/abstract_db_test.e rename to library/persistence/store_mysql/tests/util/abstract_db_test.e diff --git a/library/persistence/mysql/tests/util/clean_db.e b/library/persistence/store_mysql/tests/util/clean_db.e similarity index 100% rename from library/persistence/mysql/tests/util/clean_db.e rename to library/persistence/store_mysql/tests/util/clean_db.e diff --git a/library/persistence/store_odbc/src/cms_storage_store_odbc.e b/library/persistence/store_odbc/src/cms_storage_store_odbc.e new file mode 100644 index 0000000..1fa9922 --- /dev/null +++ b/library/persistence/store_odbc/src/cms_storage_store_odbc.e @@ -0,0 +1,82 @@ +note + description: "Summary description for {CMS_STORAGE_STORE_ODBC}." + date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $" + revision: "$Revision: 96596 $" + +class + CMS_STORAGE_STORE_ODBC + +inherit + CMS_STORAGE_STORE_SQL + redefine + make + end + + CMS_CORE_STORAGE_SQL_I + + CMS_USER_STORAGE_SQL_I + + REFACTORING_HELPER + +create + make, + make_with_driver + +feature {NONE} -- Initialization + + make (a_connection: DATABASE_CONNECTION) + -- + do + Precursor (a_connection) + create odbc_driver.make_from_string_general ("odbc") + end + + make_with_driver (a_connection: DATABASE_CONNECTION; a_driver: detachable READABLE_STRING_GENERAL) + require + is_connected: a_connection.is_connected + do + make (a_connection) + if a_driver /= Void then + create odbc_driver.make_from_string_general (a_driver) + end + end + +feature -- Status report + + odbc_driver: IMMUTABLE_STRING_32 + -- Database's driver name. + -- sqlite, mysql, ... + + is_initialized: BOOLEAN + -- Is storage initialized? + do + Result := has_user + end + +feature -- Conversion + + sql_statement (a_statement: STRING): STRING + -- . + local + i: INTEGER + do + Result := a_statement + if odbc_driver.same_caseless_characters_general ("sqlite3", 1, 5, 1) then + from + i := 1 + until + i = 0 + loop + i := a_statement.substring_index ("AUTO_INCREMENT", i) + if i > 0 then + if Result = a_statement then + create Result.make_from_string (a_statement) + end + Result.remove (i + 4) + i := i + 14 + end + end + end + end + +end diff --git a/library/persistence/store_odbc/src/cms_storage_store_odbc_builder.e b/library/persistence/store_odbc/src/cms_storage_store_odbc_builder.e new file mode 100644 index 0000000..ba65841 --- /dev/null +++ b/library/persistence/store_odbc/src/cms_storage_store_odbc_builder.e @@ -0,0 +1,68 @@ +note + description: "[ + Interface responsible to instantiate CMS_STORAGE_STORE_ODBC object. + ]" + author: "$Author: jfiat $" + date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $" + revision: "$Revision: 96616 $" + +class + CMS_STORAGE_STORE_ODBC_BUILDER + +inherit + CMS_STORAGE_STORE_SQL_BUILDER + + GLOBAL_SETTINGS + +create + make + +feature {NONE} -- Initialization + + make + -- Initialize `Current'. + do + end + +feature -- Factory + + storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_STORE_ODBC + local + s: detachable STRING + conn: detachable DATABASE_CONNECTION + do + if + attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.environment.application_config_path) as l_database_config + then + if l_database_config.driver.is_case_insensitive_equal ("odbc") then + s := l_database_config.database_string + if attached reuseable_connection.item as d then + if s.same_string (d.name) then + conn := d.connection + end + end + if conn = Void or else not conn.is_connected then + create {DATABASE_CONNECTION_ODBC} conn.login_with_connection_string (s) + reuseable_connection.replace ([s, conn]) + end + if conn.is_connected then + create Result.make_with_driver (conn, l_database_config.item ("Driver")) + set_map_zero_null_value (False) --| This way we map 0 to 0, instead of Null as default. + if Result.is_available then + if not Result.is_initialized then + initialize (a_setup, Result) + end + end + end + else + -- Wrong mapping between storage name and storage builder! + end + end + end + + reuseable_connection: CELL [detachable TUPLE [name: STRING; connection: DATABASE_CONNECTION]] + once + create Result.put (Void) + end + +end diff --git a/library/persistence/mysql/persistence_mysql.ecf b/library/persistence/store_odbc/store_odbc-safe.ecf similarity index 53% rename from library/persistence/mysql/persistence_mysql.ecf rename to library/persistence/store_odbc/store_odbc-safe.ecf index a572b69..e06a4d0 100644 --- a/library/persistence/mysql/persistence_mysql.ecf +++ b/library/persistence/store_odbc/store_odbc-safe.ecf @@ -1,30 +1,26 @@ - - + + - - - - - - - - - - - - - - - - - /database/database_connection_odbc.e - - - + + + + + + + + + + + + + + + /EIFGENs$ /CVS$ diff --git a/library/persistence/store_odbc/tests/Readme.md b/library/persistence/store_odbc/tests/Readme.md new file mode 100644 index 0000000..b81d64f --- /dev/null +++ b/library/persistence/store_odbc/tests/Readme.md @@ -0,0 +1,26 @@ +SQLite ODBC. + +Install the odbc driver from http://www.ch-werner.de/sqliteodbc/ + +Current version + sqliteodbc.exe -- Win32 + sqliteodbc_w64.exe -- Win64 + + +Test the ODBC driver using Firefox SQLite DBManager https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/ + +1. Open the odbc manger from Windows, create a new database using the SQLite3 ODBC driver and then open it from Firefox. + + +EiffelStore + SQLiteODBC. + +Connection String: https://www.connectionstrings.com/sqlite3-odbc-driver/ + + "Driver=SQLite3 ODBC Driver;Database=./cms_lite.db;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;" + +Edit the database location based on your system. + + + + + diff --git a/library/persistence/store_odbc/tests/application.e b/library/persistence/store_odbc/tests/application.e new file mode 100644 index 0000000..9b3ede1 --- /dev/null +++ b/library/persistence/store_odbc/tests/application.e @@ -0,0 +1,29 @@ +note + description : "tests application root class" + date : "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $" + revision : "$Revision: 96542 $" + +class + APPLICATION + +inherit + ARGUMENTS + +create + make + +feature {NONE} -- Initialization + + make + -- Run application. + local + storage: CMS_STORAGE_SQLITE + do + -- Change the path. + create connection.login_with_connection_string ("Driver=SQLite3 ODBC Driver;Database=./cms_lite.db;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;") + create storage.make (connection) + end + + connection: DATABASE_CONNECTION_ODBC + +end diff --git a/library/persistence/store_odbc/tests/cms_lite.db b/library/persistence/store_odbc/tests/cms_lite.db new file mode 100644 index 0000000..208c3a4 Binary files /dev/null and b/library/persistence/store_odbc/tests/cms_lite.db differ diff --git a/library/persistence/store_odbc/tests/nodes/node_test_set.e b/library/persistence/store_odbc/tests/nodes/node_test_set.e new file mode 100644 index 0000000..e80f720 --- /dev/null +++ b/library/persistence/store_odbc/tests/nodes/node_test_set.e @@ -0,0 +1,205 @@ +note + description: "[ + Eiffel tests that can be executed by testing tool. + ]" + author: "EiffelStudio test wizard" + date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $" + revision: "$Revision: 96542 $" + testing: "type/manual" + +class + NODE_TEST_SET + +inherit + EQA_TEST_SET + redefine + on_prepare, + on_clean + select + default_create + end + ABSTRACT_DB_TEST + rename + default_create as default_db_test + end + + +feature {NONE} -- Events + + on_prepare + -- + do + (create {CLEAN_DB}).clean_db(connection) + assert ("Empty Nodes", storage.nodes.after) + end + + on_clean + -- + do + end + +feature -- Test routines + + test_new_node + do + assert ("Empty Nodes", storage.nodes.after) + storage.new_node (default_node) + assert ("Not empty Nodes after new_node", not storage.nodes.after) + -- Exist node with id 1 + assert ("Exist node with id 1", attached storage.node_by_id (1)) + -- Not exist node with id 2 + assert ("Not exist node with id 2", storage.node_by_id (2) = Void) + end + + + test_update_node + local + l_node: CMS_NODE + do + assert ("Empty Nodes", storage.nodes.after) + l_node := custom_node ("

test node udpate

", "Update node", "Test case update") + storage.new_node (l_node) + assert ("Not empty Nodes after new_node", not storage.nodes.after) + -- Exist node with id 1 + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then ll_node.content ~ l_node.content and then ll_node.summary ~ l_node.summary and then ll_node.title ~ l_node.title ) + + -- Update node (content and summary) + + if attached {CMS_NODE} storage.node_by_id (1) as l_un then + l_un.set_content ("

Updating test node udpate

") + l_un.set_summary ("updating summary") + storage.update_node (l_un) + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then not (ll_node.content ~ l_node.content) and then not (ll_node.summary ~ l_node.summary) and then ll_node.title ~ l_node.title ) + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then ll_node.content ~ l_un.content and then ll_node.summary ~ l_un.summary and then ll_node.title ~ l_un.title ) + end + + -- Update node (content and summary and title) + if attached {CMS_NODE} storage.node_by_id (1) as l_un then + l_un.set_content ("

Updating test node udpate

") + l_un.set_summary ("updating summary") + l_un.set_title ("Updating Test case") + storage.update_node (l_un) + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then not (ll_node.content ~ l_node.content) and then not (ll_node.summary ~ l_node.summary) and then not (ll_node.title ~ l_node.title) ) + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then ll_node.content ~ l_un.content and then ll_node.summary ~ l_un.summary and then ll_node.title ~ l_un.title ) + end + end + + test_update_title + local + l_node: CMS_NODE + do + assert ("Empty Nodes", storage.nodes.after) + l_node := custom_node ("

test node udpate

", "Update node", "Test case update") + storage.new_node (l_node) + assert ("Not empty Nodes after new_node", not storage.nodes.after) + -- Exist node with id 1 + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then ll_node.content ~ l_node.content and then ll_node.summary ~ l_node.summary and then ll_node.title ~ l_node.title ) + + -- Update node title + + if attached {CMS_NODE} storage.node_by_id (1) as l_un then + storage.update_node_title (1, l_un.id, "New Title") + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then ll_node.content ~ l_un.content and then ll_node.summary ~ l_un.summary and then not ( ll_node.title ~ l_un.title) and then ll_node.title ~ "New Title" ) + end + end + + test_update_summary + local + l_node: CMS_NODE + do + assert ("Empty Nodes", storage.nodes.after) + l_node := custom_node ("

test node udpate

", "Update node", "Test case update") + storage.new_node (l_node) + assert ("Not empty Nodes after new_node", not storage.nodes.after) + -- Exist node with id 1 + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then ll_node.content ~ l_node.content and then ll_node.summary ~ l_node.summary and then ll_node.title ~ l_node.title ) + + -- Update node summary + + if attached {CMS_NODE} storage.node_by_id (1) as l_un then + storage.update_node_summary (1, l_un.id,"New Summary") + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then ll_node.content ~ l_un.content and then not (ll_node.summary ~ l_un.summary) and then ll_node.summary ~ "New Summary" and then ll_node.title ~ l_un.title) + end + end + + test_update_content + local + l_node: CMS_NODE + do + assert ("Empty Nodes", storage.nodes.after) + l_node := custom_node ("

test node udpate

", "Update node", "Test case update") + storage.new_node (l_node) + assert ("Not empty Nodes after new_node", not storage.nodes.after) + -- Exist node with id 1 + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then ll_node.content ~ l_node.content and then ll_node.summary ~ l_node.summary and then ll_node.title ~ l_node.title ) + + -- Update node content + + if attached {CMS_NODE} storage.node_by_id (1) as l_un then + storage.update_node_content (1, l_un.id, "New Content") + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then not (ll_node.content ~ l_un.content) and then ll_node.content ~ "New Content" and then ll_node.summary ~ l_un.summary and then ll_node.title ~ l_un.title) + end + end + + + test_delete_node + local + l_node: CMS_NODE + do + assert ("Empty Nodes", storage.nodes.after) + l_node := custom_node ("

test node udpate

", "Update node", "Test case update") + storage.new_node (l_node) + assert ("Not empty Nodes after new_node", not storage.nodes.after) + -- Exist node with id 1 + assert ("Exist node with id 1", attached {CMS_NODE} storage.node_by_id (1) as ll_node and then ll_node.content ~ l_node.content and then ll_node.summary ~ l_node.summary and then ll_node.title ~ l_node.title ) + + -- Delte node 1 + + storage.delete_node_by_id (1) + assert ("Node does not exist", storage.node_by_id (1) = Void) + end + + test_recent_nodes + -- Content_10, Summary_10, Title_10 + -- Content_9, Summary_9, Title_9 + -- .. + -- Content_1, Summary_1, Title_1 + local + i : INTEGER + do + assert ("Empty Nodes", storage.nodes.after) + across 1 |..| 10 as c loop + storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)) + end + + -- Scenario (0,10) rows, recents (10 down to 1) + i := 10 + across storage.recent_nodes (0, 10) as c loop + assert ("Same id:" + i.out, c.item.id = i) + i := i - 1 + end + + -- Scenario (5, 10) rows, recent nodes (5 down to 1) + i := 5 + across storage.recent_nodes (5, 10) as c loop + assert ("Same id:" + i.out, c.item.id = i) + i := i - 1 + end + + -- Scenario (9,10) rows, recent node 1 + i := 1 + across storage.recent_nodes (9, 10) as c loop + assert ("Same id:" + i.out, c.item.id = i) + i := i - 1 + end + + -- Scenrario 10..10 empty + assert ("Empty", storage.recent_nodes (10, 10).after) + + end + + +end + + + diff --git a/library/persistence/store_odbc/tests/storage/storage_test_set.e b/library/persistence/store_odbc/tests/storage/storage_test_set.e new file mode 100644 index 0000000..0189001 --- /dev/null +++ b/library/persistence/store_odbc/tests/storage/storage_test_set.e @@ -0,0 +1,273 @@ +note + description: "Summary description for {STORAGE_TEST_SET}." + author: "" + date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $" + revision: "$Revision: 96542 $" + +class + STORAGE_TEST_SET + +inherit + EQA_TEST_SET + redefine + on_prepare, + on_clean + select + default_create + end + ABSTRACT_DB_TEST + rename + default_create as default_db_test + end + + +feature {NONE} -- Events + + on_prepare + -- + do + (create {CLEAN_DB}).clean_db(connection) + end + + on_clean + -- + do + end + +feature -- Test routines + + test_has_user + do + assert ("Not has user", not storage.has_user) + end + + test_all_users + do + assert ("to implement all_users", False) + end + + test_user_by_id_not_exist + do + assert ("User does not exist", storage.user_by_id (1) = Void) + end + + test_user_by_name_not_exist + do + assert ("User does not exist", storage.user_by_name ("test") = Void) + end + + test_user_by_email_not_exist + do + assert ("User does not exist", storage.user_by_name ("test@test.com") = Void) + end + + test_user_with_bad_id + local + l_retry: BOOLEAN + l_user: detachable CMS_USER + do + if not l_retry then + l_user := storage.user_by_id (0) + assert ("Precondition does not get the wrong value", False) + else + assert ("Expected precondition violation", True) + end + rescue + l_retry := True + retry + end + + test_user_with_bad_name_empty + local + l_retry: BOOLEAN + l_user: detachable CMS_USER + do + if not l_retry then + l_user := storage.user_by_name ("") + assert ("Precondition does not get the wrong value", False) + else + assert ("Expected precondition violation", True) + end + rescue + l_retry := True + retry + end + + test_user_with_bad_email_empty + local + l_retry: BOOLEAN + l_user: detachable CMS_USER + do + if not l_retry then + l_user := storage.user_by_email ("") + assert ("Precondition does not get the wrong value", False) + else + assert ("Expected precondition violation", True) + end + rescue + l_retry := True + retry + end + + test_save_user + do + storage.save_user (default_user) + assert ("Has user", storage.has_user) + end + + test_user_by_id + do + storage.save_user (default_user) + assert ("Has user", storage.has_user) + if attached {CMS_USER} storage.user_by_id (1) as l_user then + assert ("Exist", True) + assert ("User test", l_user.name ~ "test") + assert ("User id = 1", l_user.id = 1) + else + assert ("Wrong Implementation", False) + end + end + + test_user_by_name + do + storage.save_user (default_user) + assert ("Has user", storage.has_user) + if attached {CMS_USER} storage.user_by_name ("test") as l_user then + assert ("Exist", True) + assert ("User nane: test", l_user.name ~ "test") + else + assert ("Wrong Implementation", False) + end + end + + test_user_by_email + do + storage.save_user (default_user) + assert ("Has user", storage.has_user) + if attached {CMS_USER} storage.user_by_email ("test@test.com") as l_user then + assert ("Exist", True) + assert ("User email: test@test.com", l_user.email ~ "test@test.com") + else + assert ("Wrong Implementation", False) + end + end + + test_invalid_credential + do + storage.save_user (default_user) + assert ("Has user test", attached storage.user_by_name ("test")) + assert ("Wrong password", not storage.is_valid_credential ("test", "test")) + assert ("Wrong user", not storage.is_valid_credential ("test1", "test")) + end + + test_valid_credential + do + storage.save_user (default_user) + assert ("Has user test", attached storage.user_by_name ("test")) + assert ("Valid password", storage.is_valid_credential ("test", "password")) + end + +-- test_recent_nodes_empty +-- do +-- assert ("No recent nodes", storage.recent_nodes (0, 10).is_empty) +-- end + +-- test_recent_nodes +-- local +-- l_nodes: LIST[CMS_NODE] +-- do +-- across 1 |..| 10 as c loop +-- storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)) +-- end +-- l_nodes := storage.recent_nodes (0, 10) +-- assert ("10 recent nodes", l_nodes.count = 10) +-- assert ("First node id=10", l_nodes.first.id = 10) +-- assert ("Last node id=1", l_nodes.last.id = 1) + + +-- l_nodes := storage.recent_nodes (5, 10) +-- assert ("5 recent nodes", l_nodes.count = 5) +-- assert ("First node id=5", l_nodes.first.id = 5) +-- assert ("Last node id=1", l_nodes.last.id = 1) + +-- l_nodes := storage.recent_nodes (9, 10) +-- assert ("1 recent nodes", l_nodes.count = 1) +-- assert ("First node id=1", l_nodes.first.id = 1) +-- assert ("Last node id=1", l_nodes.last.id = 1) + +-- l_nodes := storage.recent_nodes (10, 10) +-- assert ("Is empty", l_nodes.is_empty) +-- end + +-- test_node_does_not_exist +-- do +-- across 1 |..| 10 as c loop +-- storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)) +-- end +-- assert ("Not exist node id: 12", storage.node_by_id (12) = Void) +-- end + +-- test_node +-- do +-- across 1 |..| 10 as c loop +-- storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)) +-- end +-- assert ("has nodes", storage.nodes.count > 5) +-- assert ("Node id: 10", attached storage.node_by_id (10) as l_node and then l_node.title ~ "Title_10" ) +-- end + +-- test_update_node +-- local +-- l_node: CMS_NODE +-- do +-- storage.new_node (custom_node ("Content", "Summary", "Title")) +-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then +-- l_node := ll_node.twin +-- l_node.set_content ("New Content") +-- l_node.set_summary ("New Summary") +-- l_node.set_title("New Title") + +---- storage.update_node (l_node) +-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then not (u_node.content ~ ll_node.content) and then not (u_node.summary ~ ll_node.summary)) +-- end +-- end + +-- test_update_node_title +-- do +-- storage.new_node (custom_node ("Content", "Summary", "Title")) +-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then +---- storage.update_node_title (ll_node.id, "New Title") +-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then u_node.content ~ ll_node.content and then u_node.summary ~ ll_node.summary) +-- end +-- end + +-- test_update_node_summary +-- do +-- storage.new_node (custom_node ("Content", "Summary", "Title")) +-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then +---- storage.update_node_summary (ll_node.id, "New Summary") +-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then u_node.content ~ ll_node.content and then not (u_node.summary ~ ll_node.summary)) +-- end +-- end + +-- test_update_node_content +-- do +-- storage.new_node (custom_node ("Content", "Summary", "Title")) +-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then +---- storage.update_node_content (ll_node.id, "New Content") +-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then not (u_node.content ~ ll_node.content) and then u_node.summary ~ ll_node.summary) +-- end +-- end + +-- test_delete_node +-- do +-- across 1 |..| 10 as c loop +-- storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)) +-- end +-- assert ("Exist node id: 10", attached storage.node_by_id (10) as l_node and then l_node.title ~ "Title_10" ) +-- storage.delete_node_by_id (10) +-- assert ("Not exist node id: 10", storage.node_by_id (10) = Void) +-- end + + +end diff --git a/library/persistence/store_odbc/tests/tests-safe.ecf b/library/persistence/store_odbc/tests/tests-safe.ecf new file mode 100644 index 0000000..a8f1365 --- /dev/null +++ b/library/persistence/store_odbc/tests/tests-safe.ecf @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + /nodes$ + + + + diff --git a/library/persistence/store_odbc/tests/users/user_test_set.e b/library/persistence/store_odbc/tests/users/user_test_set.e new file mode 100644 index 0000000..db5047c --- /dev/null +++ b/library/persistence/store_odbc/tests/users/user_test_set.e @@ -0,0 +1,72 @@ +note + description: "[ + Eiffel tests that can be executed by testing tool. + ]" + author: "EiffelStudio test wizard" + date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $" + revision: "$Revision: 96542 $" + testing: "type/manual" + +class + USER_TEST_SET + +inherit + EQA_TEST_SET + redefine + on_prepare, + on_clean + select + default_create + end + ABSTRACT_DB_TEST + rename + default_create as default_db_test + end + + +feature {NONE} -- Events + + on_prepare + -- + do + (create {CLEAN_DB}).clean_db(connection) + storage.new_user (custom_user ("admin", "admin","admin@admin.com")) + end + + on_clean + -- + do + end + +feature -- Test routines + + test_user_exist + -- User admin exist + do + assert ("Not void", attached storage.user_by_email ("admin@admin.com")) + assert ("Not void", attached storage.user_by_id (1)) + assert ("Not void", attached storage.user_by_name ("admin")) + end + + test_user_not_exist + -- Uset test does not exist. + do + assert ("Void", storage.user_by_email ("test@admin.com") = Void) + assert ("Void", storage.user_by_id (2) = Void ) + assert ("Void", storage.user_by_name ("test") = Void) + end + + test_new_user + do + storage.new_user (custom_user ("test", "test","test@admin.com")) + assert ("Not void", attached storage.user_by_email ("test@admin.com")) + assert ("Not void", attached storage.user_by_id (2)) + assert ("Not void", attached storage.user_by_id (2) as l_user and then l_user.id = 2 and then l_user.name ~ "test") + assert ("Not void", attached storage.user_by_name ("test")) + end + + + +end + + diff --git a/library/persistence/store_odbc/tests/util/abstract_db_test.e b/library/persistence/store_odbc/tests/util/abstract_db_test.e new file mode 100644 index 0000000..3ce95e3 --- /dev/null +++ b/library/persistence/store_odbc/tests/util/abstract_db_test.e @@ -0,0 +1,55 @@ +note + description: "Summary description for {ABSTRACT_DB_TEST}." + date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $" + revision: "$Revision: 96542 $" + +class + ABSTRACT_DB_TEST + + +feature -- Database connection + + connection: DATABASE_CONNECTION_ODBC + -- odbc database connection + once + create Result.login_with_connection_string ("Driver=SQLite3 ODBC Driver;Database=cms_lite.db;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;") +-- create Result.make_basic ("cms_lite.db") + end + +feature {NONE} -- Implementation + + storage: CMS_STORAGE + -- node provider. + once + create {CMS_STORAGE_SQLITE} Result.make (connection) + end + +feature {NONE} -- Fixture Factory: Users + + default_user: CMS_USER + do + Result := custom_user ("test", "password", "test@test.com") + end + + custom_user (a_name, a_password, a_email: READABLE_STRING_32): CMS_USER + do + create Result.make (a_name) + Result.set_password (a_password) + Result.set_email (a_email) + end + +--feature {NONE} -- Fixture Factories: Nodes + +-- default_node: CMS_NODE +-- do +-- Result := custom_node ("Default content", "default summary", "Default") +-- end + +-- custom_node (a_content, a_summary, a_title: READABLE_STRING_32): CMS_PAGE +-- do +-- create Result.make (a_title) +-- Result.set_content (a_content, a_summary, Void) +-- end + + +end diff --git a/library/persistence/store_odbc/tests/util/clean_db.e b/library/persistence/store_odbc/tests/util/clean_db.e new file mode 100644 index 0000000..d381540 --- /dev/null +++ b/library/persistence/store_odbc/tests/util/clean_db.e @@ -0,0 +1,66 @@ +note + description: "[ + Setting up database tests + 1. Put the database in a known state before running your test suite. + 2. Data reinitialization. For testing in developer sandboxes, something that you should do every time you rebuild the system, you may want to forgo dropping and rebuilding the database in favor of simply reinitializing the source data. + You can do this either by erasing all existing data and then inserting the initial data vales back into the database, or you can simple run updates to reset the data values. + The first approach is less risky and may even be faster for large amounts of data. - See more at: http://www.agiledata.org/essays/databaseTesting.html#sthash.6yVp35g8.dpuf + ]" + + date: "$Date$" + revision: "$Revision$" + EIS: "name=Database Testing", "src=http://www.agiledata.org/essays/databaseTesting.html", "protocol=uri" + +class + CLEAN_DB + +feature + + clean_db (a_connection: DATABASE_CONNECTION) + -- Clean db test. + local + l_parameters: STRING_TABLE[STRING] + do + create l_parameters.make (0) + + db_handler(a_connection).set_query (create {DATABASE_QUERY}.data_reader (Sql_delete_nodes, l_parameters)) + db_handler(a_connection).execute_change + + -- Clean Users + db_handler(a_connection).set_query (create {DATABASE_QUERY}.data_reader (Sql_delete_users, l_parameters)) + db_handler(a_connection).execute_change + +-- -- Reset Autoincremente +-- db_handler(a_connection).set_query (create {DATABASE_QUERY}.data_reader (Rest_users_autoincrement, l_parameters)) +-- db_handler(a_connection).execute_change + +-- db_handler(a_connection).set_query (create {DATABASE_QUERY}.data_reader (Rest_nodes_autoincrement, l_parameters)) +-- db_handler(a_connection).execute_change + end + + + +feature -- Database Hanlder + + db_handler (a_connection: DATABASE_CONNECTION): DATABASE_HANDLER + -- Db handler + once + create {DATABASE_HANDLER_IMPL} Result.make (a_connection) + end + + +feature -- Sql delete queries + + Sql_delete_users: STRING = "delete from Users" + -- Clean Users. + + Sql_delete_nodes: STRING = "delete from Nodes" + -- Clean Nodes. + + Rest_users_autoincrement: STRING = "ALTER TABLE Users AUTO_INCREMENT = 1" + -- reset autoincrement + + Rest_nodes_autoincrement: STRING = "ALTER TABLE Nodes AUTO_INCREMENT = 1" + -- reset autoincrement. + +end diff --git a/src/persistence/sql/cms_proxy_storage_sql.e b/src/persistence/sql/cms_proxy_storage_sql.e index 212cfa8..10a37b2 100644 --- a/src/persistence/sql/cms_proxy_storage_sql.e +++ b/src/persistence/sql/cms_proxy_storage_sql.e @@ -109,4 +109,12 @@ feature -- Access Result:= sql_storage.sql_item (a_index) end +feature -- Conversion + + sql_statement (a_statement: STRING): STRING + -- + do + Result := sql_storage.sql_statement (a_statement) + end + end diff --git a/src/persistence/sql/cms_storage_sql_i.e b/src/persistence/sql/cms_storage_sql_i.e index 8f38ab0..6a1e903 100644 --- a/src/persistence/sql/cms_storage_sql_i.e +++ b/src/persistence/sql/cms_storage_sql_i.e @@ -150,22 +150,42 @@ feature -- Helper sql_execute_script (a_sql_script: STRING) -- Execute SQL script. -- i.e: multiple SQL statements. + local + i: INTEGER + err: BOOLEAN do reset_error --- sql_begin_transaction - sql_change (a_sql_script, Void) --- sql_commit_transaction + sql_begin_transaction +-- Issue on MySQL with multiple statements +-- sql_change (a_sql_script, Void) + from + i := 1 + until + i > a_sql_script.count or err + loop + if attached next_sql_statement (a_sql_script, i) as s then + if not s.is_whitespace then + sql_change (sql_statement (s), Void) + err := err or has_error + reset_error + end + i := i + s.count + else + i := a_sql_script.count + 1 + end + end + if err then + sql_rollback_transaction + else + sql_commit_transaction + end end sql_table_exists (a_table_name: READABLE_STRING_8): BOOLEAN -- Does table `a_table_name' exists? - local - l_params: STRING_TABLE [detachable ANY] do reset_error - create l_params.make (1) - l_params.force (a_table_name, "tbname") - sql_query ("SELECT count(*) FROM :tbname ;", l_params) + sql_query ("SELECT count(*) FROM " + a_table_name + " ;", Void) Result := not has_error -- FIXME: find better solution reset_error @@ -173,13 +193,9 @@ feature -- Helper sql_table_items_count (a_table_name: READABLE_STRING_8): INTEGER_64 -- Number of items in table `a_table_name'? - local - l_params: STRING_TABLE [detachable ANY] do reset_error - create l_params.make (1) - l_params.force (a_table_name, "tbname") - sql_query ("SELECT count(*) FROM :tbname ;", l_params) + sql_query ("SELECT count(*) FROM " + a_table_name + " ;", Void) if not has_error then Result := sql_read_integer_64 (1) end @@ -325,4 +341,57 @@ feature -- Access end end +feature -- Conversion + + sql_statement (a_statement: STRING): STRING + -- Statement normalized for underlying SQL database. + deferred + end + +feature {NONE} -- Implementation + + next_sql_statement (a_script: STRING; a_start_index: INTEGER): detachable STRING + local + i,j,n: INTEGER + c: CHARACTER + l_end: INTEGER + do + from + i := a_start_index + n := a_script.count + until + i > n or a_script[i] = ';' + loop + c := a_script[i] + inspect c + when '`', '"', '%'' then + from + j := i + l_end := 0 + until + l_end > 0 or j > n + loop + j := a_script.index_of (c, i + 1) + if j > i then + if a_script [j - 1] /= '\' then + l_end := j + end + end + end + if l_end > 0 then + i := l_end + else + i := j + end + else + + end + i := i + 1 + end + i := a_script.index_of (';', a_start_index) + if i > a_start_index then + Result := a_script.substring (a_start_index, i) + end + end + end