Implemented view node by content type (no more hardcoded cases).

Added CMS_NODE_TYPE as descendant of CMS_CONTENT_TYPE,
  in case we have content which is not a node in the future.
  (probably useless, but for now, this extra abstraction is harmful)
Moved all node related code under node module cluster.
Applied comments from Javier Velilla.
Code cleaning.
This commit is contained in:
2015-04-29 17:28:33 +02:00
parent e8bb3790ba
commit c982f0ea9c
34 changed files with 756 additions and 521 deletions

View File

@@ -68,20 +68,6 @@ feature -- Access: user
do
end
feature -- User Nodes
user_collaborator_nodes (a_id: like {CMS_USER}.id): LIST [CMS_NODE]
-- Possible list of nodes where the user identified by `a_id', is a collaborator.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
end
user_author_nodes (a_id: like {CMS_USER}.id): LIST [CMS_NODE]
-- Possible list of nodes where the user identified by `a_id', is the author.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
end
feature -- Change: user
new_user (a_user: CMS_USER)

View File

@@ -6,6 +6,9 @@ note
deferred class
CMS_STORAGE_SQL_I
inherit
SHARED_LOGGER
feature -- Access
api: detachable CMS_API

View File

@@ -1,53 +0,0 @@
note
description: "Node storage extension for specific node descendant."
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_NODE_STORAGE_EXTENSION [G -> CMS_NODE]
feature -- Access
content_type: READABLE_STRING_8
deferred
end
feature -- Status report
is_accepted (a_node: CMS_NODE): BOOLEAN
-- Is `a_node' accepted by current storage extension?
do
Result := attached {G} a_node
end
feature -- Persistence
store_node (a_node: CMS_NODE)
require
a_node_accepted: is_accepted (a_node)
do
if attached {G} a_node as obj then
store (obj)
end
end
load_node (a_node: CMS_NODE)
require
a_node_accepted: is_accepted (a_node)
do
if attached {G} a_node as obj then
load (obj)
end
end
feature {NONE} -- Persistence implementation
store (a_node: G)
deferred
end
load (a_node: G)
deferred
end
end

View File

@@ -1,176 +0,0 @@
note
description: "Summary description for {CMS_NODE_STORAGE_I}."
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_NODE_STORAGE_I
inherit
SHARED_LOGGER
feature -- Error Handling
error_handler: ERROR_HANDLER
-- Error handler.
deferred
end
feature -- Storage extension
register_node_storage_extension (a_extension: CMS_NODE_STORAGE_EXTENSION [CMS_NODE])
-- Register `a_extension' as extension to the node storage system.
local
tb: like node_storage_extensions
do
tb := node_storage_extensions
if tb = Void then
create tb.make_caseless (1)
node_storage_extensions := tb
end
tb.force (a_extension, a_extension.content_type)
end
node_storage_extension (a_node: CMS_NODE): detachable CMS_NODE_STORAGE_EXTENSION [CMS_NODE]
-- Extension to the node storage system for node `a_node'.
do
if attached node_storage_extensions as tb then
Result := tb.item (a_node.content_type)
end
end
feature {NONE} -- Implementation
node_storage_extensions: detachable STRING_TABLE [CMS_NODE_STORAGE_EXTENSION [CMS_NODE]]
-- Table of node storage extensions.
extended_store (a_node: CMS_NODE)
-- Store extended data from `a_node'.
do
if attached node_storage_extension (a_node) as ext then
ext.store_node (a_node)
end
end
extended_load (a_node: CMS_NODE)
-- Load extended data into `a_node'.
do
if attached node_storage_extension (a_node) as ext then
ext.load_node (a_node)
end
end
feature -- Access
nodes_count: INTEGER_64
-- Count of nodes.
deferred
end
nodes: LIST [CMS_NODE]
-- List of nodes.
deferred
end
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- List of recent `a_count' nodes with an offset of `lower'.
deferred
end
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
-- Retrieve node by id `a_id', if any.
require
a_id > 0
deferred
end
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
-- Node's author. if any.
require
valid_node: a_id > 0
deferred
end
feature -- Change: Node
save_node (a_node: CMS_NODE)
-- Create or update `a_node'.
do
if a_node.has_id then
update_node (a_node)
else
new_node (a_node)
end
end
new_node (a_node: CMS_NODE)
-- Save node `a_node'.
require
no_id: not a_node.has_id
valid_user: attached a_node.author as l_author and then l_author.id > 0
deferred
end
update_node (a_node: CMS_NODE)
-- Update node content `a_node'.
-- The user `a_id' is an existing or new collaborator.
require
has_id: a_node.has_id
has_author: attached a_node.author as l_author and then l_author.has_id
deferred
end
delete_node (a_node: CMS_NODE)
-- Delete `a_node'.
do
if a_node.has_id then
delete_node_by_id (a_node.id)
end
end
delete_node_by_id (a_id: INTEGER_64)
-- Remove node by id `a_id'.
require
valid_node_id: a_id > 0
deferred
end
-- update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
-- -- Update node title to `a_title', node identified by id `a_node_id'.
-- -- The user `a_user_id' is an existing or new collaborator.
-- require
-- valid_node_id: a_node_id > 0
-- valid_user_id: a_user_id > 0
-- deferred
-- end
-- update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
-- -- Update node summary to `a_summary', node identified by id `a_node_id'.
-- -- The user `a_user_id' is an existing or new collaborator.
-- require
-- valid_id: a_node_id > 0
-- valid_user_id: a_user_id > 0
-- deferred
-- end
-- update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
-- -- Update node content to `a_content', node identified by id `a_node_id'.
-- -- The user `a_user_id' is an existing or new collaborator.
-- require
-- valid_id: a_node_id > 0
-- valid_user_id: a_user_id > 0
-- deferred
-- end
feature -- Helpers
fill_node (a_node: CMS_NODE)
-- Fill `a_node' with extra information from database.
-- i.e: specific to each content type data.
require
has_id: a_node.has_id
deferred
end
end

