Added a common database backend implementation.

Added sqlite (proof of concept)
This commit is contained in:
jvelilla
2014-09-17 10:33:37 -03:00
parent fbb5c57b8f
commit 4227b82c7e
37 changed files with 1889 additions and 153 deletions

View File

@@ -13,6 +13,7 @@
<library name="layout" location="..\..\..\layout\layout.ecf"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/>
<library name="mysql" location="$ISE_LIBRARY\library\store\dbms\rdbms\mysql\mysql-safe.ecf"/>
<library name="odbc" location="$ISE_LIBRARY\library\store\dbms\rdbms\odbc\odbc-safe.ecf"/>
<library name="store" location="$ISE_LIBRARY\library\store\store-safe.ecf" readonly="false"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
@@ -24,5 +25,6 @@
</file_rule>
</cluster>
<cluster name="interface" location="..\..\interface\" recursive="true"/>
<cluster name="common" location="..\common\" recursive="true"/>
</target>
</system>

View File

@@ -1,132 +0,0 @@
note
description: "Stored procedures paramters names"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
DATA_PARAMETERS_NAMES
feature -- Access
Contactid_param: STRING = "ContactID"
Username_param: STRING = "Username"
Submitter_username_param: STRING = "SubmitterUsername"
Responsibleid_param: STRING = "ResponsibleID"
Email_param: STRING = "Email"
Synopsis_param: STRING = "Synopsis"
Openonly_param: STRING = "OpenOnly"
Number_param: STRING = "Number"
Categoryid_param: STRING = "CategoryID"
Category_synopsis_param: STRING = "CategorySynopsis"
Statusid_param: STRING = "StatusID"
Private_param: STRING = "Private"
Priorityid_param: STRING = "PriorityID"
Severityid_param: STRING = "SeverityID"
Searchtext_param: STRING = "SearchText"
Searchsynopsis_param: STRING = "SearchSynopsis"
Searchdescription_param: STRING = "SearchDescription"
Reportid_param: STRING = "ReportID"
Interactionid_param: STRING = "InteractionID"
Attachmentid_param: STRING = "AttachmentID"
Fieldtitle_param: STRING = "FieldTitle"
Passwordhash_param: STRING = "PasswordHash"
Registrationtoken_param: STRING = "RegistrationToken"
Answerhash_param: STRING = "AnswerHash"
Classid_param: STRING = "Classid"
Confidential_param: STRING = "Confidential"
Release_param: STRING = "Release"
Environment_param: STRING = "Environment"
Description_param: STRING = "Description"
Toreproduce_param: STRING = "ToReproduce"
Content_param: STRING = "Content"
Alreadyexists_param: STRING = "AlreadyExists"
Firstname_param: STRING = "FirstName"
Lastname_param: STRING = "LastName"
Responsible_param: STRING = "Responsible"
Responsible_firstname_param: STRING = "ResponsibleFirstName"
Responsible_lastname_param: STRING = "ResponsibleLastName"
Length_param: STRING = "Length"
Filename_param: STRING = "Filename"
Position_param: STRING = "Position"
Address_param: STRING = "Address"
City_param: STRING = "City"
Country_param: STRING = "Country"
Region_param: STRING = "Region"
Code_param: STRING = "Code"
Tel_param: STRING = "Tel"
Fax_param: STRING = "Fax"
Name_param: STRING = "Name"
Url_param: STRING = "URL"
Token_param: STRING = "Token"
Filter_param: STRING = "Filter"
feature -- Login
Passwordsalt_param: STRING = "PasswordSalt"
Answersalt_param: STRING = "AnswerSalt"
Questionid_param: STRING = "QuestionID"
feature -- Download Parameter Names
Subject_param: STRING = "Subject"
Notes_param: STRING = "Notes"
Platform_param: STRING = "Platform"
Newsletter_param: STRING = "Newsletter"
end

View File

@@ -1,29 +0,0 @@
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

View File

@@ -1,103 +0,0 @@
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 -- 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

View File

