Added a common database backend implementation.
Added sqlite (proof of concept)
This commit is contained in:
29
persistence/implementation/common/database/database_config.e
Normal file
29
persistence/implementation/common/database/database_config.e
Normal file
@@ -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
|
||||
110
persistence/implementation/common/database/database_connection.e
Normal file
110
persistence/implementation/common/database/database_connection.e
Normal file
@@ -0,0 +1,110 @@
|
||||
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
|
||||
|
||||
SHARED_ERROR
|
||||
|
||||
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 -- 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
|
||||
|
||||
end
|
||||
@@ -0,0 +1,67 @@
|
||||
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 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,126 @@
|
||||
note
|
||||
description: "Object that handle a database connection for ODBC"
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
class
|
||||
DATABASE_CONNECTION_ODBC
|
||||
|
||||
inherit
|
||||
|
||||
DATABASE_CONNECTION
|
||||
redefine
|
||||
db_application
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
set_successful
|
||||
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)
|
||||
|
||||
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
|
||||
set_successful
|
||||
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 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)
|
||||
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
|
||||
177
persistence/implementation/common/database/database_handler.e
Normal file
177
persistence/implementation/common/database/database_handler.e
Normal file
@@ -0,0 +1,177 @@
|
||||
note
|
||||
description: "Abstract Database Handler"
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
deferred class
|
||||
DATABASE_HANDLER
|
||||
|
||||
inherit
|
||||
|
||||
SHARED_ERROR
|
||||
|
||||
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_reader
|
||||
-- Execute store.
|
||||
require
|
||||
store_not_void: store /= void
|
||||
deferred
|
||||
end
|
||||
|
||||
execute_writer
|
||||
-- Execute store.
|
||||
require
|
||||
store_not_void: store /= void
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- SQL Queries
|
||||
|
||||
execute_query
|
||||
-- Execute query.
|
||||
require
|
||||
query_not_void: query /= void
|
||||
deferred
|
||||
end
|
||||
|
||||
execute_change
|
||||
-- Execute sqlquery 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
|
||||
|
||||
has_error: BOOLEAN
|
||||
-- Is there an error?
|
||||
|
||||
count: INTEGER
|
||||
-- Number of rows, last execution.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature {NODE_DATA_PROVIDER}-- Implementation
|
||||
|
||||
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,284 @@
|
||||
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
|
||||
set_successful
|
||||
ensure
|
||||
connection_not_void: connection /= Void
|
||||
last_query_not_void: last_query /= Void
|
||||
end
|
||||
|
||||
feature -- Functionality
|
||||
|
||||
execute_reader
|
||||
-- Execute stored procedure that returns data.
|
||||
local
|
||||
l_db_selection: DB_SELECTION
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
if not l_retried then
|
||||
if not keep_connection then
|
||||
connect
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
if not keep_connection then
|
||||
disconnect
|
||||
end
|
||||
set_successful
|
||||
log.write_debug ( generator+".execute_reader Successful")
|
||||
end
|
||||
rescue
|
||||
set_last_error_from_exception ("Store procedure execution")
|
||||
log.write_critical (generator+ ".execute_reader " + last_error_message)
|
||||
if is_connected then
|
||||
disconnect
|
||||
end
|
||||
l_retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
execute_writer
|
||||
-- Execute stored procedure that update/add data.
|
||||
local
|
||||
l_db_change: DB_CHANGE
|
||||
l_retried : BOOLEAN
|
||||
do
|
||||
if not l_retried then
|
||||
if not keep_connection and not is_connected then
|
||||
connect
|
||||
end
|
||||
|
||||
if attached store as l_store then
|
||||
create l_db_change.make
|
||||
db_update := l_db_change
|
||||
l_store.execute_writer (l_db_change)
|
||||
if not l_store.has_error then
|
||||
db_control.commit
|
||||
end
|
||||
end
|
||||
if not keep_connection then
|
||||
disconnect
|
||||
end
|
||||
set_successful
|
||||
log.write_debug ( generator+".execute_writer Successful")
|
||||
end
|
||||
rescue
|
||||
set_last_error_from_exception ("Store procedure execution")
|
||||
log.write_critical (generator+ ".execute_writer " + last_error_message)
|
||||
if is_connected then
|
||||
disconnect
|
||||
end
|
||||
l_retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
feature -- SQL Queries
|
||||
|
||||
execute_query
|
||||
-- Execute query.
|
||||
local
|
||||
l_db_selection: DB_SELECTION
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
if not l_retried then
|
||||
if not keep_connection then
|
||||
connect
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
if not keep_connection then
|
||||
disconnect
|
||||
end
|
||||
set_successful
|
||||
end
|
||||
rescue
|
||||
set_last_error_from_exception ("execute_query")
|
||||
log.write_critical (generator+ ".execute_query " + last_error_message)
|
||||
if is_connected then
|
||||
disconnect
|
||||
end
|
||||
l_retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
|
||||
execute_change
|
||||
-- Execute sqlquery that update/add data.
|
||||
local
|
||||
l_db_change: DB_CHANGE
|
||||
l_retried : BOOLEAN
|
||||
do
|
||||
if not l_retried then
|
||||
if not keep_connection and not is_connected then
|
||||
connect
|
||||
end
|
||||
|
||||
if attached query as l_query then
|
||||
create l_db_change.make
|
||||
db_update := l_db_change
|
||||
l_query.execute_change (l_db_change)
|
||||
db_control.commit
|
||||
end
|
||||
if not keep_connection then
|
||||
disconnect
|
||||
end
|
||||
set_successful
|
||||
end
|
||||
rescue
|
||||
set_last_error_from_exception ("Store procedure execution")
|
||||
log.write_critical (generator+ ".execute_writer " + last_error_message)
|
||||
if is_connected then
|
||||
disconnect
|
||||
end
|
||||
l_retried := True
|
||||
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
|
||||
|
||||
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_update: detachable DB_CHANGE
|
||||
-- Database modification.
|
||||
|
||||
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_update 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 {ESA_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
|
||||
538
persistence/implementation/common/database/database_null.e
Normal file
538
persistence/implementation/common/database/database_null.e
Normal file
@@ -0,0 +1,538 @@
|
||||
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
|
||||
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
|
||||
137
persistence/implementation/common/database/database_query.e
Normal file
137
persistence/implementation/common/database/database_query.e
Normal file
@@ -0,0 +1,137 @@
|
||||
note
|
||||
description: "Abstract Database Query"
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
|
||||
class
|
||||
DATABASE_QUERY
|
||||
|
||||
inherit
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
data_reader
|
||||
|
||||
feature -- Intialization
|
||||
|
||||
data_reader (a_query: STRING; a_parameters: STRING_TABLE [detachable ANY])
|
||||
-- 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
|
||||
|
||||
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 .
|
||||
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: STRING_TABLE [detachable ANY]
|
||||
-- query parameters.
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
has_error: BOOLEAN
|
||||
-- is there an error?
|
||||
|
||||
error_message: detachable STRING_32
|
||||
-- Error message if any.
|
||||
|
||||
error_code: INTEGER
|
||||
-- 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.as_string_32)
|
||||
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 -- ESA_DATABASE_QUERY
|
||||
@@ -0,0 +1,33 @@
|
||||
note
|
||||
description: "Help to encode sql queries, to prevent sql injections."
|
||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||
revision: "$Revision: 95678 $"
|
||||
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: "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