Factorized code for Eiffel Store + SQL CMS storage.

Revisited database schema to make it simpler for now, and shorter columns name.
See schema.sql under sqlite implementation
This commit is contained in:
2015-01-21 22:15:01 +01:00
parent d23cfbc300
commit db6afb6952
16 changed files with 614 additions and 361 deletions

View File

@@ -9,13 +9,13 @@
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="concurrency" value="none"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="..\..\cms-safe.ecf" readonly="false"/>
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
<library name="layout" location="..\..\library\layout\layout-safe.ecf" readonly="false"/>
<library name="persistence_mysql" location="..\..\library\persistence\implementation\mysql\persistence_mysql-safe.ecf" readonly="false"/>
<library name="persistence_sqlite" location="..\..\library\persistence\implementation\sqlite\persistence_sqlite-safe.ecf" readonly="false"/>
<library name="layout" location="..\..\library\layout\layout-safe.ecf" readonly="false"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
</target>
@@ -29,6 +29,7 @@
</target>
<target name="demo_nino" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<setting name="concurrency" value="none"/>
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>

View File

@@ -0,0 +1,106 @@
note
description: "Summary description for {CMS_STORAGE_STORE_SQL}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_STORAGE_STORE_SQL
inherit
CMS_STORAGE
CMS_STORAGE_SQL
feature {NONE} -- Initialization
make (a_connection: DATABASE_CONNECTION)
--
require
is_connected: a_connection.is_connected
do
connection := a_connection
log.write_information (generator + ".make - is database connected? "+ a_connection.is_connected.out )
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
create error_handler.make
-- error_handler.add_synchronization (db_handler.database_error_handler)
end
feature {NONE} -- Implementation
db_handler: DATABASE_HANDLER
connection: DATABASE_CONNECTION
-- Current database connection.
feature -- Query
sql_post_execution
-- Post database execution.
do
error_handler.append (db_handler.database_error_handler)
if error_handler.has_error then
log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
end
end
sql_begin_transaction
do
connection.begin_transaction
end
sql_commit_transaction
do
connection.commit
end
sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
do
check_sql_query_validity (a_sql_statement, a_params)
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
db_handler.execute_query
end
sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
do
check_sql_query_validity (a_sql_statement, a_params)
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
db_handler.execute_change
end
sql_rows_count: INTEGER
-- Number of rows for last sql execution.
do
Result := db_handler.count
end
sql_start
-- Set the cursor on first element.
do
db_handler.start
end
sql_after: BOOLEAN
-- Are there no more items to iterate over?
do
Result := db_handler.after
end
sql_forth
-- Fetch next row from last sql execution, if any.
do
db_handler.forth
end
sql_item (a_index: INTEGER): detachable ANY
do
if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then
Result := l_item.item (a_index)
else
check has_item_at_index: False end
end
end
end

View File

@@ -7,8 +7,9 @@ class
CMS_STORAGE_MYSQL
inherit
CMS_STORAGE
CMS_STORAGE_STORE_SQL
CMS_USER_STORAGE_MYSQL
@@ -19,85 +20,93 @@ inherit
create
make
feature {NONE} -- Initialization
--feature {NONE} -- Initialization
make (a_connection: DATABASE_CONNECTION)
--
require
is_connected: a_connection.is_connected
do
connection := a_connection
log.write_information (generator + ".make - is database connected? "+ a_connection.is_connected.out )
-- make (a_connection: DATABASE_CONNECTION)
-- --
-- require
-- is_connected: a_connection.is_connected
-- do
-- connection := a_connection
-- log.write_information (generator + ".make - is database connected? "+ a_connection.is_connected.out )
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
-- create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
create error_handler.make
-- error_handler.add_synchronization (db_handler.database_error_handler)
end
-- create error_handler.make
---- error_handler.add_synchronization (db_handler.database_error_handler)
-- end
db_handler: DATABASE_HANDLER
-- db_handler: DATABASE_HANDLER
connection: DATABASE_CONNECTION
-- Current database connection.
-- connection: DATABASE_CONNECTION
-- -- Current database connection.
feature -- Query
--feature -- Query
sql_post_execution
-- Post database execution.
do
error_handler.append (db_handler.database_error_handler)
if error_handler.has_error then
log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
end
end
-- sql_post_execution
-- -- Post database execution.
-- do
-- error_handler.append (db_handler.database_error_handler)
-- if error_handler.has_error then
-- log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
-- end
-- end
sql_begin_transaction
do
connection.begin_transaction
end
-- sql_begin_transaction
-- do
-- connection.begin_transaction
-- end
sql_commit_transaction
do
connection.commit
end
-- sql_commit_transaction
-- do
-- connection.commit
-- end
sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
do
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
db_handler.execute_query
end
-- sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
-- do
-- check_sql_query_validity (a_sql_statement, a_params)
-- db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
-- db_handler.execute_query
-- end
sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
do
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
db_handler.execute_change
end
-- sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
-- do
-- check_sql_query_validity (a_sql_statement, a_params)
-- db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
-- db_handler.execute_change
-- end
sql_rows_count: INTEGER
-- Number of rows for last sql execution.
do
Result := db_handler.count
end
-- sql_rows_count: INTEGER
-- -- Number of rows for last sql execution.
-- do
-- Result := db_handler.count
-- end
sql_after: BOOLEAN
-- Are there no more items to iterate over?
do
Result := db_handler.after
end
-- sql_start
-- -- Set the cursor on first element.
-- do
-- db_handler.start
-- end
sql_forth
-- Fetch next row from last sql execution, if any.
do
db_handler.forth
end
-- sql_after: BOOLEAN
-- -- Are there no more items to iterate over?
-- do
-- Result := db_handler.after
-- end
sql_item (a_index: INTEGER): detachable ANY
do
if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then
Result := l_item.item (a_index)
else
check has_item_at_index: False end
end
end
-- sql_forth
-- -- Fetch next row from last sql execution, if any.
-- do
-- db_handler.forth
-- end
-- sql_item (a_index: INTEGER): detachable ANY
-- do
-- if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then
-- Result := l_item.item (a_index)
-- else
-- check has_item_at_index: False end
-- end
-- end
end

