Added weight into to the CMS_LINK and provide a `sort' feature for CMS_MENU and related.
Protected cms service from registering many time the same module type.
Moved library/persistence/implementation/* under library/persistence/.
Moved site/www/themes to site/themes
For SQLite storage driver, auto create sqlite db file using associated sql script (to be completed).
Added code in demo module to reuse storage for module purpose.
Always call sql_post_execution in sql_query and sql_change, and not anymore by the callers.
Removed is_web and is_html from {CMS_SETUP}, it was not used.
Reused SHARED_*_ENCODER in CMS_ENCODERS
Added CMS_API.logger rather than using directly the SHARED_LOGGER.log ...
Centralize the implementation of current_user in CMS_REQUEST_UTIL
Removed the inheritance on WSF_FILTER for node handlers, since it is useless and unused.
Added CMS_NODE_API and CMS_USER_API
Prefix html id for block generated html items with "block-", to avoid css name conflict on "main", "content" or similar.
Code cleaning
This commit is contained in:
121
library/persistence/implementation/store/cms_storage_store_sql.e
Normal file
121
library/persistence/implementation/store/cms_storage_store_sql.e
Normal file
@@ -0,0 +1,121 @@
|
||||
note
|
||||
description: "Summary description for {CMS_STORAGE_STORE_SQL}."
|
||||
author: ""
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
deferred class
|
||||
CMS_STORAGE_STORE_SQL
|
||||
|
||||
inherit
|
||||
CMS_STORAGE
|
||||
|
||||
CMS_STORAGE_SQL
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_connection: DATABASE_CONNECTION)
|
||||
--
|
||||
require
|
||||
is_connected: a_connection.is_connected
|
||||
do
|
||||
connection := a_connection
|
||||
log.write_information (generator + ".make - is database connected? "+ a_connection.is_connected.out )
|
||||
|
||||
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
||||
|
||||
create error_handler.make
|
||||
-- error_handler.add_synchronization (db_handler.database_error_handler)
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_available: BOOLEAN
|
||||
-- Is storage available?
|
||||
do
|
||||
Result := connection.is_connected
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
db_handler: DATABASE_HANDLER
|
||||
|
||||
connection: DATABASE_CONNECTION
|
||||
-- Current database connection.
|
||||
|
||||
feature -- Query
|
||||
|
||||
sql_post_execution
|
||||
-- Post database execution.
|
||||
do
|
||||
error_handler.append (db_handler.database_error_handler)
|
||||
if error_handler.has_error then
|
||||
log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
|
||||
end
|
||||
end
|
||||
|
||||
sql_begin_transaction
|
||||
do
|
||||
connection.begin_transaction
|
||||
end
|
||||
|
||||
sql_rollback_transaction
|
||||
do
|
||||
connection.rollback
|
||||
end
|
||||
|
||||
sql_commit_transaction
|
||||
do
|
||||
connection.commit
|
||||
end
|
||||
|
||||
sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||
do
|
||||
check_sql_query_validity (a_sql_statement, a_params)
|
||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
|
||||
db_handler.execute_query
|
||||
sql_post_execution
|
||||
end
|
||||
|
||||
sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||
do
|
||||
check_sql_query_validity (a_sql_statement, a_params)
|
||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
|
||||
db_handler.execute_change
|
||||
sql_post_execution
|
||||
end
|
||||
|
||||
sql_rows_count: INTEGER
|
||||
-- Number of rows for last sql execution.
|
||||
do
|
||||
Result := db_handler.count
|
||||
end
|
||||
|
||||
sql_start
|
||||
-- Set the cursor on first element.
|
||||
do
|
||||
db_handler.start
|
||||
end
|
||||
|
||||
sql_after: BOOLEAN
|
||||
-- Are there no more items to iterate over?
|
||||
do
|
||||
Result := db_handler.after
|
||||
end
|
||||
|
||||
sql_forth
|
||||
-- Fetch next row from last sql execution, if any.
|
||||
do
|
||||
db_handler.forth
|
||||
end
|
||||
|
||||
sql_item (a_index: INTEGER): detachable ANY
|
||||
do
|
||||
if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then
|
||||
Result := l_item.item (a_index)
|
||||
else
|
||||
check has_item_at_index: False end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
note
|
||||
description: "Database configuration"
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
deferred class
|
||||
DATABASE_CONFIG
|
||||
|
||||
feature -- Database access
|
||||
|
||||
hostname: STRING = ""
|
||||
-- Database hostname.
|
||||
|
||||
username: STRING = ""
|
||||
-- Database username.
|
||||
|
||||
password: STRING = ""
|
||||
-- Database password.
|
||||
|
||||
database_name: STRING = "EiffelDB"
|
||||
-- Database name.
|
||||
|
||||
is_keep_connection: BOOLEAN
|
||||
-- Keep Connection to database?
|
||||
do
|
||||
Result := True
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,191 @@
|
||||
note
|
||||
description: "Abstract class to handle a database connection"
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
deferred class
|
||||
DATABASE_CONNECTION
|
||||
|
||||
inherit
|
||||
|
||||
DATABASE_CONFIG
|
||||
|
||||
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)
|
||||
|
||||
-- Create a database handler with user `a_username', password `a_password',
|
||||
-- host `a_hostname', database_name `a_database_name', and keep_connection `connection'.
|
||||
require
|
||||
username_not_void: a_username /= Void
|
||||
username_not_empty: not a_username.is_empty
|
||||
password_not_void: a_password /= Void
|
||||
hostname_not_void: a_hostname /= Void
|
||||
hotname_not_empty: not a_hostname.is_empty
|
||||
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
|
||||
|
||||
login_with_connection_string (a_connection_string: STRING)
|
||||
-- Login with `a_connection_string'
|
||||
-- and immediately connect to database.
|
||||
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]
|
||||
-- Database application.
|
||||
|
||||
db_control: DB_CONTROL
|
||||
-- Database control.
|
||||
|
||||
keep_connection: BOOLEAN
|
||||
-- Keep connection alive?
|
||||
|
||||
feature -- Transactions
|
||||
|
||||
begin_transaction
|
||||
-- Start a transaction which will be terminated by a call to `rollback' or `commit'.
|
||||
local
|
||||
rescued: BOOLEAN
|
||||
do
|
||||
if not rescued then
|
||||
if db_control.is_ok then
|
||||
db_control.begin
|
||||
else
|
||||
database_error_handler.add_database_error (db_control.error_message_32, db_control.error_code)
|
||||
end
|
||||
end
|
||||
rescue
|
||||
rescued := True
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
db_control.reset
|
||||
retry
|
||||
end
|
||||
|
||||
commit
|
||||
-- Commit updates in the database.
|
||||
local
|
||||
rescued: BOOLEAN
|
||||
do
|
||||
if not rescued then
|
||||
if db_control.is_ok then
|
||||
db_control.commit
|
||||
else
|
||||
database_error_handler.add_database_error (db_control.error_message_32, db_control.error_code)
|
||||
end
|
||||
end
|
||||
rescue
|
||||
rescued := True
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
db_control.reset
|
||||
retry
|
||||
end
|
||||
|
||||
rollback
|
||||
-- Rollback updates in the database.
|
||||
local
|
||||
rescued: BOOLEAN
|
||||
do
|
||||
if not rescued then
|
||||
if db_control.is_ok then
|
||||
db_control.rollback
|
||||
else
|
||||
database_error_handler.add_database_error (db_control.error_message_32, db_control.error_code)
|
||||
end
|
||||
end
|
||||
rescue
|
||||
rescued := True
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
db_control.reset
|
||||
retry
|
||||
end
|
||||
|
||||
feature -- Change Element
|
||||
|
||||
not_keep_connection
|
||||
do
|
||||
keep_connection := False
|
||||
end
|
||||
|
||||
feature -- Conection
|
||||
|
||||
connect
|
||||
-- Connect to the database.
|
||||
require else
|
||||
db_control_not_void: db_control /= Void
|
||||
do
|
||||
if not is_connected then
|
||||
db_control.connect
|
||||
end
|
||||
end
|
||||
|
||||
disconnect
|
||||
-- Disconnect from the database.
|
||||
require else
|
||||
db_control_not_void: db_control /= Void
|
||||
do
|
||||
db_control.disconnect
|
||||
end
|
||||
|
||||
is_connected: BOOLEAN
|
||||
-- True if connected to the database.
|
||||
require else
|
||||
db_control_not_void: db_control /= Void
|
||||
do
|
||||
Result := db_control.is_connected
|
||||
end
|
||||
|
||||
feature -- Error Handling
|
||||
|
||||
database_error_handler: DATABASE_ERROR_HANDLER
|
||||
-- Error handler.
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
has_error: BOOLEAN
|
||||
-- Has error?
|
||||
do
|
||||
Result := database_error_handler.has_error
|
||||
end
|
||||
|
||||
feature -- Helper
|
||||
|
||||
exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception)
|
||||
-- Record 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)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -0,0 +1,68 @@
|
||||
note
|
||||
description: "Null object to meet Void Safe."
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
class
|
||||
DATABASE_CONNECTION_NULL
|
||||
|
||||
inherit
|
||||
|
||||
DATABASE_CONNECTION
|
||||
redefine
|
||||
db_application,
|
||||
is_connected
|
||||
end
|
||||
|
||||
create
|
||||
make, make_common, make_basic
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
make_common
|
||||
-- Create a database handler for ODBC with common settings.
|
||||
do
|
||||
create database_error_handler.make
|
||||
create db_application.login (username, password)
|
||||
db_application.set_hostname (hostname)
|
||||
db_application.set_data_source (database_name)
|
||||
db_application.set_base
|
||||
create db_control.make
|
||||
end
|
||||
|
||||
make (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN)
|
||||
|
||||
-- Create a database handler for ODBC.
|
||||
do
|
||||
make_common
|
||||
end
|
||||
|
||||
make_basic (a_database_name: STRING)
|
||||
|
||||
-- Create a database handler for ODBC.
|
||||
do
|
||||
make_common
|
||||
end
|
||||
|
||||
|
||||
login_with_connection_string (a_string: STRING)
|
||||
-- Login with `a_connection_string'
|
||||
-- and immediately connect to database.
|
||||
do
|
||||
make_common
|
||||
end
|
||||
|
||||
|
||||
feature -- Databse Connection
|
||||
|
||||
db_application: DATABASE_APPL[DATABASE_NULL]
|
||||
-- Database application.
|
||||
|
||||
|
||||
is_connected: BOOLEAN
|
||||
-- True if connected to the database.
|
||||
do
|
||||
Result := True
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,128 @@
|
||||
note
|
||||
description: "Object that handle a database connection for ODBC"
|
||||
date: "$Date: 2014-11-13 12:23:47 -0300 (ju., 13 nov. 2014) $"
|
||||
revision: "$Revision: 96085 $"
|
||||
|
||||
class
|
||||
DATABASE_CONNECTION_ODBC
|
||||
|
||||
inherit
|
||||
|
||||
DATABASE_CONNECTION
|
||||
redefine
|
||||
db_application
|
||||
end
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
create
|
||||
make, make_common, make_basic, 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")
|
||||
-- log.write_critical (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")
|
||||
-- log.write_critical (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)
|
||||
|
||||
-- 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'
|
||||
do
|
||||
create database_error_handler.make
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
login_with_connection_string (a_string: STRING)
|
||||
-- Login with `a_connection_string'and immediately connect to database.
|
||||
do
|
||||
log.write_debug (generator +".login_with_connection_string")
|
||||
create db_application.login_with_connection_string (a_string)
|
||||
create database_error_handler.make
|
||||
db_application.set_base
|
||||
create db_control.make
|
||||
log.write_debug (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
|
||||
log.write_critical (generator +".login_with_connection_string:"+ db_control.error_code.out )
|
||||
log.write_critical (generator +".login_with_connection_string:"+ db_control.error_message_32 )
|
||||
end
|
||||
log.write_debug (generator +".login_with_connection_string, After connect, is_connected? "+ is_connected.out)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Databse Connection
|
||||
|
||||
db_application: DATABASE_APPL [ODBC]
|
||||
-- Database application.
|
||||
|
||||
end
|
||||
@@ -0,0 +1,237 @@
|
||||
note
|
||||
description: "Abstract Database Handler"
|
||||
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
|
||||
revision: "$Revision: 96542 $"
|
||||
|
||||
deferred class
|
||||
DATABASE_HANDLER
|
||||
|
||||
inherit
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
feature -- Access
|
||||
|
||||
store: detachable DATABASE_STORE_PROCEDURE
|
||||
-- Database stored_procedure to handle.
|
||||
|
||||
query: detachable DATABASE_QUERY
|
||||
-- Database query.
|
||||
|
||||
feature -- Modifiers
|
||||
|
||||
set_store (a_store: DATABASE_STORE_PROCEDURE)
|
||||
-- Set `store' to `a_store' to execute.
|
||||
require
|
||||
store_not_void: a_store /= Void
|
||||
do
|
||||
store := a_store
|
||||
ensure
|
||||
store_set: store = a_store
|
||||
end
|
||||
|
||||
set_query (a_query: DATABASE_QUERY)
|
||||
-- Set `query' to `a_query' to execute.
|
||||
require
|
||||
query_not_void: a_query /= Void
|
||||
do
|
||||
query := a_query
|
||||
ensure
|
||||
query_set: query = a_query
|
||||
end
|
||||
|
||||
feature -- Functionality Store Procedures
|
||||
|
||||
execute_store_reader
|
||||
-- Execute a `store' to read data.
|
||||
require
|
||||
store_not_void: store /= Void
|
||||
deferred
|
||||
end
|
||||
|
||||
execute_store_writer
|
||||
-- Execute a `store' to write data.
|
||||
require
|
||||
store_not_void: store /= Void
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- SQL Queries
|
||||
|
||||
execute_query
|
||||
-- Execute sql query, the read data from the database.
|
||||
require
|
||||
query_not_void: query /= Void
|
||||
deferred
|
||||
end
|
||||
|
||||
execute_change
|
||||
-- Execute sql query that update/add data.
|
||||
require
|
||||
query_not_void: query /= Void
|
||||
deferred
|
||||
end
|
||||
|
||||
|
||||
feature -- Iteration
|
||||
|
||||
start
|
||||
-- Set the cursor on first element.
|
||||
deferred
|
||||
end
|
||||
|
||||
item: ANY
|
||||
-- Item at current cursor position.
|
||||
require
|
||||
valid_position: not after
|
||||
deferred
|
||||
end
|
||||
|
||||
after: BOOLEAN
|
||||
-- Are there no more items to iterate over?
|
||||
deferred
|
||||
end
|
||||
|
||||
forth
|
||||
-- Move to next position.
|
||||
require
|
||||
valid_position: not after
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
read_integer_32 (a_index: INTEGER): INTEGER_32
|
||||
-- Retrieved value at `a_index' position in `item'.
|
||||
do
|
||||
if attached {DB_TUPLE} item as l_item then
|
||||
if attached {INTEGER_32_REF} l_item.item (a_index) as ll_item then
|
||||
Result := ll_item.item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
read_string (a_index: INTEGER): detachable STRING
|
||||
-- Retrieved value at `a_index' position in `item'.
|
||||
do
|
||||
if attached {DB_TUPLE} item as l_item then
|
||||
if attached {STRING} l_item.item (a_index) as ll_item then
|
||||
Result := ll_item
|
||||
elseif attached {BOOLEAN_REF} l_item.item (a_index) as ll_item then
|
||||
Result := ll_item.item.out
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
read_date_time (a_index: INTEGER): detachable DATE_TIME
|
||||
-- Retrieved value at `a_index' position in `item'.
|
||||
do
|
||||
if attached {DB_TUPLE} item as l_item then
|
||||
if attached {DATE_TIME} l_item.item (a_index) as ll_item then
|
||||
Result := ll_item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
read_boolean (a_index: INTEGER): detachable BOOLEAN
|
||||
-- Retrieved value at `a_index' position in `item'.
|
||||
do
|
||||
if attached {DB_TUPLE} item as l_item then
|
||||
if attached {BOOLEAN} l_item.item (a_index) as ll_item then
|
||||
Result := ll_item
|
||||
elseif attached {BOOLEAN_REF} l_item.item (a_index) as ll_item then
|
||||
Result := ll_item.item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
count: INTEGER
|
||||
-- Number of rows, last execution.
|
||||
deferred
|
||||
end
|
||||
|
||||
connection: DATABASE_CONNECTION
|
||||
-- Database connection.
|
||||
|
||||
db_control: DB_CONTROL
|
||||
-- Database control.
|
||||
do
|
||||
Result := connection.db_control
|
||||
end
|
||||
|
||||
db_result: detachable DB_RESULT
|
||||
-- Database query result.
|
||||
|
||||
db_selection: detachable DB_SELECTION
|
||||
-- Database selection.
|
||||
|
||||
db_change: detachable DB_CHANGE
|
||||
-- Database modification.
|
||||
|
||||
feature -- Error handling
|
||||
|
||||
check_database_change_error
|
||||
-- Check database error from `db_change'.
|
||||
do
|
||||
if attached db_change as l_change and then not l_change.is_ok then
|
||||
database_error_handler.add_database_error (l_change.error_message_32, l_change.error_code)
|
||||
log.write_error (generator + ".check_database_change_error: " + l_change.error_message_32)
|
||||
l_change.reset
|
||||
end
|
||||
end
|
||||
|
||||
check_database_selection_error
|
||||
-- Check database error from `db_selection'.
|
||||
do
|
||||
if attached db_selection as l_selection and then not l_selection.is_ok then
|
||||
database_error_handler.add_database_error (l_selection.error_message_32, l_selection.error_code)
|
||||
log.write_error (generator + ".check_database_selection_error: " + l_selection.error_message_32)
|
||||
l_selection.reset
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Error Handling
|
||||
|
||||
database_error_handler: DATABASE_ERROR_HANDLER
|
||||
-- Error handler.
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
has_error: BOOLEAN
|
||||
-- Has error?
|
||||
do
|
||||
Result := database_error_handler.has_error
|
||||
end
|
||||
|
||||
feature -- Helper
|
||||
|
||||
exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception)
|
||||
-- Record 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)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Connection Handling
|
||||
|
||||
connect
|
||||
-- Connect to the database.
|
||||
deferred
|
||||
end
|
||||
|
||||
disconnect
|
||||
-- Disconnect from the database.
|
||||
deferred
|
||||
ensure
|
||||
not_connected: not is_connected
|
||||
end
|
||||
|
||||
is_connected: BOOLEAN
|
||||
-- True if connected to the database.
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,234 @@
|
||||
note
|
||||
description: "Database handler Implementation"
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
class
|
||||
DATABASE_HANDLER_IMPL
|
||||
|
||||
inherit
|
||||
DATABASE_HANDLER
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_connection: DATABASE_CONNECTION)
|
||||
-- Create a database handler with connnection `connection'.
|
||||
do
|
||||
connection := a_connection
|
||||
create last_query.make_now
|
||||
create database_error_handler.make
|
||||
ensure
|
||||
connection_not_void: connection /= Void
|
||||
last_query_not_void: last_query /= Void
|
||||
database_error_handler_set: attached database_error_handler
|
||||
end
|
||||
|
||||
feature -- Functionality
|
||||
|
||||
execute_store_reader
|
||||
-- Execute stored procedure that returns data.
|
||||
local
|
||||
l_db_selection: DB_SELECTION
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
if not l_retried then
|
||||
database_error_handler.reset
|
||||
if attached store as l_store then
|
||||
create l_db_selection.make
|
||||
db_selection := l_db_selection
|
||||
items := l_store.execute_reader (l_db_selection)
|
||||
check_database_selection_error
|
||||
end
|
||||
log.write_debug ( generator+".execute_reader Successful")
|
||||
end
|
||||
rescue
|
||||
l_retried := True
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
if attached db_selection as l_selection then
|
||||
l_selection.reset
|
||||
end
|
||||
retry
|
||||
end
|
||||
|
||||
execute_store_writer
|
||||
-- Execute stored procedure that update/add data.
|
||||
local
|
||||
l_db_change: DB_CHANGE
|
||||
l_retried : BOOLEAN
|
||||
do
|
||||
if not l_retried then
|
||||
database_error_handler.reset
|
||||
if attached store as l_store then
|
||||
create l_db_change.make
|
||||
db_change := l_db_change
|
||||
l_store.execute_writer (l_db_change)
|
||||
check_database_change_error
|
||||
end
|
||||
log.write_debug ( generator+".execute_writer Successful")
|
||||
end
|
||||
rescue
|
||||
l_retried := True
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
if attached db_change as l_change then
|
||||
l_change.reset
|
||||
end
|
||||
retry
|
||||
end
|
||||
|
||||
feature -- SQL Queries
|
||||
|
||||
execute_query
|
||||
-- Execute query.
|
||||
local
|
||||
l_db_selection: DB_SELECTION
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
if not l_retried then
|
||||
database_error_handler.reset
|
||||
if attached query as l_query then
|
||||
create l_db_selection.make
|
||||
db_selection := l_db_selection
|
||||
items := l_query.execute_reader (l_db_selection)
|
||||
check_database_selection_error
|
||||
end
|
||||
end
|
||||
rescue
|
||||
l_retried := True
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
if attached db_selection as l_selection then
|
||||
l_selection.reset
|
||||
end
|
||||
retry
|
||||
end
|
||||
|
||||
|
||||
execute_change
|
||||
-- Execute sql_query that update/add data.
|
||||
local
|
||||
l_db_change: DB_CHANGE
|
||||
l_retried : BOOLEAN
|
||||
do
|
||||
if not l_retried then
|
||||
database_error_handler.reset
|
||||
if attached query as l_query then
|
||||
create l_db_change.make
|
||||
db_change := l_db_change
|
||||
l_query.execute_change (l_db_change)
|
||||
check_database_change_error
|
||||
end
|
||||
end
|
||||
rescue
|
||||
l_retried := True
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
if attached db_change as l_change then
|
||||
l_change.reset
|
||||
end
|
||||
retry
|
||||
end
|
||||
|
||||
|
||||
feature -- Iteration
|
||||
|
||||
start
|
||||
-- Set the cursor on first element.
|
||||
do
|
||||
if attached db_selection as l_db_selection and then l_db_selection.container /= Void then
|
||||
l_db_selection.start
|
||||
end
|
||||
end
|
||||
|
||||
forth
|
||||
-- Move cursor to next element.
|
||||
do
|
||||
if attached db_selection as l_db_selection then
|
||||
l_db_selection.forth
|
||||
else
|
||||
check False end
|
||||
end
|
||||
end
|
||||
|
||||
after: BOOLEAN
|
||||
-- True for the last element.
|
||||
do
|
||||
if attached db_selection as l_db_selection and then l_db_selection.container /= Void then
|
||||
Result := l_db_selection.after or else l_db_selection.cursor = Void
|
||||
else
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
|
||||
item: DB_TUPLE
|
||||
-- Current element.
|
||||
do
|
||||
if attached db_selection as l_db_selection and then attached l_db_selection.cursor as l_cursor then
|
||||
create {DB_TUPLE} Result.copy (l_cursor)
|
||||
else
|
||||
check False then end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
last_query: DATE_TIME
|
||||
-- Last time when a query was executed.
|
||||
|
||||
keep_connection: BOOLEAN
|
||||
-- Keep connection alive?
|
||||
do
|
||||
Result := connection.keep_connection
|
||||
end
|
||||
|
||||
connect
|
||||
-- Connect to the database.
|
||||
require else
|
||||
db_control_not_void: db_control /= Void
|
||||
do
|
||||
if not is_connected then
|
||||
db_control.connect
|
||||
end
|
||||
end
|
||||
|
||||
disconnect
|
||||
-- Disconnect from the database.
|
||||
require else
|
||||
db_control_not_void: db_control /= Void
|
||||
do
|
||||
db_control.disconnect
|
||||
end
|
||||
|
||||
is_connected: BOOLEAN
|
||||
-- True if connected to the database.
|
||||
require else
|
||||
db_control_not_void: db_control /= Void
|
||||
do
|
||||
Result := db_control.is_connected
|
||||
end
|
||||
|
||||
affected_row_count: INTEGER
|
||||
-- The number of rows changed, deleted, or inserted by the last statement.
|
||||
do
|
||||
if attached db_change as l_update then
|
||||
Result := l_update.affected_row_count
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Result
|
||||
|
||||
items : detachable LIST[DB_RESULT]
|
||||
-- Query result.
|
||||
|
||||
count: INTEGER
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached items as l_items then
|
||||
Result := l_items.count
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,91 @@
|
||||
note
|
||||
description: "External iteration cursor for {DATABASE_HANDLER}"
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
class
|
||||
DATABASE_ITERATION_CURSOR [G]
|
||||
|
||||
inherit
|
||||
|
||||
ITERATION_CURSOR [G]
|
||||
|
||||
ITERABLE [G]
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
make (a_handler: DATABASE_HANDLER; a_action: like action)
|
||||
-- Create an iterator and set `db_handlet' to `a_handler'
|
||||
-- `action' to `a_action'
|
||||
do
|
||||
db_handler := a_handler
|
||||
action := a_action
|
||||
ensure
|
||||
db_handler_set: db_handler = a_handler
|
||||
action_set: action = a_action
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
item: G
|
||||
-- Item at current cursor position.
|
||||
do
|
||||
Result := action.item ([db_item])
|
||||
end
|
||||
|
||||
db_item: DB_TUPLE
|
||||
-- Current element.
|
||||
do
|
||||
if attached {DB_TUPLE} db_handler.item as l_item then
|
||||
Result := l_item
|
||||
else
|
||||
check False then
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
after: BOOLEAN
|
||||
-- Are there no more items to iterate over?
|
||||
do
|
||||
Result := db_handler.after
|
||||
end
|
||||
|
||||
feature -- Cursor movement
|
||||
|
||||
start
|
||||
-- Set the cursor on first element.
|
||||
do
|
||||
db_handler.start
|
||||
end
|
||||
|
||||
forth
|
||||
-- Move to next position.
|
||||
do
|
||||
db_handler.forth
|
||||
end
|
||||
|
||||
feature -- Cursor
|
||||
|
||||
new_cursor: DATABASE_ITERATION_CURSOR [G]
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := twin
|
||||
Result.start
|
||||
end
|
||||
|
||||
feature -- Action
|
||||
|
||||
action: FUNCTION [ANY, detachable TUPLE, G]
|
||||
-- Agent to create a new item of type G.
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
db_handler: DATABASE_HANDLER
|
||||
-- Associated handler used for iteration.
|
||||
|
||||
end
|
||||
@@ -0,0 +1,539 @@
|
||||
note
|
||||
description: "Null object to meet void safe"
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
class
|
||||
DATABASE_NULL
|
||||
|
||||
inherit
|
||||
DATABASE
|
||||
|
||||
|
||||
feature -- Acccess
|
||||
|
||||
database_handle_name: STRING = "NULL"
|
||||
-- Handle name
|
||||
|
||||
feature -- For DATABASE_STATUS
|
||||
|
||||
is_error_updated: BOOLEAN
|
||||
-- Has an NULL function been called since last update which may have
|
||||
-- updated error code, error message?
|
||||
|
||||
is_warning_updated: BOOLEAN
|
||||
-- Has an ODBC function been called since last update which may have
|
||||
-- updated warning message?
|
||||
|
||||
found: BOOLEAN
|
||||
-- Is there any record matching the last
|
||||
-- selection condition used ?
|
||||
|
||||
clear_error
|
||||
-- Reset database error status.
|
||||
do
|
||||
end
|
||||
|
||||
insert_auto_identity_column: BOOLEAN = False
|
||||
-- For INSERTs and UPDATEs should table auto-increment identity columns be explicitly included in the statement?
|
||||
|
||||
feature -- For DATABASE_CHANGE
|
||||
|
||||
descriptor_is_available: BOOLEAN
|
||||
do
|
||||
end
|
||||
|
||||
|
||||
feature -- For DATABASE_FORMAT
|
||||
|
||||
date_to_str (object: DATE_TIME): STRING
|
||||
-- String representation in SQL of `object'
|
||||
-- For ODBC, ORACLE
|
||||
do
|
||||
create Result.make_empty
|
||||
end
|
||||
|
||||
string_format (object: detachable STRING): STRING
|
||||
-- String representation in SQL of `object'
|
||||
obsolete
|
||||
"Use `string_format_32' instead."
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
string_format_32 (object: detachable READABLE_STRING_GENERAL): STRING_32
|
||||
-- String representation in SQL of `object'
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
True_representation: STRING
|
||||
-- Database representation of the boolean True
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
False_representation: STRING
|
||||
-- Database representation of the boolean False
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
feature -- For DATABASE_SELECTION, DATABASE_CHANGE
|
||||
|
||||
normal_parse: BOOLEAN
|
||||
-- Should the SQL string be normal parsed,
|
||||
-- using SQL_SCAN?
|
||||
do
|
||||
end
|
||||
|
||||
feature -- DATABASE_STRING
|
||||
|
||||
sql_name_string: STRING
|
||||
-- SQL type name of string
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
feature -- DATABASE_REAL
|
||||
|
||||
sql_name_real: STRING
|
||||
-- SQL type name for real
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
feature -- DATABASE_DATETIME
|
||||
|
||||
sql_name_datetime: STRING
|
||||
-- SQL type name for datetime
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
feature -- DATABASE_DECIMAL
|
||||
|
||||
sql_name_decimal: STRING
|
||||
-- SQL type name for decimal
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
feature -- DATABASE_DOUBLE
|
||||
|
||||
sql_name_double: STRING
|
||||
-- SQL type name for double
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
feature -- DATABASE_CHARACTER
|
||||
|
||||
sql_name_character: STRING
|
||||
-- SQL type name for character
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
feature -- DATABASE_INTEGER
|
||||
|
||||
sql_name_integer: STRING
|
||||
-- SQL type name for integer
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
sql_name_integer_16: STRING
|
||||
-- SQL type name for integer
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
sql_name_integer_64: STRING
|
||||
-- SQL type name for integer
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
feature -- DATABASE_BOOLEAN
|
||||
|
||||
sql_name_boolean: STRING
|
||||
-- SQL type name for boolean
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
feature -- LOGIN and DATABASE_APPL only for password_ok
|
||||
|
||||
|
||||
password_ok (upasswd: STRING): BOOLEAN
|
||||
-- Can the user password be Void?
|
||||
do
|
||||
Result := True
|
||||
end
|
||||
|
||||
password_ensure (name, passwd, uname, upasswd: STRING): BOOLEAN
|
||||
-- Is name equal to uname and passwd equal to upasswd?
|
||||
do
|
||||
end
|
||||
|
||||
feature -- For DATABASE_PROC
|
||||
|
||||
|
||||
support_sql_of_proc: BOOLEAN
|
||||
-- Does the database support SQL attachment to the stored procedure?
|
||||
do
|
||||
end
|
||||
|
||||
support_stored_proc: BOOLEAN
|
||||
-- Does the database support creating a stored procedure?
|
||||
do
|
||||
end
|
||||
|
||||
sql_as: STRING
|
||||
-- Creating a stored procedure "as"...
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
sql_end: STRING
|
||||
-- End of the stored procedure creation string.
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
sql_execution: STRING
|
||||
-- Begining of the stored procedure execution string.
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
sql_creation: STRING
|
||||
-- Begining of the stored procedure creation string.
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
sql_after_exec: STRING
|
||||
-- End of the stored procedure execution string.
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
support_drop_proc: BOOLEAN
|
||||
-- Does the database support stored procedure dropping from server?
|
||||
do
|
||||
end
|
||||
|
||||
name_proc_lower: BOOLEAN
|
||||
-- Has the name of the stored procedure to be in lower case?
|
||||
do
|
||||
end
|
||||
|
||||
map_var_between: STRING
|
||||
-- @ symbol for ODBC and Sybase
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
map_var_name_32 (par_name: READABLE_STRING_GENERAL): STRING_32
|
||||
-- Redefined for Sybase
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
Select_text_32 (proc_name: READABLE_STRING_GENERAL): STRING_32
|
||||
-- SQL query to get stored procedure text
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
Select_exists_32 (name: READABLE_STRING_GENERAL): STRING_32
|
||||
-- SQL query to test stored procedure existing
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
|
||||
Selection_string (rep_qualifier, rep_owner, repository_name: STRING): STRING
|
||||
-- String to select the table needed
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
sql_string: STRING
|
||||
-- Database type of a string
|
||||
-- with a size less than Max_char_size
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
sql_string2 (int: INTEGER): STRING
|
||||
-- Database type of a string
|
||||
-- with a size more than Max_char_size
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
sql_wstring: STRING
|
||||
-- Database type of a string
|
||||
-- with a size less than Max_char_size
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
sql_wstring2 (int: INTEGER): STRING
|
||||
-- Database type of a string
|
||||
-- with a size more than Max_char_size
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
feature -- External features
|
||||
|
||||
get_error_message: POINTER
|
||||
-- Function related with the error processing
|
||||
do
|
||||
create Result
|
||||
end
|
||||
|
||||
get_error_message_string: STRING_32
|
||||
-- Function related with the error processing
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
get_error_code: INTEGER
|
||||
-- Function related with the error processing
|
||||
do
|
||||
end
|
||||
|
||||
get_warn_message: POINTER
|
||||
-- Function related with the error processing
|
||||
do
|
||||
create Result
|
||||
end
|
||||
|
||||
get_warn_message_string: STRING_32
|
||||
-- Function related with the error processing
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
new_descriptor: INTEGER
|
||||
-- A descriptor is used to store a row fetched by FETCH command
|
||||
-- Whenever perform a SELECT statement, allocate a new descriptor
|
||||
-- by int_new_descriptor(), the descriptor is freed
|
||||
-- when the SELECT statement terminates.
|
||||
do
|
||||
end
|
||||
|
||||
init_order (no_descriptor: INTEGER; command: READABLE_STRING_GENERAL)
|
||||
-- In DYNAMICALLY EXECUTE mode perform the SQL statement
|
||||
-- But this routine only get things ready for dynamic execution:
|
||||
-- 1. get the SQL statement PREPAREd; and check if there are
|
||||
-- warning message for the SQL statement;
|
||||
-- 2. DESCRIBE the SQL statement and get enough information to
|
||||
-- allocate enough memory space for the corresponding descriptor.
|
||||
do
|
||||
end
|
||||
|
||||
start_order (no_descriptor: INTEGER)
|
||||
-- Finish execution of a SQL statement in DYNAMICLLY EXECUTION mode: */
|
||||
-- 1. if the PREPAREd SQL statement is a NON_SELECT statement,
|
||||
-- just EXECUTE it; otherwise, DEFINE a CURSOR for it and
|
||||
-- OPEN the CURSOR. In the process, if error occurs, do some
|
||||
-- clearence;
|
||||
do
|
||||
end
|
||||
|
||||
next_row (no_descriptor: INTEGER)
|
||||
-- A SELECT statement is now being executed in DYNAMIC EXECUTION mode,
|
||||
-- the routine is to FETCH a new tuple from database
|
||||
-- and if a new tuple is fetched, return 1 otherwise return 0.
|
||||
do
|
||||
end
|
||||
|
||||
terminate_order (no_descriptor: INTEGER)
|
||||
-- A SQL has been performed in DYNAMIC EXECUTION mode,
|
||||
-- so the routine is to do some clearence:
|
||||
-- 1. if the DYNAMICALLY EXECUTED SQL statement is a NON_SELECT
|
||||
-- statement, just free the memory for ODBCSQLDA and clear
|
||||
-- the cell in 'descriptor' to NULL; otherwise, CLOSE the CURSOR
|
||||
-- and then do the same clearence.
|
||||
-- 2. return error number.
|
||||
do
|
||||
end
|
||||
|
||||
close_cursor (no_descriptor: INTEGER)
|
||||
-- A SQL has been performed in DYNAMIC EXECUTION mode,
|
||||
-- Then if the DYNAMICALLY EXECUTED SQL statement is a SELECT
|
||||
-- statement, then the cursor is closed.
|
||||
-- Then one can do an other selection on the previous cursor.
|
||||
do
|
||||
end
|
||||
|
||||
exec_immediate (no_descriptor: INTEGER; command: READABLE_STRING_GENERAL)
|
||||
-- In IMMEDIATE EXECUTE mode perform the SQL statement,
|
||||
-- and then check if there is warning message for the execution,
|
||||
do
|
||||
end
|
||||
|
||||
put_col_name (no_descriptor: INTEGER; index: INTEGER; ar: STRING; max_len:INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
put_data (no_descriptor: INTEGER; index: INTEGER; ar: STRING; max_len:INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
put_data_32 (no_descriptor: INTEGER; index: INTEGER; ar: STRING_32; max_len:INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
|
||||
conv_type (indicator: INTEGER; index: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
--| FIXME
|
||||
--| This description really does not explain a thing...
|
||||
do
|
||||
end
|
||||
|
||||
get_count (no_descriptor: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_data_len (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_col_len (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_col_type (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_integer_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_integer_16_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER_16
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_integer_64_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER_64
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_float_data (no_descriptor: INTEGER; ind: INTEGER): DOUBLE
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_real_data (no_descriptor: INTEGER; ind: INTEGER): REAL
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_boolean_data (no_descriptor: INTEGER; ind: INTEGER): BOOLEAN
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
is_null_data (no_descriptor: INTEGER; ind: INTEGER): BOOLEAN
|
||||
-- Is last retrieved data null?
|
||||
do
|
||||
end
|
||||
|
||||
get_date_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_hour (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_sec (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_min (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_year (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_day (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_month (no_descriptor: INTEGER; ind: INTEGER): INTEGER
|
||||
-- Function used to get data from structure SQLDA filled by FETCH clause.
|
||||
do
|
||||
end
|
||||
|
||||
get_decimal (no_descriptor: INTEGER; ind: INTEGER): detachable TUPLE [digits: STRING_8; sign, precision, scale: INTEGER]
|
||||
-- Function used to get decimal info
|
||||
do
|
||||
end
|
||||
|
||||
|
||||
database_make (i: INTEGER)
|
||||
-- Initialize database c-module
|
||||
do
|
||||
end
|
||||
|
||||
connect (user_name, user_passwd, data_source, application, hostname, role_id: STRING; role_passwd: detachable STRING; group_id: STRING)
|
||||
-- Connect to database
|
||||
do
|
||||
end
|
||||
|
||||
connect_by_connection_string (a_connect_string: STRING)
|
||||
-- Connect to database by connection string
|
||||
do
|
||||
end
|
||||
|
||||
disconnect
|
||||
-- Disconnect the current connection with an database
|
||||
do
|
||||
end
|
||||
|
||||
commit
|
||||
-- Commit the current transaction
|
||||
do
|
||||
end
|
||||
|
||||
rollback
|
||||
-- Commit the current transaction
|
||||
do
|
||||
end
|
||||
|
||||
trancount: INTEGER
|
||||
-- Return the number of transactions now active
|
||||
do
|
||||
end
|
||||
|
||||
begin
|
||||
-- Begin a data base transaction
|
||||
do
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,124 @@
|
||||
note
|
||||
description: "Abstract Database Query"
|
||||
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
|
||||
revision: "$Revision: 96542 $"
|
||||
|
||||
class
|
||||
DATABASE_QUERY
|
||||
|
||||
inherit
|
||||
REFACTORING_HELPER
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
create
|
||||
data_reader
|
||||
|
||||
feature {NONE} -- Intialization
|
||||
|
||||
data_reader (a_query: STRING; a_parameters: like parameters)
|
||||
-- SQL data reader for the query `a_query' with arguments `a_parameters'
|
||||
do
|
||||
log.write_information (generator + ".data_reader" + " execute query: " + a_query)
|
||||
log.write_debug (generator + ".data_reader" + " arguments:" + log_parameters (a_parameters))
|
||||
query := a_query
|
||||
parameters := a_parameters
|
||||
ensure
|
||||
query_set: query = a_query
|
||||
parameters_set: parameters = a_parameters
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_reader (a_base_selection: DB_SELECTION): detachable LIST [DB_RESULT]
|
||||
-- Execute the Current sql query.
|
||||
do
|
||||
to_implement ("Check test dynamic sequel. to redesign.")
|
||||
create {ARRAYED_LIST [DB_RESULT]} Result.make (100)
|
||||
a_base_selection.set_container (Result)
|
||||
set_map_name (a_base_selection)
|
||||
a_base_selection.set_query (query)
|
||||
a_base_selection.execute_query
|
||||
if a_base_selection.is_ok then
|
||||
a_base_selection.load_result
|
||||
Result := a_base_selection.container
|
||||
else
|
||||
log.write_error (generator + "." + a_base_selection.error_message_32)
|
||||
end
|
||||
unset_map_name (a_base_selection)
|
||||
a_base_selection.terminate
|
||||
end
|
||||
|
||||
execute_change (a_base_change: DB_CHANGE)
|
||||
-- Execute the Current sql query to change/update data in the database.
|
||||
do
|
||||
to_implement ("Check test dynamic sequel. to redesign.")
|
||||
set_map_name (a_base_change)
|
||||
a_base_change.set_query (query)
|
||||
a_base_change.execute_query
|
||||
unset_map_name (a_base_change)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
query: STRING
|
||||
-- SQL query to execute.
|
||||
|
||||
parameters: detachable STRING_TABLE [detachable ANY]
|
||||
-- query parameters.
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
set_map_name (a_base_selection: DB_EXPRESSION)
|
||||
-- Store parameters `item' and their `key'.
|
||||
do
|
||||
if attached parameters as l_parameters then
|
||||
across
|
||||
l_parameters as ic
|
||||
loop
|
||||
a_base_selection.set_map_name (ic.item, ic.key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unset_map_name (a_base_selection: DB_EXPRESSION)
|
||||
-- Remove parameters item associated with key `key'.
|
||||
do
|
||||
if attached parameters as l_parameters then
|
||||
across
|
||||
l_parameters as ic
|
||||
loop
|
||||
a_base_selection.unset_map_name (ic.key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
log_parameters (a_parameters: like parameters): STRING
|
||||
-- Parameters to log with name and value
|
||||
-- exclude sensitive information.
|
||||
do
|
||||
create Result.make_empty
|
||||
if a_parameters /= Void then
|
||||
across
|
||||
a_parameters as ic
|
||||
loop
|
||||
Result.append ("name:")
|
||||
Result.append (ic.key.as_string_32)
|
||||
Result.append (", value:")
|
||||
if
|
||||
ic.key.has_substring ("Password") or else
|
||||
ic.key.has_substring ("password")
|
||||
then
|
||||
-- Data to exclude
|
||||
else
|
||||
if attached ic.item as l_item then
|
||||
Result.append (l_item.out)
|
||||
end
|
||||
end
|
||||
Result.append ("%N")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end -- DATABASE_QUERY
|
||||
@@ -0,0 +1,34 @@
|
||||
note
|
||||
description: "Help to encode sql queries, to prevent sql injections."
|
||||
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
|
||||
revision: "$Revision: 96542 $"
|
||||
EIS: "SQL server injection", "src=http://blogs.msdn.com/b/raulga/archive/2007/01/04/dynamic-sql-sql-injection.aspx", "protocol=url"
|
||||
|
||||
expanded class
|
||||
DATABASE_SQL_SERVER_ENCODER
|
||||
|
||||
inherit
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
feature -- Escape SQL input
|
||||
|
||||
encode (a_string: READABLE_STRING_32): READABLE_STRING_32
|
||||
-- Escape single quote (') and braces ([,]).
|
||||
local
|
||||
l_string: STRING
|
||||
do
|
||||
l_string := a_string.twin
|
||||
if not l_string.is_empty then
|
||||
l_string.replace_substring_all ("[", "[[")
|
||||
l_string.replace_substring_all ("]", "]]")
|
||||
if l_string.index_of ('%'', 1) > 0 then
|
||||
l_string.replace_substring ("[", 1, l_string.index_of ('%'', 1))
|
||||
end
|
||||
if l_string.last_index_of ('%'', l_string.count) > 0 then
|
||||
l_string.replace_substring ("]", l_string.last_index_of ('%'', l_string.count), l_string.count)
|
||||
end
|
||||
end
|
||||
Result := l_string
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,193 @@
|
||||
note
|
||||
description: "Database Store Procedure"
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
class
|
||||
DATABASE_STORE_PROCEDURE
|
||||
|
||||
inherit
|
||||
|
||||
SHARED_ERROR
|
||||
|
||||
create
|
||||
data_reader, data_writer
|
||||
|
||||
feature -- Intialization
|
||||
|
||||
data_reader (a_sp: STRING; a_parameters: HASH_TABLE [ANY, STRING_32])
|
||||
-- SQL data reader for the stored procedure `a_sp' with arguments `a_parameters'.
|
||||
local
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
log.write_information (generator + ".data_reader" + " execute store procedure: " + a_sp)
|
||||
log.write_debug (generator + ".data_reader" + " arguments:" + log_parameters (a_parameters))
|
||||
if not l_retried then
|
||||
stored_procedure := a_sp
|
||||
parameters := a_parameters
|
||||
create proc.make (stored_procedure)
|
||||
proc.load
|
||||
if not a_parameters.is_empty then
|
||||
proc.set_arguments_32 (a_parameters.current_keys, a_parameters.linear_representation.to_array)
|
||||
end
|
||||
if proc.exists then
|
||||
if proc.text_32 /= Void then
|
||||
debug
|
||||
log.write_debug ( generator + ".data_reader: " + proc.text_32)
|
||||
end
|
||||
end
|
||||
else
|
||||
has_error := True
|
||||
error_message := proc.error_message_32
|
||||
error_code := proc.error_code
|
||||
log.write_error (generator + ".data_witer message:" + proc.error_message_32 + " code:" + proc.error_code.out)
|
||||
end
|
||||
else
|
||||
stored_procedure := a_sp
|
||||
parameters := a_parameters
|
||||
create proc.make (stored_procedure)
|
||||
end
|
||||
rescue
|
||||
set_last_error_from_exception ("SQL execution")
|
||||
log.write_critical (generator+ ".data_reader " + last_error_message)
|
||||
l_retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
data_writer (a_sp: STRING; a_parameters: HASH_TABLE [ANY, STRING_32])
|
||||
-- SQL data reader for the stored procedure `a_sp' with arguments `a_parameters'
|
||||
local
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
log.write_information (generator + ".data_reader" + " execute store procedure: " + a_sp)
|
||||
log.write_debug (generator + ".data_reader" + " arguments:" + log_parameters (a_parameters))
|
||||
if not l_retried then
|
||||
stored_procedure := a_sp
|
||||
parameters := a_parameters
|
||||
create proc.make (stored_procedure)
|
||||
proc.load
|
||||
proc.set_arguments_32 (a_parameters.current_keys, a_parameters.linear_representation.to_array)
|
||||
if proc.exists then
|
||||
if proc.text_32 /= Void then
|
||||
debug
|
||||
log.write_debug ( generator + ".data_writer: " + proc.text_32)
|
||||
end
|
||||
end
|
||||
else
|
||||
has_error := True
|
||||
error_message := proc.error_message_32
|
||||
error_code := proc.error_code
|
||||
log.write_error (generator + ".data_witer message:" + proc.error_message_32 + " code:" + proc.error_code.out)
|
||||
end
|
||||
else
|
||||
stored_procedure := a_sp
|
||||
parameters := a_parameters
|
||||
create proc.make (stored_procedure)
|
||||
end
|
||||
rescue
|
||||
set_last_error_from_exception ("SQL execution")
|
||||
log.write_critical (generator+ ".data_reader " + last_error_message)
|
||||
l_retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
|
||||
execute_reader (a_base_selection: DB_SELECTION): detachable LIST [DB_RESULT]
|
||||
-- Execute the Current store procedure.
|
||||
do
|
||||
create {ARRAYED_LIST [DB_RESULT]} Result.make (100)
|
||||
a_base_selection.set_container (Result)
|
||||
set_map_name (a_base_selection)
|
||||
proc.execute (a_base_selection)
|
||||
a_base_selection.load_result
|
||||
Result := a_base_selection.container
|
||||
unset_map_name (a_base_selection)
|
||||
end
|
||||
|
||||
execute_writer (a_base_change: DB_CHANGE)
|
||||
-- Execute the Current store procedure.
|
||||
do
|
||||
set_map_name (a_base_change)
|
||||
proc.execute (a_base_change)
|
||||
unset_map_name (a_base_change)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
proc: DB_PROC
|
||||
-- object to create and execute stored procedure.
|
||||
|
||||
parameters: HASH_TABLE [detachable ANY, STRING_32]
|
||||
-- Parameters to be used by the stored procedure.
|
||||
|
||||
stored_procedure: STRING
|
||||
-- Store procedure to execute
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
has_error: BOOLEAN
|
||||
-- Is there an error.
|
||||
|
||||
error_message: detachable STRING_32
|
||||
-- Last error message.
|
||||
|
||||
error_code: INTEGER
|
||||
-- Last error code.
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
set_map_name (a_base_selection: DB_EXPRESSION)
|
||||
-- Store parameters `item' and their `key'.
|
||||
do
|
||||
from
|
||||
parameters.start
|
||||
until
|
||||
parameters.after
|
||||
loop
|
||||
a_base_selection.set_map_name (parameters.item_for_iteration, parameters.key_for_iteration)
|
||||
parameters.forth
|
||||
end
|
||||
end
|
||||
|
||||
unset_map_name (a_base_selection: DB_EXPRESSION)
|
||||
-- Remove parameters item associated with key `key'.
|
||||
do
|
||||
from
|
||||
parameters.start
|
||||
until
|
||||
parameters.after
|
||||
loop
|
||||
a_base_selection.unset_map_name (parameters.key_for_iteration)
|
||||
parameters.forth
|
||||
end
|
||||
end
|
||||
|
||||
log_parameters (a_parameters: like parameters): STRING
|
||||
-- Parameters to log with name and value
|
||||
-- exclude sensitive information.
|
||||
do
|
||||
create Result.make_empty
|
||||
from
|
||||
a_parameters.start
|
||||
until
|
||||
a_parameters.after
|
||||
loop
|
||||
Result.append ("name:")
|
||||
Result.append (a_parameters.key_for_iteration)
|
||||
Result.append (", value:")
|
||||
if
|
||||
a_parameters.key_for_iteration.has_substring ("Password") or else
|
||||
a_parameters.key_for_iteration.has_substring ("password")
|
||||
then
|
||||
-- Data to exclude
|
||||
else
|
||||
if attached a_parameters.item_for_iteration as l_item then
|
||||
Result.append (l_item.out)
|
||||
end
|
||||
end
|
||||
Result.append ("%N")
|
||||
a_parameters.forth
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
note
|
||||
description: "Error from database"
|
||||
date: "$Date: 2014-11-13 16:23:47 +0100 (jeu., 13 nov. 2014) $"
|
||||
revision: "$Revision: 96085 $"
|
||||
|
||||
class
|
||||
DATABASE_ERROR
|
||||
|
||||
inherit
|
||||
ERROR_CUSTOM
|
||||
|
||||
create
|
||||
make_from_message
|
||||
|
||||
feature {NONE} -- Init
|
||||
|
||||
make_from_message (a_m: like message; a_code: like code)
|
||||
-- Create from `a_m'
|
||||
do
|
||||
make (a_code, once "Database Error", a_m)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
note
|
||||
description: "Database error handler"
|
||||
date: "$Date: 2014-11-13 16:23:47 +0100 (jeu., 13 nov. 2014) $"
|
||||
revision: "$Revision: 96085 $"
|
||||
|
||||
class
|
||||
DATABASE_ERROR_HANDLER
|
||||
|
||||
inherit
|
||||
ERROR_HANDLER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Error operation
|
||||
|
||||
add_database_error (a_message: READABLE_STRING_32; a_code: INTEGER)
|
||||
-- Add a database error.
|
||||
local
|
||||
l_error: DATABASE_ERROR
|
||||
do
|
||||
create l_error.make_from_message (a_message, a_code)
|
||||
add_error (l_error)
|
||||
end
|
||||
|
||||
add_database_no_change_error (a_message: READABLE_STRING_32; a_code: INTEGER)
|
||||
-- Add a database error.
|
||||
local
|
||||
l_error: DATABASE_NO_CHANGE_ERROR
|
||||
do
|
||||
create l_error.make_from_message (a_message, a_code)
|
||||
add_error (l_error)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
note
|
||||
description: "Summary description for {DATABASE_NO_CHANGE_ERROR}."
|
||||
author: ""
|
||||
date: "$Date: 2014-11-13 16:23:47 +0100 (jeu., 13 nov. 2014) $"
|
||||
revision: "$Revision: 96085 $"
|
||||
|
||||
class
|
||||
DATABASE_NO_CHANGE_ERROR
|
||||
|
||||
inherit
|
||||
DATABASE_ERROR
|
||||
redefine
|
||||
make_from_message
|
||||
end
|
||||
|
||||
create
|
||||
make_from_message
|
||||
|
||||
feature {NONE} -- Init
|
||||
|
||||
make_from_message (a_m: like message; a_code: like code)
|
||||
-- Create from `a_m'
|
||||
do
|
||||
make (a_code, once "Database No Change Error", a_m)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
note
|
||||
description: "Helper for paramenter Names"
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
deferred class
|
||||
PARAMETER_NAME_HELPER
|
||||
|
||||
feature -- String
|
||||
|
||||
string_parameter (a_value: STRING; a_length: INTEGER): STRING
|
||||
-- Adjust a parameter `a_value' to the lenght `a_length'.
|
||||
require
|
||||
valid_length: a_length > 0
|
||||
do
|
||||
if a_value.count <= a_length then
|
||||
Result := a_value
|
||||
else
|
||||
create Result.make_from_string (a_value.substring (1, a_length))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user