View File

@@ -1,106 +0,0 @@
note
description: "[
Objects that ...
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
class
CMS_NODE_STORAGE_NULL
inherit
CMS_NODE_STORAGE_I
create
make
feature {NONE} -- Initialization
make
-- Initialize `Current'.
do
create error_handler.make
end
feature -- Error Handling
error_handler: ERROR_HANDLER
-- Error handler.
feature -- Access: node
nodes_count: INTEGER_64
-- Count of nodes.
do
end
nodes: LIST[CMS_NODE]
-- List of nodes.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
end
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- List of the `a_count' most recent nodes, starting from `a_lower'.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
end
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
-- <Precursor>
do
end
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
-- Node's author. if any.
do
end
node_collaborators (a_id: like {CMS_NODE}.id): LIST [CMS_USER]
-- Possible list of node's collaborator.
do
create {ARRAYED_LIST [CMS_USER]} Result.make (0)
end
feature -- Node
new_node (a_node: CMS_NODE)
-- Add a new node
do
end
delete_node_by_id (a_id: INTEGER_64)
-- <Precursor>
do
end
update_node (a_node: CMS_NODE)
-- <Precursor>
do
end
-- update_node_title (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
-- -- <Precursor>
-- do
-- end
-- update_node_summary (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
-- -- <Precursor>
-- do
-- end
-- update_node_content (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
-- -- <Precursor>
-- do
-- end
feature -- Helpers
fill_node (a_node: CMS_NODE)
-- Fill `a_node' with extra information from database.
-- i.e: specific to each content type data.
do
end
end

View File

@@ -1,362 +0,0 @@
note
description: "[
CMS NODE Storage based on SQL statements.
]"
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
class
CMS_NODE_STORAGE_SQL
inherit
CMS_PROXY_STORAGE_SQL
CMS_NODE_STORAGE_I
CMS_STORAGE_SQL_I
REFACTORING_HELPER
SHARED_LOGGER
create
make
feature -- Access
nodes_count: INTEGER_64
-- Number of items nodes.
do
error_handler.reset
write_information_log (generator + ".nodes_count")
sql_query (sql_select_nodes_count, Void)
if sql_rows_count = 1 then
Result := sql_read_integer_64 (1)
end
end
nodes: LIST [CMS_NODE]
-- List of nodes.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
error_handler.reset
write_information_log (generator + ".nodes")
from
sql_query (sql_select_nodes, Void)
sql_start
until
sql_after
loop
if attached fetch_node as l_node then
Result.force (l_node)
end
sql_forth
end
-- across
-- Result as ic
-- loop
-- fill_node (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'.
local
l_parameters: STRING_TABLE [detachable ANY]
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
error_handler.reset
write_information_log (generator + ".nodes")
from
create l_parameters.make (2)
l_parameters.put (a_count, "rows")
l_parameters.put (a_lower, "offset")
sql_query (sql_select_recent_nodes, l_parameters)
sql_start
until
sql_after
loop
if attached fetch_node as l_node then
Result.force (l_node)
end
sql_forth
end
end
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
-- Retrieve node by id `a_id', if any.
local
l_parameters: STRING_TABLE [ANY]
do
error_handler.reset
write_information_log (generator + ".node")
create l_parameters.make (1)
l_parameters.put (a_id, "nid")
sql_query (sql_select_node_by_id, l_parameters)
if sql_rows_count = 1 then
Result := fetch_node
end
end
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
-- Node's author for the given node id.
local
l_parameters: STRING_TABLE [ANY]
do
error_handler.reset
write_information_log (generator + ".node_author")
create l_parameters.make (1)
l_parameters.put (a_id, "node_id")
sql_query (select_node_author, l_parameters)
if sql_rows_count >= 1 then
Result := fetch_author
end
end
last_inserted_node_id: INTEGER_64
-- Last insert node id.
do
error_handler.reset
write_information_log (generator + ".last_inserted_node_id")
sql_query (Sql_last_insert_node_id, Void)
if sql_rows_count = 1 then
Result := sql_read_integer_64 (1)
end
end
feature -- Change: Node
new_node (a_node: CMS_NODE)
-- Save node `a_node'.
do
store_node (a_node)
end
update_node (a_node: CMS_NODE)
-- Update node content `a_node'.
do
store_node (a_node)
end
delete_node_by_id (a_id: INTEGER_64)
-- Remove node by id `a_id'.
local
l_parameters: STRING_TABLE [ANY]
do
write_information_log (generator + ".delete_node")
error_handler.reset
create l_parameters.make (1)
l_parameters.put (a_id, "nid")
sql_change (sql_delete_node, l_parameters)
end
-- update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
-- -- <Precursor>
-- local
-- l_parameters: STRING_TABLE [detachable ANY]
-- do
-- -- FIXME: unused a_user_id !
-- error_handler.reset
-- write_information_log (generator + ".update_node_title")
-- create l_parameters.make (3)
-- l_parameters.put (a_title, "title")
-- 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)
-- end
-- update_node_summary (a_user_id: Like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
-- -- <Precursor>
-- local
-- l_parameters: STRING_TABLE [detachable ANY]
-- do
-- -- FIXME: unused a_user_id !
-- error_handler.reset
-- write_information_log (generator + ".update_node_summary")
-- create l_parameters.make (3)
-- l_parameters.put (a_summary, "summary")
-- 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)
-- end
-- update_node_content (a_user_id: Like {CMS_USER}.id;a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
-- -- <Precursor>
-- local
-- l_parameters: STRING_TABLE [detachable ANY]
-- do
-- -- FIXME: unused a_user_id !
-- error_handler.reset
-- write_information_log (generator + ".update_node_content")
-- create l_parameters.make (3)
-- l_parameters.put (a_content, "content")
-- 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)
-- end
feature {NONE} -- Implementation
store_node (a_node: CMS_NODE)
local
l_parameters: STRING_TABLE [detachable ANY]
now: DATE_TIME
do
create now.make_now_utc
error_handler.reset
write_information_log (generator + ".store_node")
create l_parameters.make (8)
l_parameters.put (a_node.content_type, "type")
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.format, "format")
l_parameters.put (a_node.publication_date, "publish")
l_parameters.put (now, "changed")
if attached a_node.author as l_author then
check valid_author: l_author.has_id end
l_parameters.put (l_author.id, "author")
else
l_parameters.put (0, "author")
end
sql_begin_transaction
if a_node.has_id then
-- Update
l_parameters.put (a_node.id, "nid")
sql_change (sql_update_node, l_parameters)
if not error_handler.has_error then
-- FIXED: FOR NOW no revision
-- a_node.set_revision (a_node.revision + 1) -- FIXME: Should be incremented by one, in same transaction...but check!
a_node.set_modification_date (now)
end
else
-- Store new node
l_parameters.put (a_node.creation_date, "created")
sql_change (sql_insert_node, l_parameters)
if not error_handler.has_error then
a_node.set_modification_date (now)
a_node.set_id (last_inserted_node_id)
a_node.set_revision (1) -- New object.
end
end
extended_store (a_node)
sql_commit_transaction
end
feature -- Helpers
fill_node (a_node: CMS_NODE)
-- Fill `a_node' with extra information from database.
-- i.e: specific to each content type data.
do
error_handler.reset
write_information_log (generator + ".fill_node")
extended_load (a_node)
end
feature {NONE} -- Queries
sql_select_nodes_count: STRING = "SELECT count(*) from Nodes;"
sql_select_nodes: STRING = "SELECT * from Nodes;"
-- SQL Query to retrieve all nodes.
sql_select_node_by_id: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed FROM Nodes WHERE nid =:nid ORDER BY revision desc, publish desc LIMIT 1;"
sql_select_recent_nodes: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed FROM Nodes ORDER BY nid desc, publish desc LIMIT :rows OFFSET :offset ;"
sql_insert_node: STRING = "INSERT INTO nodes (revision, type, title, summary, content, format, publish, created, changed, author) VALUES (1, :type, :title, :summary, :content, :format, :publish, :created, :changed, :author);"
-- SQL Insert to add a new node.
sql_update_node : STRING = "UPDATE nodes SET revision = revision, type=:type, title=:title, summary=:summary, content=:content, format=:format, publish=:publish, changed=:changed, author=:author WHERE nid=:nid;"
-- FIXME: for now no revision inc.!
-- sql_update_node : STRING = "UPDATE nodes SET revision = revision + 1, type=:type, title=:title, summary=:summary, content=:content, format=:format, publish=:publish, changed=:changed, revision = revision + 1, author=:author WHERE nid=:nid;"
-- SQL node.
sql_delete_node: STRING = "DELETE FROM nodes WHERE nid=:nid;"
-- sql_update_node_author: STRING = "UPDATE nodes SET author=:author WHERE nid=:nid;"
-- sql_update_node_title: STRING ="UPDATE nodes SET title=:title, changed=:changed, revision = revision + 1 WHERE nid=:nid;"
-- -- SQL update node title.
-- sql_update_node_summary: STRING ="UPDATE nodes SET summary=:summary, changed=:changed, revision = revision + 1 WHERE nid=:nid;"
-- -- SQL update node summary.
-- sql_update_node_content: STRING ="UPDATE nodes SET content=:content, changed=:changed, revision = revision + 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
Select_user_author: STRING = "SELECT uid, name, password, salt, email, status, created, signed FROM Nodes INNER JOIN users ON nodes.author=users.uid AND users.uid = :uid;"
Select_node_author: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed FROM users INNER JOIN nodes ON nodes.author=users.uid AND nodes.nid =:nid;"
feature {NONE} -- Implementation
fetch_node: detachable CMS_PARTIAL_NODE
do
if attached sql_read_string (3) as l_type then
create Result.make_empty (l_type)
if attached sql_read_integer_64 (1) as l_id then
Result.set_id (l_id)
end
if attached sql_read_integer_64 (2) as l_revision then
Result.set_revision (l_revision)
end
if attached sql_read_string_32 (4) as l_title then
Result.set_title (l_title)
end
if attached sql_read_string_32 (5) as l_summary then
Result.set_summary (l_summary)
end
if attached sql_read_string (6) as l_content then
Result.set_content (l_content)
end
if attached sql_read_string (7) as l_format then
Result.set_format (l_format)
end
if attached sql_read_integer_64 (8) as l_author_id then
Result.set_author (create {CMS_PARTIAL_USER}.make_with_id (l_author_id))
end
if attached sql_read_date_time (9) as l_publication_date then
Result.set_publication_date (l_publication_date)
end
if attached sql_read_date_time (10) as l_creation_date then
Result.set_creation_date (l_creation_date)
end
if attached sql_read_date_time (11) as l_modif_date then
Result.set_modification_date (l_modif_date)
end
end
end
fetch_author: detachable CMS_USER
do
if attached sql_read_string_32 (2) as l_name and then not l_name.is_whitespace then
create Result.make (l_name)
if attached sql_read_integer_32 (1) as l_id then
Result.set_id (l_id)
end
if attached sql_read_string (3) as l_password then
-- FIXME: should we return the password here ???
Result.set_hashed_password (l_password)
end
if attached sql_read_string (5) as l_email then
Result.set_email (l_email)
end
else
check expected_valid_user: False end
end
end
end

View File

@@ -1,112 +0,0 @@
note
description: "Storage extension for Page nodes."
date: "$Date$"
revision: "$Revision$"
class
CMS_NODE_STORAGE_SQL_PAGE_EXTENSION
inherit
CMS_NODE_STORAGE_EXTENSION [CMS_PAGE]
CMS_PROXY_STORAGE_SQL
rename
sql_storage as node_storage
redefine
node_storage
end
SHARED_LOGGER
create
make
feature {NONE} -- Initialization
node_storage: CMS_NODE_STORAGE_SQL
-- <Precursor>
feature -- Access
content_type: STRING
once
Result := {CMS_PAGE_CONTENT_TYPE}.name
end
feature -- Persistence
store (a_node: CMS_PAGE)
local
l_parameters: STRING_TABLE [ANY]
l_new_parent_id, l_previous_parent_id: INTEGER_64
l_update: BOOLEAN
do
error_handler.reset
write_information_log (generator + ".store_page_data")
create l_parameters.make (2)
l_parameters.put (a_node.id, "nid")
l_parameters.put (a_node.revision, "revision")
sql_query (sql_select_page_data, l_parameters)
if not has_error then
if sql_rows_count = 1 then
l_previous_parent_id := sql_read_integer_64 (3)
l_update := True
end
if attached a_node.parent as l_parent then
l_new_parent_id := l_parent.id
else
l_new_parent_id := 0
end
l_parameters.put (l_new_parent_id, "parent")
if l_update and l_new_parent_id /= l_previous_parent_id then
sql_change (sql_update_page_data, l_parameters)
elseif l_new_parent_id > 0 then
sql_change (sql_insert_page_data, l_parameters)
else
-- no page data, means everything is empty.
end
end
end
load (a_node: CMS_PAGE)
local
l_parameters: STRING_TABLE [ANY]
n: INTEGER
ct: CMS_PAGE_CONTENT_TYPE
do
error_handler.reset
write_information_log (generator + ".fill_page")
create l_parameters.make (2)
l_parameters.put (a_node.id, "nid")
l_parameters.put (a_node.revision, "revision")
sql_query (sql_select_page_data, l_parameters)
if not has_error then
n := sql_rows_count
if n = 1 then
-- nid, revision, parent
if
attached sql_read_integer_64 (3) as l_parent_id and then
l_parent_id /= a_node.id and then
attached node_storage.node_by_id (l_parent_id) as l_parent
then
-- FIXME: find a simple way to access the declared content types.
create ct
a_node.set_parent (ct.new_node (l_parent))
else
write_debug_log ("Invalid parent node id!")
end
else
check unique_data: n = 0 end
end
end
end
feature -- SQL
sql_select_page_data: STRING = "SELECT nid, revision, parent FROM page_nodes WHERE nid =:nid AND revision=:revision;"
sql_insert_page_data: STRING = "INSERT INTO page_nodes (nid, revision, parent) VALUES (:nid, :revision, :parent);"
sql_update_page_data: STRING = "UPDATE page_nodes SET nid=:nid, revision=:revision, parent=:parent WHERE nid=:nid AND revision=:revision;"
end