View File

@@ -1,61 +0,0 @@
-- Creator: MySQL Workbench 6.1.7/ExportSQLite plugin 2009.12.02
-- Author: javier
-- Caption: New Model
-- Project: Name of the project
-- Changed: 2014-09-16 23:12
-- Created: 2014-09-16 23:12
PRAGMA foreign_keys = OFF;
-- Schema: cms_dev
BEGIN;
CREATE TABLE "nodes"(
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
"publication_date" DATE NOT NULL,
"creation_date" DATE NOT NULL,
"modification_date" DATE NOT NULL,
"title" VARCHAR(255) NOT NULL,
"summary" TEXT NOT NULL,
"content" MEDIUMTEXT NOT NULL
);
CREATE TABLE "roles"(
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
"role" VARCHAR(100) NOT NULL,
CONSTRAINT "role"
UNIQUE("role")
);
CREATE TABLE "users"(
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
"username" VARCHAR(100) NOT NULL,
"password" VARCHAR(100) NOT NULL,
"salt" VARCHAR(100) NOT NULL,
"email" VARCHAR(250) NOT NULL,
CONSTRAINT "username"
UNIQUE("username")
);
CREATE TABLE "users_nodes"(
"users_id" INTEGER NOT NULL CHECK("users_id">=0),
"nodes_id" INTEGER NOT NULL CHECK("nodes_id">=0),
PRIMARY KEY("users_id","nodes_id"),
CONSTRAINT "fk_users_has_nodes_nodes1"
FOREIGN KEY("nodes_id")
REFERENCES "nodes"("id"),
CONSTRAINT "fk_users_has_nodes_users"
FOREIGN KEY("users_id")
REFERENCES "users"("id")
);
CREATE INDEX "users_nodes.fk_users_has_nodes_nodes1_idx" ON "users_nodes"("nodes_id");
CREATE INDEX "users_nodes.fk_users_has_nodes_users_idx" ON "users_nodes"("users_id");
CREATE TABLE "users_roles"(
"users_id" INTEGER NOT NULL CHECK("users_id">=0),
"roles_id" INTEGER NOT NULL CHECK("roles_id">=0),
PRIMARY KEY("users_id","roles_id"),
CONSTRAINT "fk_users_has_roles_roles1"
FOREIGN KEY("roles_id")
REFERENCES "roles"("id"),
CONSTRAINT "fk_users_has_roles_users1"
FOREIGN KEY("users_id")
REFERENCES "users"("id")
);
CREATE INDEX "users_roles.fk_users_has_roles_roles1_idx" ON "users_roles"("roles_id");
CREATE INDEX "users_roles.fk_users_has_roles_users1_idx" ON "users_roles"("users_id");
COMMIT;

View File

@@ -0,0 +1,36 @@
PRAGMA foreign_keys = OFF;
BEGIN;
CREATE TABLE "users"(
"uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0),
"name" VARCHAR(100) NOT NULL,
"password" VARCHAR(100) NOT NULL,
"salt" VARCHAR(100) NOT NULL,
"email" VARCHAR(250) NOT NULL,
"status" INTEGER,
"created" DATETIME NOT NULL,
"signed" DATETIME,
CONSTRAINT "name"
UNIQUE("name")
);
CREATE TABLE "users_roles"(
"rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
"role" VARCHAR(100) NOT NULL,
CONSTRAINT "role"
UNIQUE("role")
);
CREATE TABLE "nodes"(
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
"version" INTEGER,
"type" INTEGER,
"title" VARCHAR(255) NOT NULL,
"summary" TEXT NOT NULL,
"content" MEDIUMTEXT NOT NULL,
"author" INTEGER,
"publish" DATETIME,
"created" DATETIME NOT NULL,
"changed" DATETIME NOT NULL
);
COMMIT;