@@ -101,21 +101,29 @@ feature -- Initialization
login_with_connection_string (a_string: STRING)
-- Login with `a_connection_string'and immediately connect to database.
local
l_string: LIST[STRING]
l_server: STRING
l_port: STRING
l_schema: STRING
l_user: STRING
l_password: STRING
do
log.write_debug (generator +".login_with_connection_string")
create db_application.login_with_connection_string (a_string)
l_string := a_string.split (';')
l_server := l_string.at (2).split ('=').at (2)
l_port := l_string.at (3).split ('=').at (2)
l_schema := l_string.at (4).split ('=').at (2)
l_user := l_string.at (5).split ('=').at (2)
l_password := l_string.at (6).split ('=').at (2)
create db_application
db_application.set_application (l_schema)
db_application.set_hostname (l_server + ":" + l_port)
db_application.login_and_connect (l_user, l_password)
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
login_with_schema (a_schema: STRING; a_username: STRING; a_password: STRING)

View File

@@ -1,67 +0,0 @@
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

View File

@@ -1,177 +0,0 @@
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

View File

@@ -1,284 +0,0 @@
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

View File

@@ -1,91 +0,0 @@
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

View File

@@ -1,538 +0,0 @@
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

View File

@@ -1,137 +0,0 @@
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

View File

@@ -1,33 +0,0 @@
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

View File

@@ -1,193 +0,0 @@
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

View File

@@ -1,23 +0,0 @@
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

View File

@@ -1,114 +0,0 @@
note
description: "Summary description for {NODE}."
date: "$Date$"
revision: "$Revision$"
class
CMS_NODE
create
make
feature{NONE} -- Initialization
make (a_content: READABLE_STRING_32; a_summary:READABLE_STRING_32; a_title: READABLE_STRING_32)
local
l_time: DATE_TIME
do
create l_time.make_now_utc
set_content (a_content)
set_summary (a_summary)
set_title (a_title)
set_creation_date (l_time)
set_modification_date (l_time)
set_publication_date (l_time)
ensure
content_set: content = a_content
summary_set: summary = a_summary
title_set: title = a_title
end
feature -- Access
content: READABLE_STRING_32
-- Content of the node.
summary: READABLE_STRING_32
-- A short summary of the node.
title: READABLE_STRING_32
-- Full title of the node.
modification_date: DATE_TIME
-- When the node was updated.
creation_date: DATE_TIME
-- When the node was created.
publication_date: DATE_TIME
-- When the node was published.
publication_date_output: READABLE_STRING_32
id: INTEGER_64 assign set_id
-- Unique id.
feature -- Element change
set_content (a_content: like content)
-- Assign `content' with `a_content'.
do
content := a_content
ensure
content_assigned: content = a_content
end
set_summary (a_summary: like summary)
-- Assign `summary' with `a_summary'.
do
summary := a_summary
ensure
summary_assigned: summary = a_summary
end
set_title (a_title: like title)
-- Assign `title' with `a_title'.
do
title := a_title
ensure
title_assigned: title = a_title
end
set_modification_date (a_modification_date: like modification_date)
-- Assign `modification_date' with `a_modification_date'.
do
modification_date := a_modification_date
ensure
modification_date_assigned: modification_date = a_modification_date
end
set_creation_date (a_creation_date: like creation_date)
-- Assign `creation_date' with `a_creation_date'.
do
creation_date := a_creation_date
ensure
creation_date_assigned: creation_date = a_creation_date
end
set_publication_date (a_publication_date: like publication_date)
-- Assign `publication_date' with `a_publication_date'.
do
publication_date := a_publication_date
publication_date_output := publication_date.formatted_out ("yyyy/[0]mm/[0]dd")
ensure
publication_date_assigned: publication_date = a_publication_date
end
set_id (an_id: like id)
-- Assign `id' with `an_id'.
do
id := an_id
ensure
id_assigned: id = an_id
end
end

View File

@@ -1,68 +0,0 @@
note
description: "Summary description for {USER}."
date: "$Date$"
revision: "$Revision$"
class
CMS_USER
create
make
feature {NONE} -- Initialization
make (a_name: READABLE_STRING_32)
-- Create an object with name `a_name'.
do
name := a_name
end
feature -- Access
id: INTEGER_64
-- Unique id.
name: READABLE_STRING_32
-- User name.
password: detachable READABLE_STRING_32
-- User password.
email: detachable READABLE_STRING_32
-- User email.
feature -- Change element
set_id (a_id: like id)
-- Set `id' with `a_id'.
do
id := a_id
ensure
id_set: id = a_id
end
set_name (n: like name)
-- Set `name' with `n'.
do
name := n
ensure
name_set: name = n
end
set_password (p: like password)
-- Set `password' with `p'.
do
password := p
ensure
password_set: password = p
end
set_email (m: like email)
-- Set `email' with `m'.
do
email := m
ensure
email_set: email = m
end
end

View File

@@ -1,153 +0,0 @@
note
description: "Provides security routine helpers"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
SECURITY_PROVIDER
inherit
REFACTORING_HELPER
feature -- Access
token: STRING
-- Cryptographic random base 64 string.
do
Result := salt_with_size (5)
-- Remove trailing equal sign
Result.keep_head (Result.count - 1)
end
salt: STRING
-- Cryptographic random number of 16 bytes.
do
Result := salt_with_size (16)
end
password: STRING
-- Cryptographic random password of 10 bytes.
do
Result := salt_with_size (10)
-- Remove trailing equal signs
Result.keep_head (Result.count - 2)
end
password_hash (a_password, a_salt: STRING): STRING
-- Password hash based on password `a_password' and salt value `a_salt'.
do
Result := sha1_string (a_password + a_salt )
end
feature {NONE} -- Implementation
salt_with_size (a_val: INTEGER): STRING
-- Return a salt with size `a_val'.
local
l_salt: SALT_XOR_SHIFT_64_GENERATOR
l_array: ARRAY [INTEGER_8]
i: INTEGER
do
create l_salt.make (a_val)
create l_array.make_empty
i := 1
across
l_salt.new_sequence as c
loop
l_array.force (c.item.as_integer_8, i)
i := i + 1
end
Result := encode_base_64 (l_array)
end
sha1_string (a_str: STRING): STRING
-- SHA1 diggest of `a_str'.
do
sha1.update_from_string (a_str)
Result := sha1.digest_as_string
sha1.reset
end
sha1: SHA1
-- Create a SHA1 object.
once
create Result.make
end
feature -- Encoding
encode_base_64 (bytes: SPECIAL [INTEGER_8]): STRING_8
-- Encodes a byte array into a STRING doing base64 encoding.
local
l_output: SPECIAL [INTEGER_8]
l_remaining: INTEGER
i, ptr: INTEGER
char: CHARACTER
do
to_implement ("Check existing code to do that!!!.")
create l_output.make_filled (0, ((bytes.count + 2) // 3) * 4)
l_remaining := bytes.count
from
i := 0
ptr := 0
until
l_remaining <= 3
loop
l_output [ptr] := encode_value (bytes [i] |>> 2)
ptr := ptr + 1
l_output [ptr] := encode_value (((bytes [i] & 0x3) |<< 4) | ((bytes [i + 1] |>> 4) & 0xF))
ptr := ptr + 1
l_output [ptr] := encode_value (((bytes [i + 1] & 0xF) |<< 2) | ((bytes [i + 2] |>> 6) & 0x3))
ptr := ptr + 1
l_output [ptr] := encode_value (bytes [i + 2] & 0x3F)
ptr := ptr + 1
l_remaining := l_remaining - 3
i := i + 3
end
-- encode when exactly 1 element (left) to encode
char := '='
if l_remaining = 1 then
l_output [ptr] := encode_value (bytes [i] |>> 2)
ptr := ptr + 1
l_output [ptr] := encode_value (((bytes [i]) & 0x3) |<< 4)
ptr := ptr + 1
l_output [ptr] := char.code.as_integer_8
ptr := ptr + 1
l_output [ptr] := char.code.as_integer_8
ptr := ptr + 1
end
-- encode when exactly 2 elements (left) to encode
if l_remaining = 2 then
l_output [ptr] := encode_value (bytes [i] |>> 2)
ptr := ptr + 1
l_output [ptr] := encode_value (((bytes [i] & 0x3) |<< 4) | ((bytes [i + 1] |>> 4) & 0xF));
ptr := ptr + 1
l_output [ptr] := encode_value ((bytes [i + 1] & 0xF) |<< 2);
ptr := ptr + 1
l_output [ptr] := char.code.as_integer_8
ptr := ptr + 1
end
Result := ""
across
l_output as elem
loop
Result.append_character (elem.item.to_character_8)
end
end
base64_map: SPECIAL [CHARACTER_8]
-- Table for Base64 encoding.
once
Result := ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/").area
end
encode_value (i: INTEGER_8): INTEGER_8
-- Encode `i'.
do
Result := base64_map [i & 0x3F].code.as_integer_8
end
end

View File

@@ -1,53 +0,0 @@
note
description: "Summary description for {STRING_HELPER}."
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
STRING_HELPER
feature -- Access
is_blank (s: detachable READABLE_STRING_32): BOOLEAN
local
i,n: INTEGER
do
Result := True
if s /= Void then
from
i := 1
n := s.count
until
i > n or not Result
loop
Result := s[i].is_space
i := i + 1
end
end
end
indented_text (pre: READABLE_STRING_8; t: READABLE_STRING_8): READABLE_STRING_8
-- Indendted text.
local
s8: STRING_8
do
s8 := t.string
s8.prepend (pre)
s8.replace_substring_all ("%N", "%N" + pre)
Result := s8
end
json_encode (a_string: STRING): STRING
-- json encode `a_string'.
local
encode: SHARED_JSON_ENCODER
do
create encode
Result := encode.json_encoder.encoded_string (a_string)
debug
print ("%NResult" + Result)
end
end
end