View File

@@ -1,14 +0,0 @@
DROP TABLE IF EXISTS nodes;
CREATE TABLE nodes
(
id smallint unsigned NOT NULL auto_increment,
publication_date date NOT NULL, #When the article was published
creation_date date NOT NULL, #When the article was created
modification_date date NOT NULL, #When the article was updated
title varchar(255) NOT NULL, #Full title of the article
summary text NOT NULL, #A short summary of the articule
content mediumtext NOT NULL, #The HTML content of the article
PRIMARY KEY (ID)
);

View File

@@ -9,6 +9,67 @@ deferred class
inherit
CMS_NODE_STORAGE_SQL
redefine
nodes, recent_nodes
end
feature {NONE} -- Implementation
db_handler: DATABASE_HANDLER
deferred
end
feature -- Access
nodes: LIST [CMS_NODE]
-- List of nodes.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
across nodes_iterator as ic loop
Result.force (ic.item)
end
end
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- List of recent `a_count' nodes with an offset of `lower'.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_count)
across recent_nodes_iterator (a_lower, a_count) as c loop
Result.force (c.item)
end
end
feature -- Access: iterator
nodes_iterator: DATABASE_ITERATION_CURSOR [CMS_NODE]
-- List of nodes.
local
l_parameters: STRING_TABLE [ANY]
do
error_handler.reset
log.write_information (generator + ".nodes_iterator")
create l_parameters.make (0)
sql_query (select_nodes, l_parameters)
sql_post_execution
create Result.make (db_handler, agent fetch_node)
end
recent_nodes_iterator (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [CMS_NODE]
-- The most recent `a_rows'.
local
l_parameters: STRING_TABLE [ANY]
l_query: STRING
do
-- FIXME: check implementation...
error_handler.reset
log.write_information (generator + ".recent_nodes_iterator")
create l_parameters.make (2)
l_parameters.put (a_rows, "rows")
l_parameters.put (a_lower, "offset")
create l_query.make_from_string (select_recent_nodes)
sql_query (l_query, l_parameters)
create Result.make (db_handler, agent fetch_node)
sql_post_execution
end
end

View File

@@ -8,6 +8,8 @@ class
inherit
CMS_STORAGE
CMS_STORAGE_STORE_SQL
CMS_USER_STORAGE_SQLITE
@@ -18,85 +20,93 @@ inherit
create
make
feature {NONE} -- Initialization
--feature {NONE} -- Initialization
make (a_connection: DATABASE_CONNECTION)
--
require
is_connected: a_connection.is_connected
do
connection := a_connection
log.write_information (generator + ".make_with_database is database connected? "+ a_connection.is_connected.out )
-- make (a_connection: DATABASE_CONNECTION)
-- --
-- require
-- is_connected: a_connection.is_connected
-- do
-- connection := a_connection
-- log.write_information (generator + ".make_with_database is database connected? "+ a_connection.is_connected.out )
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
-- create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
create error_handler.make
-- error_handler.add_synchronization (db_handler.database_error_handler)
end
-- create error_handler.make
---- error_handler.add_synchronization (db_handler.database_error_handler)
-- end
db_handler: DATABASE_HANDLER
-- db_handler: DATABASE_HANDLER
connection: DATABASE_CONNECTION
-- Current database connection.
-- connection: DATABASE_CONNECTION
-- -- Current database connection.
feature -- Access: user
--feature -- Access: user
sql_post_execution
-- Post database execution.
do
error_handler.append (db_handler.database_error_handler)
if error_handler.has_error then
log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
end
end
-- sql_post_execution
-- -- Post database execution.
-- do
-- error_handler.append (db_handler.database_error_handler)
-- if error_handler.has_error then
-- log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
-- end
-- end
sql_begin_transaction
do
connection.begin_transaction
end
-- sql_begin_transaction
-- do
-- connection.begin_transaction
-- end
sql_commit_transaction
do
connection.commit
end
-- sql_commit_transaction
-- do
-- connection.commit
-- end
sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
do
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
db_handler.execute_query
end
-- sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
-- do
-- check_sql_query_validity (a_sql_statement, a_params)
-- db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
-- db_handler.execute_query
-- end
sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
do
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
db_handler.execute_change
end
-- sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
-- do
-- check_sql_query_validity (a_sql_statement, a_params)
-- db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
-- db_handler.execute_change
-- end
sql_rows_count: INTEGER
-- Number of rows for last sql execution.
do
Result := db_handler.count
end
-- sql_rows_count: INTEGER
-- -- Number of rows for last sql execution.
-- do
-- Result := db_handler.count
-- end
sql_after: BOOLEAN
-- Are there no more items to iterate over?
do
Result := db_handler.after
end
-- sql_start
-- -- Set the cursor on first element.
-- do
-- db_handler.start
-- end
sql_forth
-- Fetch next row from last sql execution, if any.
do
db_handler.forth
end
-- sql_after: BOOLEAN
-- -- Are there no more items to iterate over?
-- do
-- Result := db_handler.after
-- end
sql_item (a_index: INTEGER): detachable ANY
do
if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then
Result := l_item.item (a_index)
else
check has_item_at_index: False end
end
end
-- sql_forth
-- -- Fetch next row from last sql execution, if any.
-- do
-- db_handler.forth
-- end
-- sql_item (a_index: INTEGER): detachable ANY
-- do
-- if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then
-- Result := l_item.item (a_index)
-- else
-- check has_item_at_index: False end
-- end
-- end
end

View File

@@ -162,21 +162,23 @@ feature -- Handler
l_user: CMS_USER
l_node: CMS_NODE
do
create {NOT_IMPLEMENTED_ERROR_CMS_RESPONSE} r.make (req, res, a_api)
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_api)
if attached a_api.user_by_name ("foo") as u then
l_user := u
else
create l_user.make ("foo")
l_user.set_password ("foobar#")
l_user.set_email ("jfiat@eiffel.com")
l_user.set_email ("test@example.com")
a_api.new_user (l_user)
end
create l_node.make ({STRING_32} "This is a content", {STRING_32} "And a summary", {STRING_32} "Nice title")
l_node.set_author (l_user)
a_api.new_node (l_node)
if a_api.nodes_count = 0 then
create l_node.make ({STRING_32} "This is a content", {STRING_32} "And a summary", {STRING_32} "Nice title")
l_node.set_author (l_user)
a_api.new_node (l_node)
end
create s.make_from_string ("<p>Sorry: listing the CMS nodes is not yet implemented.</p>")
create s.make_from_string ("<p>Nodes:</p>")
if attached a_api.nodes as lst then
across
lst as ic
@@ -191,7 +193,7 @@ feature -- Handler
end
r.set_main_content (s)
r.add_block (create {CMS_CONTENT_BLOCK}.make ("nodes_warning", Void, "/nodes/ is not yet implemented<br/>", Void), "highlighted")
r.add_block (create {CMS_CONTENT_BLOCK}.make ("nodes_warning", Void, "/nodes/ is not yet fully implemented<br/>", Void), "highlighted")
r.execute
end

View File

@@ -7,13 +7,13 @@ class
CMS_STORAGE_NULL
inherit
CMS_STORAGE
redefine
default_create
select
default_create
end
REFACTORING_HELPER
rename
default_create as default_create_rh
@@ -70,11 +70,16 @@ feature -- User Nodes
feature -- Change: user
save_user (a_user: CMS_USER)
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
do
end
update_user (a_user: CMS_USER)
-- Update user `a_user'.
do
end
feature -- Access: roles and permissions
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
@@ -93,9 +98,13 @@ feature -- Change: roles and permissions
do
end
feature -- Access: node
nodes_count: INTEGER_64
-- Count of nodes.
do
end
nodes: LIST[CMS_NODE]
-- List of nodes.
do
@@ -156,11 +165,4 @@ feature -- Node
do
end
feature -- User
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
do
end
end

View File

@@ -30,6 +30,58 @@ feature -- Execution
feature -- Operation
check_sql_query_validity (a_sql_statement: READABLE_STRING_8; a_params: detachable STRING_TABLE [detachable ANY])
local
l_sql_params: STRING_TABLE [READABLE_STRING_8]
i,j,n,m: INTEGER
s: STRING
do
create l_sql_params.make_caseless (0)
from
i := 1
n := a_sql_statement.count
until
i > n
loop
i := a_sql_statement.index_of (':', i)
if i = 0 then
i := n -- exit
else
from
j := i + 1
until
j > n or not (a_sql_statement[j].is_alpha_numeric or a_sql_statement[j] = '_')
loop
j := j + 1
end
s := a_sql_statement.substring (i + 1, j - 1)
l_sql_params.force (s, s)
end
i := i + 1
end
if a_params = Void then
if not l_sql_params.is_empty then
check False end
error_handler.add_custom_error (-1, "invalid query", "missing value for sql parameters")
end
else
across
a_params as ic
loop
if l_sql_params.has (ic.key) then
l_sql_params.remove (ic.key)
else
error_handler.add_custom_error (-1, "useless value", "value for unexpected parameter [" + ic.key + "]")
end
end
across
l_sql_params as ic
loop
error_handler.add_custom_error (-1, "invalid query", "missing value for sql parameter [" + ic.item + "]")
end
end
end
sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
deferred
end
@@ -45,6 +97,11 @@ feature -- Access
deferred
end
sql_start
-- Set the cursor on first element.
deferred
end
sql_after: BOOLEAN
-- Are there no more items to iterate over?
deferred

View File

@@ -19,6 +19,11 @@ feature -- Error Handling
feature -- Access
nodes_count: INTEGER_64
-- Count of nodes.
deferred
end
nodes: LIST [CMS_NODE]
-- List of nodes.
deferred
@@ -49,7 +54,7 @@ feature -- Change: Node
-- Save node `a_node'.
require
no_id: not a_node.has_id
valid_user: attached a_node.author as l_author implies l_author.id > 0
valid_user: attached a_node.author as l_author and then l_author.id > 0
deferred
end

View File

@@ -16,7 +16,19 @@ inherit
SHARED_LOGGER
feature -- Access
feature -- Access
nodes_count: INTEGER_64
-- Number of items nodes.
do
error_handler.reset
log.write_information (generator + ".nodes_count")
sql_query (select_nodes_count, Void)
if sql_rows_count = 1 then
Result := sql_read_integer_64 (1)
end
sql_post_execution
end
nodes: LIST [CMS_NODE]
-- List of nodes.
@@ -29,6 +41,7 @@ feature -- Access
from
sql_query (select_nodes, Void)
sql_post_execution
sql_start
until
sql_after
loop
@@ -56,6 +69,7 @@ feature -- Access
l_parameters.put (a_lower, "offset")
sql_query (select_recent_nodes, l_parameters)
sql_post_execution
sql_start
until
sql_after
loop
@@ -99,18 +113,6 @@ feature -- Access
sql_post_execution
end
nodes_count: INTEGER
-- Number of items nodes.
do
error_handler.reset
log.write_information (generator + ".nodes_count")
sql_query (select_nodes_count, Void)
if sql_rows_count = 1 then
Result := sql_read_integer_32 (1)
end
sql_post_execution
end
last_inserted_node_id: INTEGER_64
-- Last insert node id.
do
@@ -137,16 +139,16 @@ feature -- Change: Node
l_parameters.put (a_node.title, "title")
l_parameters.put (a_node.summary, "summary")
l_parameters.put (a_node.content, "content")
l_parameters.put (a_node.publication_date, "publication_date")
l_parameters.put (a_node.creation_date, "creation_date")
l_parameters.put (a_node.modification_date, "modification_date")
l_parameters.put (a_node.publication_date, "publish")
l_parameters.put (a_node.creation_date, "created")
l_parameters.put (a_node.modification_date, "changed")
if
attached a_node.author as l_author and then
l_author.id > 0
then
l_parameters.put (l_author.id, "author_id")
l_parameters.put (l_author.id, "author")
else
l_parameters.put (0, "author_id")
l_parameters.put (0, "author")
end
sql_change (sql_insert_node, l_parameters)
sql_post_execution
@@ -167,10 +169,6 @@ feature -- Change: Node
create l_parameters.make (1)
l_parameters.put (a_id, "id")
sql_change (sql_delete_node, l_parameters)
sql_post_execution
-- Delete from user nodes. FIXME: what is that ???
sql_change (sql_delete_from_user_node, l_parameters)
sql_post_execution
end
@@ -178,25 +176,28 @@ feature -- Change: Node
-- Update node content `a_node'.
local
l_parameters: STRING_TABLE [detachable ANY]
now: DATE_TIME
do
create now.make_now_utc
error_handler.reset
log.write_information (generator + ".update_node")
create l_parameters.make (7)
l_parameters.put (a_node.title, "title")
l_parameters.put (a_node.summary, "summary")
l_parameters.put (a_node.content, "content")
l_parameters.put (a_node.publication_date, "publication_date")
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
l_parameters.put (a_node.publication_date, "publish")
l_parameters.put (now, "changed")
l_parameters.put (a_node.id, "id")
if attached a_node.author as l_author then
l_parameters.put (l_author.id, "id")
l_parameters.put (l_author.id, "editor")
l_parameters.put (l_author.id, "author")
else
l_parameters.put (0, "id")
l_parameters.put (0, "editor")
l_parameters.put (0, "author")
end
sql_change (sql_update_node, l_parameters)
sql_post_execution
if not error_handler.has_error then
a_node.set_modification_date (now)
end
end
update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
@@ -210,8 +211,8 @@ feature -- Change: Node
log.write_information (generator + ".update_node_title")
create l_parameters.make (3)
l_parameters.put (a_title, "title")
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
l_parameters.put (a_node_id, "id")
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
l_parameters.put (a_node_id, "nid")
sql_change (sql_update_node_title, l_parameters)
sql_post_execution
end
@@ -227,8 +228,8 @@ feature -- Change: Node
log.write_information (generator + ".update_node_summary")
create l_parameters.make (3)
l_parameters.put (a_summary, "summary")
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
l_parameters.put (a_node_id, "id")
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
l_parameters.put (a_node_id, "nid")
sql_change (sql_update_node_summary, l_parameters)
sql_post_execution
end
@@ -244,8 +245,8 @@ feature -- Change: Node
log.write_information (generator + ".update_node_content")
create l_parameters.make (3)
l_parameters.put (a_content, "content")
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
l_parameters.put (a_node_id, "id")
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
l_parameters.put (a_node_id, "nid")
sql_change (sql_update_node_content, l_parameters)
sql_post_execution
end
@@ -257,49 +258,36 @@ feature {NONE} -- Queries
Select_nodes: STRING = "select * from Nodes;"
-- SQL Query to retrieve all nodes.
Select_node_by_id: STRING = "select * from Nodes where id =:id order by id desc, publication_date desc;"
Select_node_by_id: STRING = "select * from Nodes where nid =:nid order by nid desc, publish desc;"
Select_recent_nodes: STRING = "select * from Nodes order by id desc, publication_date desc LIMIT :rows OFFSET :offset ;"
Select_recent_nodes: STRING = "select * from Nodes order by nid desc, publish desc LIMIT :rows OFFSET :offset ;"
SQL_Insert_node: STRING = "insert into nodes (title, summary, content, publication_date, creation_date, modification_date, author_id) values (:title, :summary, :content, :publication_date, :creation_date, :modification_date, :author_id);"
SQL_Insert_node: STRING = "insert into nodes (title, summary, content, publish, created, changed, author) values (:title, :summary, :content, :publish, :created, :changed, :author);"
-- SQL Insert to add a new node.
SQL_Update_node_title: STRING ="update nodes SET title=:title, modification_date=:modification_date, version = version + 1 where id=:id;"
-- SQL update node title.
SQL_Update_node_summary: STRING ="update nodes SET summary=:summary, modification_date=:modification_date, version = version + 1 where id=:id;"
-- SQL update node summary.
SQL_Update_node_content: STRING ="update nodes SET content=:content, modification_date=:modification_date, version = version + 1 where id=:id;"
-- SQL node content.
Slq_update_editor: STRING ="update nodes SET editor_id=:users_id where id=:nodes_id;"
-- SQL node content.
SQL_Update_node : STRING = "update nodes SET title=:title, summary=:summary, content=:content, publication_date=:publication_date, modification_date=:modification_date, version = version + 1, editor_id=:editor where id=:id;"
SQL_Update_node : STRING = "update nodes SET title=:title, summary=:summary, content=:content, publish=:publish, changed=:changed, version = version + 1, author=:author where nid=:nid;"
-- SQL node.
SQL_Delete_node: STRING = "delete from nodes where id=:id;"
SQL_Delete_node: STRING = "delete from nodes where nid=:nid;"
Sql_update_node_author: STRING = "update nodes SET author_id=:user_id where id=:id;"
Sql_update_node_author: STRING = "update nodes SET author=:author where nid=:nid;"
Sql_last_insert_node_id: STRING = "SELECT MAX(id) from nodes;"
SQL_Update_node_title: STRING ="update nodes SET title=:title, changed=:changed, version = version + 1 where nid=:nid;"
-- SQL update node title.
SQL_Update_node_summary: STRING ="update nodes SET summary=:summary, changed=:changed, version = version + 1 where nid=:nid;"
-- SQL update node summary.
SQL_Update_node_content: STRING ="update nodes SET content=:content, changed=:changed, version = version + 1 where nid=:nid;"
-- SQL node content.
Sql_last_insert_node_id: STRING = "SELECT MAX(nid) from nodes;"
feature {NONE} -- Sql Queries: USER_ROLES collaborators, author
Sql_insert_users_nodes: STRING = "insert into users_nodes (users_id, nodes_id) values (:users_id, :nodes_id);"
Select_user_author: STRING = "SELECT * FROM Nodes INNER JOIN users ON nodes.author=users.uid and users.uid = :uid;"
select_node_collaborators: STRING = "SELECT * FROM Users INNER JOIN users_nodes ON users.id=users_nodes.users_id and users_nodes.nodes_id = :node_id;"
Select_user_author: STRING = "SELECT * FROM Nodes INNER JOIN users ON nodes.author_id=users.id and users.id = :user_id;"
Select_node_author: STRING = "SELECT * FROM Users INNER JOIN nodes ON nodes.author_id=users.id and nodes.id =:node_id;"
Select_user_collaborator: STRING = "SELECT * FROM Nodes INNER JOIN users_nodes ON users_nodes.nodes_id = nodes.id and users_nodes.users_id = :user_id;"
Select_exist_user_node: STRING= "Select Count(*) from Users_nodes where users_id=:user_id and nodes_id=:node_id;"
sql_delete_from_user_node: STRING = "delete from users_nodes where nodes_id=:id"
Select_node_author: STRING = "SELECT * FROM Users INNER JOIN nodes ON nodes.author=users.uid and nodes.nid =:nid;"
feature {NONE} -- Implementation
@@ -309,24 +297,27 @@ feature {NONE} -- Implementation
if attached sql_read_integer_64 (1) as l_id then
Result.set_id (l_id)
end
if attached sql_read_date_time (2) as l_publication_date then
Result.set_publication_date (l_publication_date)
end
if attached sql_read_date_time (3) as l_creation_date then
Result.set_creation_date (l_creation_date)
end
if attached sql_read_date_time (4) as l_modif_date then
Result.set_modification_date (l_modif_date)
end
if attached sql_read_string_32 (5) as l_title then
if attached sql_read_string_32 (4) as l_title then
Result.set_title (l_title)
end
if attached sql_read_string_32 (6) as l_summary then
if attached sql_read_string_32 (5) as l_summary then
Result.set_summary (l_summary)
end
if attached sql_read_string (7) as l_content then
if attached sql_read_string (6) as l_content then
Result.set_content (l_content)
end
if attached sql_read_date_time (8) as l_publication_date then
Result.set_publication_date (l_publication_date)
end
if attached sql_read_date_time (9) as l_creation_date then
Result.set_creation_date (l_creation_date)
end
if attached sql_read_date_time (10) as l_modif_date then
Result.set_modification_date (l_modif_date)
end
if attached sql_read_integer_64 (7) as l_author_id then
-- access to API ...
end
end
fetch_author: detachable CMS_USER

View File

@@ -36,7 +36,7 @@ feature -- Access
deferred
ensure
same_id: Result /= Void implies Result.id = a_id
password: Result /= Void implies Result.password /= Void
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
end
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
@@ -46,7 +46,7 @@ feature -- Access
deferred
ensure
same_name: Result /= Void implies a_name ~ Result.name
password: Result /= Void implies Result.password /= Void
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
end
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
@@ -54,7 +54,7 @@ feature -- Access
deferred
ensure
same_email: Result /= Void implies a_email ~ Result.email
password: Result /= Void implies Result.password /= Void
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
end
is_valid_credential (a_u, a_p: READABLE_STRING_32): BOOLEAN
@@ -64,8 +64,17 @@ feature -- Access
feature -- Change: user
save_user (a_user: CMS_USER)
new_user (a_user: CMS_USER)
-- New user `a_user'.
require
no_id: not a_user.has_id
deferred
end
update_user (a_user: CMS_USER)
-- Save user `a_user'.
require
has_id: a_user.has_id
deferred
end

View File

@@ -47,6 +47,7 @@ feature -- Access: user
from
sql_query (select_users, Void)
sql_post_execution
sql_start
until
sql_after
loop
@@ -66,7 +67,7 @@ feature -- Access: user
error_handler.reset
log.write_information (generator + ".user")
create l_parameters.make (1)
l_parameters.put (a_id, "id")
l_parameters.put (a_id, "uid")
sql_query (select_user_by_id, l_parameters)
if sql_rows_count = 1 then
Result := fetch_user
@@ -136,20 +137,81 @@ feature -- Access: user
feature -- Change: user
save_user (a_user: CMS_USER)
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
local
l_parameters: STRING_TABLE [detachable ANY]
l_password_salt, l_password_hash: STRING
l_security: SECURITY_PROVIDER
do
if
attached a_user.password as l_password and then
attached a_user.email as l_email
then
sql_begin_transaction
new_user (a_user)
error_handler.reset
create l_security
l_password_salt := l_security.salt
l_password_hash := l_security.password_hash (l_password, l_password_salt)
log.write_information (generator + ".new_user")
create l_parameters.make (4)
l_parameters.put (a_user.name, "name")
l_parameters.put (l_password_hash, "password")
l_parameters.put (l_password_salt, "salt")
l_parameters.put (l_email, "email")
l_parameters.put (create {DATE_TIME}.make_now_utc, "created")
sql_change (sql_insert_user, l_parameters)
sql_post_execution
if not error_handler.has_error then
a_user.set_id (last_inserted_user_id)
sql_post_execution
end
sql_commit_transaction
else
debug ("refactor_fixme")
fixme ("maybe we should not always carry password, in this case, to implement the else part..")
end
-- set error
error_handler.add_custom_error (-1, "bad request" , "Missing password or email")
end
end
update_user (a_user: CMS_USER)
-- Save user `a_user'.
local
l_parameters: STRING_TABLE [detachable ANY]
l_password_salt, l_password_hash: detachable READABLE_STRING_8
l_security: SECURITY_PROVIDER
do
if attached a_user.password as l_password then
-- New password!
create l_security
l_password_salt := l_security.salt
l_password_hash := l_security.password_hash (l_password, l_password_salt)
else
-- Existing hashed password
l_password_hash := a_user.hashed_password
l_password_salt := user_salt (a_user.name)
end
if
l_password_hash /= Void and l_password_salt /= Void and
attached a_user.email as l_email
then
error_handler.reset
log.write_information (generator + ".update_user")
create l_parameters.make (6)
l_parameters.put (a_user.id, "uid")
l_parameters.put (a_user.name, "name")
l_parameters.put (l_password_hash, "password")
l_parameters.put (l_password_salt, "salt")
l_parameters.put (l_email, "email")
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
sql_change (sql_update_user, l_parameters)
sql_post_execution
else
-- set error
error_handler.add_custom_error (-1, "bad request" , "Missing password or email")
end
end
@@ -193,44 +255,6 @@ feature {NONE} -- Implementation
sql_post_execution
end
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
require
no_id: not a_user.has_id
local
l_parameters: STRING_TABLE [detachable ANY]
l_password_salt, l_password_hash: STRING
l_security: SECURITY_PROVIDER
do
if
attached a_user.password as l_password and then
attached a_user.email as l_email
then
error_handler.reset
create l_security
l_password_salt := l_security.salt
l_password_hash := l_security.password_hash (l_password, l_password_salt)
log.write_information (generator + ".new_user")
create l_parameters.make (4)
l_parameters.put (a_user.name, "username")
l_parameters.put (l_password_hash, "password")
l_parameters.put (l_password_salt, "salt")
l_parameters.put (l_email, "email")
sql_change (sql_insert_user, l_parameters)
sql_post_execution
if not error_handler.has_error then
a_user.set_id (last_inserted_user_id)
sql_post_execution
end
else
-- set error
error_handler.add_custom_error (-1, "bad request" , "Missing password or email")
end
sql_post_execution
end
fetch_user: detachable CMS_USER
local
l_id: INTEGER_64
@@ -282,25 +306,27 @@ feature {NONE} -- Sql Queries: USER
Select_users_count: STRING = "select count(*) from Users;"
-- Number of users.
Sql_last_insert_user_id: STRING = "SELECT MAX(id) from Users;"
Sql_last_insert_user_id: STRING = "SELECT MAX(uid) from Users;"
Select_users: STRING = "select * from Users;"
-- List of users.
Select_user_by_id: STRING = "select * from Users where id =:id;"
Select_user_by_id: STRING = "select * from Users where uid =:uid;"
-- Retrieve user by id if exists.
Select_user_by_name: STRING = "select * from Users where username =:name;"
Select_user_by_name: STRING = "select * from Users where name =:name;"
-- Retrieve user by name if exists.
Select_user_by_email: STRING = "select * from Users where email =:email;"
-- Retrieve user by email if exists.
Select_salt_by_username: STRING = "select salt from Users where username =:name;"
Select_salt_by_username: STRING = "select salt from Users where name =:name;"
-- Retrieve salt by username if exists.
SQL_Insert_user: STRING = "insert into users (username, password, salt, email) values (:username, :password, :salt, :email);"
-- SQL Insert to add a new node.
Sql_Insert_user: STRING = "insert into users (name, password, salt, email, created) values (:name, :password, :salt, :email, :created);"
-- SQL Insert to add a new node.
sql_update_user: STRING = "update users SET name=:name, password=:password, salt=:salt, email=:email WHERE uid=:uid;"
end

View File

@@ -88,12 +88,14 @@ feature -- Status Report
feature -- Access: Node
nodes_count: INTEGER_64
do
Result := storage.nodes_count
end
nodes: LIST [CMS_NODE]
-- List of nodes.
do
debug ("refactor_fixme")
fixme ("Implementation")
end
Result := storage.nodes
end
@@ -174,12 +176,15 @@ feature -- Change User
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
require
no_id: not a_user.has_id
no_hashed_password: a_user.hashed_password = Void
do
if
attached a_user.password as l_password and then
attached a_user.email as l_email
then
storage.save_user (a_user)
storage.new_user (a_user)
else
debug ("refactor_fixme")
fixme ("Add error")
@@ -187,6 +192,14 @@ feature -- Change User
end
end
update_user (a_user: CMS_USER)
-- Update user `a_user'.
require
has_id: a_user.has_id
do
storage.update_user (a_user)
end
feature -- Helpers
html_encoded (a_string: READABLE_STRING_GENERAL): STRING_8