From 05472abdd78f216a8299248df6df5ea3d7c7308f Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Fri, 16 Oct 2015 17:22:22 +0200 Subject: [PATCH 01/15] Improved block condition "path:..." by allowing wildchar. Added weight data to CMS_BLOCK to be able to sort the block lists, and thus order the display of blocks. Set negative weight for various core block, so that they appear first as expected. The weight can be set and overwritten in cms.ini , by pref blocks.{block_id}.weight=integer_weight. --- cms-safe.ecf | 7 ++-- cms.ecf | 5 ++- .../cms_block_expression_condition.e | 14 ++++++- src/kernel/content/cms_block.e | 23 ++++++++++++ src/kernel/content/cms_block_region.e | 10 +++++ .../content/cms_smarty_template_block.e | 3 ++ src/service/response/cms_response.e | 37 ++++++++++++++++++- 7 files changed, 91 insertions(+), 8 deletions(-) diff --git a/cms-safe.ecf b/cms-safe.ecf index 2562261..0ddd5a4 100644 --- a/cms-safe.ecf +++ b/cms-safe.ecf @@ -1,5 +1,5 @@ - + @@ -14,14 +14,16 @@ - + + + @@ -30,7 +32,6 @@ - diff --git a/cms.ecf b/cms.ecf index 2c92e6d..efd3245 100644 --- a/cms.ecf +++ b/cms.ecf @@ -15,14 +15,16 @@ - + + + @@ -31,7 +33,6 @@ - diff --git a/src/kernel/content/block/condition/cms_block_expression_condition.e b/src/kernel/content/block/condition/cms_block_expression_condition.e index 531fef1..0691f84 100644 --- a/src/kernel/content/block/condition/cms_block_expression_condition.e +++ b/src/kernel/content/block/condition/cms_block_expression_condition.e @@ -41,6 +41,8 @@ feature -- Evaluation satisfied_for_response (res: CMS_RESPONSE): BOOLEAN local exp: like expression + l_path: READABLE_STRING_8 + kmp: KMP_WILD do exp := expression if exp.same_string ("is_front") then @@ -50,7 +52,17 @@ feature -- Evaluation elseif exp.same_string ("") then Result := False elseif exp.starts_with ("path:") then - Result := res.location.same_string (exp.substring (6, exp.count)) + l_path := exp.substring (6, exp.count) + if l_path.has ('*') then + if l_path.index_of ('*', 1) = l_path.count then + Result := res.location.starts_with_general (l_path.substring (1, l_path.count - 1)) + else + create kmp.make (l_path, res.location) + Result := kmp.pattern_matches + end + else + Result := res.location.same_string (l_path) + end end end diff --git a/src/kernel/content/cms_block.e b/src/kernel/content/cms_block.e index e629b93..544da41 100644 --- a/src/kernel/content/cms_block.e +++ b/src/kernel/content/cms_block.e @@ -6,7 +6,12 @@ deferred class CMS_BLOCK inherit + COMPARABLE + DEBUG_OUTPUT + undefine + is_equal + end feature -- Access @@ -23,6 +28,10 @@ feature -- Access html_options: detachable CMS_HTML_OPTIONS -- Optional addition html options. + weight: INTEGER + -- Weight used to order blocks. + -- Default: 0; + feature -- Status report is_empty: BOOLEAN @@ -42,6 +51,14 @@ feature -- Status report conditions: detachable LIST [CMS_BLOCK_CONDITION] -- Optional block condition to be enabled. +feature -- Comparison + + is_less alias "<" (other: like Current): BOOLEAN + -- . + do + Result := weight < other.weight + end + feature -- Element change add_css_class (a_class: READABLE_STRING_8) @@ -83,6 +100,12 @@ feature -- Element change l_conditions.force (a_condition) end + set_weight (w: like weight) + -- Set `weight' to `w'. + do + weight := w + end + feature -- Conversion to_html (a_theme: CMS_THEME): STRING_8 diff --git a/src/kernel/content/cms_block_region.e b/src/kernel/content/cms_block_region.e index 750ebd6..b5b7929 100644 --- a/src/kernel/content/cms_block_region.e +++ b/src/kernel/content/cms_block_region.e @@ -41,6 +41,16 @@ feature -- Element change blocks.prune_all (b) end +feature -- Sort + + sort + local + cmp: QUICK_SORTER [CMS_BLOCK] + do + create cmp.make (create {COMPARABLE_COMPARATOR [CMS_BLOCK]}) + cmp.sort (blocks) + end + note copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/src/kernel/content/cms_smarty_template_block.e b/src/kernel/content/cms_smarty_template_block.e index bdb76b3..bfff2ab 100644 --- a/src/kernel/content/cms_smarty_template_block.e +++ b/src/kernel/content/cms_smarty_template_block.e @@ -15,9 +15,12 @@ inherit select out end + SHARED_TEMPLATE_CONTEXT rename out as tpl_out + undefine + is_equal end create diff --git a/src/service/response/cms_response.e b/src/service/response/cms_response.e index 1d22c8f..6adc338 100644 --- a/src/service/response/cms_response.e +++ b/src/service/response/cms_response.e @@ -423,7 +423,18 @@ feature -- Blocks initialization Result := setup.text_item_or_default ("blocks." + a_block_id + ".region", a_default_region) end -feature -- Block management +feature -- Block management + + update_block (a_block: CMS_BLOCK) + -- Update parameters for block `a_block' according to configuration. + do + if + attached setup.text_item ("blocks." + a_block.name + ".weight") as w and then + w.is_integer + then + a_block.set_weight (w.to_integer) + end + end block_conditions (a_block_id: READABLE_STRING_8): detachable ARRAYED_LIST [CMS_BLOCK_EXPRESSION_CONDITION] -- Condition associated with `a_block_id' in configuration, if any. @@ -567,6 +578,9 @@ feature -- Blocks end get_blocks + -- Get block from CMS core, and from modules. + local + l_region: CMS_BLOCK_REGION do debug ("refactor_fixme") fixme ("find a way to have this in configuration or database, and allow different order") @@ -592,6 +606,19 @@ feature -- Blocks end hooks.invoke_block (Current) + + across + regions as reg_ic + loop + l_region := reg_ic.item + across + l_region.blocks as ic + loop + update_block (ic.item) + end + l_region.sort + end + debug ("cms") put_block (create {CMS_CONTENT_BLOCK}.make ("made_with", Void, "Made with EWF", Void), "footer", True) end @@ -641,6 +668,7 @@ feature -- Blocks do create s.make_empty create Result.make ("page_top", Void, s, Void) + Result.set_weight (-5) Result.set_is_raw (True) end @@ -652,6 +680,7 @@ feature -- Blocks create s.make_from_string (theme.menu_html (primary_menu, True, Void)) create l_hb.make_empty create Result.make ("header", Void, l_hb, Void) + Result.set_weight (-4) Result.set_is_raw (True) end @@ -683,6 +712,7 @@ feature -- Blocks if attached message as m and then not m.is_empty then create Result.make ("message", Void, "
" + m + "
", Void) Result.set_is_raw (True) + Result.set_weight (-2) end end @@ -699,6 +729,7 @@ feature -- Blocks end end create Result.make ("content", Void, s, Void) + Result.set_weight (-1) Result.set_is_raw (True) end @@ -922,8 +953,10 @@ feature -- Generation across regions as reg_ic loop + l_region := reg_ic.item + -- region blocks Already sorted. across - reg_ic.item.blocks as ic + l_region.blocks as ic loop if attached {CMS_SMARTY_TEMPLATE_BLOCK} ic.item as l_tpl_block then -- Apply page variables to smarty block. From e90f82387fabf0a14a9fd3f0d13aaf4bbf932a0a Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Fri, 16 Oct 2015 23:02:47 +0200 Subject: [PATCH 02/15] Added notion of alias block, to provide a way to include a block content in mutiple regions. --- src/hooks/cms_hook_core_manager.e | 31 ++- src/kernel/content/cms_alias_block.e | 59 ++++++ src/kernel/content/cms_block.e | 36 +--- src/kernel/content/cms_block_setup.e | 55 +++++ src/kernel/content/cms_cache_block.e | 9 - src/kernel/content/cms_content_block.e | 9 - src/kernel/content/cms_menu_block.e | 8 - .../content/cms_smarty_template_block.e | 9 - src/service/response/cms_response.e | 188 +++++++++++++++--- 9 files changed, 306 insertions(+), 98 deletions(-) create mode 100644 src/kernel/content/cms_alias_block.e create mode 100644 src/kernel/content/cms_block_setup.e diff --git a/src/hooks/cms_hook_core_manager.e b/src/hooks/cms_hook_core_manager.e index 475da6e..ddf16de 100644 --- a/src/hooks/cms_hook_core_manager.e +++ b/src/hooks/cms_hook_core_manager.e @@ -138,12 +138,16 @@ feature -- Hook: block invoke_block (a_response: CMS_RESPONSE) -- Invoke block hook for response `a_response' in order to get block from modules. local - bl: READABLE_STRING_8 + bl, l_alias: READABLE_STRING_8 bl_optional: BOOLEAN l_ok: BOOLEAN l_block_cache: detachable TUPLE [block: CMS_CACHE_BLOCK; region: READABLE_STRING_8; expired: BOOLEAN] + l_alias_table: detachable STRING_TABLE [LIST [READABLE_STRING_8]] --| block_id => [alias_ids..] + l_origin_block: detachable CMS_BLOCK do if attached subscribers ({CMS_HOOK_BLOCK}) as lst then + l_alias_table := a_response.block_alias_table + across lst as c loop @@ -162,6 +166,7 @@ feature -- Hook: block else l_ok := True end + if l_ok then l_block_cache := a_response.block_cache (bl) if l_block_cache /= Void and then not l_block_cache.expired then @@ -170,6 +175,30 @@ feature -- Hook: block h.get_block_view (bl, a_response) end end + if + l_alias_table /= Void and then + attached l_alias_table.item (bl) as l_aliases + then + across + l_aliases as aliases_ic + loop + l_alias := aliases_ic.item + l_origin_block := a_response.blocks.item (bl) + if l_origin_block = Void then + h.get_block_view (bl, a_response) + l_origin_block := a_response.blocks.item (bl) + if l_origin_block /= Void then + -- Previously, it was not included. + -- Computed only to include alias + -- then remove `l_origin_block'. + a_response.remove_block (l_origin_block) + end + end + if l_origin_block /= Void then + a_response.add_block (create {CMS_ALIAS_BLOCK}.make_with_block (l_alias, l_origin_block), Void) + end + end + end end end end diff --git a/src/kernel/content/cms_alias_block.e b/src/kernel/content/cms_alias_block.e new file mode 100644 index 0000000..60cc9fa --- /dev/null +++ b/src/kernel/content/cms_alias_block.e @@ -0,0 +1,59 @@ +note + description: "[ + Block being an alias of other block. + + Mainly to avoid multiple region for a block content. + ]" + date: "$Date$" + revision: "$Revision$" + +class + CMS_ALIAS_BLOCK + +inherit + CMS_BLOCK + +create + make_with_block + +feature {NONE} -- Initialization + + make_with_block (a_name: READABLE_STRING_8; a_block: CMS_BLOCK) + do + name := a_name + origin := a_block + title := a_block.title + end + +feature -- Access + + origin: CMS_BLOCK + + name: READABLE_STRING_8 + +feature -- Status report + + is_empty: BOOLEAN + -- + do + Result := origin.is_empty + end + + is_raw: BOOLEAN + -- + do + Result := origin.is_raw + end + +feature -- Conversion + + to_html (a_theme: CMS_THEME): STRING_8 + -- HTML representation of Current block. + do + Result := origin.to_html (a_theme) + end + +;note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" +end diff --git a/src/kernel/content/cms_block.e b/src/kernel/content/cms_block.e index 544da41..74568fa 100644 --- a/src/kernel/content/cms_block.e +++ b/src/kernel/content/cms_block.e @@ -6,6 +6,11 @@ deferred class CMS_BLOCK inherit + CMS_BLOCK_SETUP + undefine + is_equal + end + COMPARABLE DEBUG_OUTPUT @@ -20,18 +25,9 @@ feature -- Access deferred end - title: detachable READABLE_STRING_32 - -- Optional title. - deferred - end - html_options: detachable CMS_HTML_OPTIONS -- Optional addition html options. - weight: INTEGER - -- Weight used to order blocks. - -- Default: 0; - feature -- Status report is_empty: BOOLEAN @@ -48,9 +44,6 @@ feature -- Status report deferred end - conditions: detachable LIST [CMS_BLOCK_CONDITION] - -- Optional block condition to be enabled. - feature -- Comparison is_less alias "<" (other: like Current): BOOLEAN @@ -87,25 +80,6 @@ feature -- Element change opts.remove_css_class (a_class) end - add_condition (a_condition: CMS_BLOCK_CONDITION) - -- Add condition `a_condition'. - local - l_conditions: like conditions - do - l_conditions := conditions - if l_conditions = Void then - create {ARRAYED_LIST [CMS_BLOCK_CONDITION]} l_conditions.make (1) - conditions := l_conditions - end - l_conditions.force (a_condition) - end - - set_weight (w: like weight) - -- Set `weight' to `w'. - do - weight := w - end - feature -- Conversion to_html (a_theme: CMS_THEME): STRING_8 diff --git a/src/kernel/content/cms_block_setup.e b/src/kernel/content/cms_block_setup.e new file mode 100644 index 0000000..d30116e --- /dev/null +++ b/src/kernel/content/cms_block_setup.e @@ -0,0 +1,55 @@ +note + description: "Settings for CMS_BLOCK, that could be set and overwritten via CMS configuration." + date: "$Date$" + revision: "$Revision$" + +class + CMS_BLOCK_SETUP + +feature -- Access + + title: detachable READABLE_STRING_32 + -- Optional title. + + weight: INTEGER + -- Weight used to order blocks. + -- Default: 0. + + conditions: detachable LIST [CMS_BLOCK_CONDITION] + -- Optional block condition to be enabled. + +feature -- Element change + + set_title (a_title: detachable READABLE_STRING_GENERAL) + -- Set `title' with `a_title'. + do + if a_title = Void then + title := Void + else + title := a_title.as_string_32 + end + end + + set_weight (w: like weight) + -- Set `weight' to `w'. + do + weight := w + end + + add_condition (a_condition: CMS_BLOCK_CONDITION) + -- Add condition `a_condition'. + local + l_conditions: like conditions + do + l_conditions := conditions + if l_conditions = Void then + create {ARRAYED_LIST [CMS_BLOCK_CONDITION]} l_conditions.make (1) + conditions := l_conditions + end + l_conditions.force (a_condition) + end + +;note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" +end diff --git a/src/kernel/content/cms_cache_block.e b/src/kernel/content/cms_cache_block.e index 29e885c..56d8aed 100644 --- a/src/kernel/content/cms_cache_block.e +++ b/src/kernel/content/cms_cache_block.e @@ -32,9 +32,6 @@ feature -- Access name: READABLE_STRING_8 -- - title: detachable READABLE_STRING_32 - -- - cache: CMS_CACHE [READABLE_STRING_8] -- Cache content. @@ -65,12 +62,6 @@ feature -- Element change name := n end - set_title (a_title: like title) - -- Set `title' to `a_title'. - do - title := a_title - end - feature -- Conversion to_html (a_theme: CMS_THEME): STRING_8 diff --git a/src/kernel/content/cms_content_block.e b/src/kernel/content/cms_content_block.e index d45f89c..ffc975e 100644 --- a/src/kernel/content/cms_content_block.e +++ b/src/kernel/content/cms_content_block.e @@ -39,9 +39,6 @@ feature -- Access name: READABLE_STRING_8 -- - title: detachable READABLE_STRING_32 - -- - content: READABLE_STRING_8 format: detachable CONTENT_FORMAT @@ -74,12 +71,6 @@ feature -- Element change name := n end - set_title (a_title: like title) - -- Set `title' to `a_title'. - do - title := a_title - end - feature -- Conversion to_html (a_theme: CMS_THEME): STRING_8 diff --git a/src/kernel/content/cms_menu_block.e b/src/kernel/content/cms_menu_block.e index 8e060d8..f0efa41 100644 --- a/src/kernel/content/cms_menu_block.e +++ b/src/kernel/content/cms_menu_block.e @@ -27,8 +27,6 @@ feature -- Access name: READABLE_STRING_8 - title: detachable READABLE_STRING_32 - feature -- Status report is_empty: BOOLEAN @@ -53,12 +51,6 @@ feature -- Element change name := n end - set_title (a_title: like title) - -- Set `title' to `a_title'. - do - title := a_title - end - set_is_horizontal (b: BOOLEAN) -- Set `is_horizontal' to `b'. do diff --git a/src/kernel/content/cms_smarty_template_block.e b/src/kernel/content/cms_smarty_template_block.e index bfff2ab..7e53d9b 100644 --- a/src/kernel/content/cms_smarty_template_block.e +++ b/src/kernel/content/cms_smarty_template_block.e @@ -58,9 +58,6 @@ feature -- Access name: READABLE_STRING_8 -- - title: detachable READABLE_STRING_32 - -- - location: PATH -- Location of template file. @@ -94,12 +91,6 @@ feature -- Element change name := n end - set_title (a_title: like title) - -- Set `title' to `a_title'. - do - title := a_title - end - set_value (v: detachable ANY; k: READABLE_STRING_GENERAL) -- Associate value `v' with key `k'. do diff --git a/src/service/response/cms_response.e b/src/service/response/cms_response.e index 6adc338..2ff4f46 100644 --- a/src/service/response/cms_response.e +++ b/src/service/response/cms_response.e @@ -401,6 +401,7 @@ feature -- Blocks initialization fixme ("let the user choose ...") end create regions.make_caseless (5) + create blocks.make (10) create l_table.make_caseless (10) l_table["top"] := block_region_preference ("top", "top") @@ -434,10 +435,19 @@ feature -- Block management then a_block.set_weight (w.to_integer) end + if + attached setup.text_item ("blocks." + a_block.name + ".title") as l_title + then + if l_title.same_string ("") then + a_block.set_title (Void) + else + a_block.set_title (l_title) + end + end end block_conditions (a_block_id: READABLE_STRING_8): detachable ARRAYED_LIST [CMS_BLOCK_EXPRESSION_CONDITION] - -- Condition associated with `a_block_id' in configuration, if any. + -- Condition associated with `a_block_id' in configuration, if any. do if attached setup.text_item ("blocks." + a_block_id + ".condition") as s then create Result.make (1) @@ -446,11 +456,11 @@ feature -- Block management if attached setup.text_list_item ("blocks." + a_block_id + ".conditions") as lst then if Result = Void then create Result.make (lst.count) - across - lst as ic - loop - Result.force (create {CMS_BLOCK_EXPRESSION_CONDITION}.make (ic.item)) - end + end + across + lst as ic + loop + Result.force (create {CMS_BLOCK_EXPRESSION_CONDITION}.make (ic.item)) end end end @@ -517,11 +527,60 @@ feature -- Block management end end +feature {CMS_HOOK_CORE_MANAGER} -- Block management: internal + + internal_block_alias_table: like block_alias_table + -- Internal memory cache for `block_alias_table'. + + block_alias_table: detachable STRING_TABLE [LIST [READABLE_STRING_8]] + -- Table of included block aliases, if any. + -- note: { block_id => [ alias-names ..] } + local + k,v: READABLE_STRING_GENERAL + l_block_id, l_alias_id: READABLE_STRING_8 + lst: detachable LIST [READABLE_STRING_8] + do + Result := internal_block_alias_table + if + Result = Void and then + attached setup.text_table_item ("blocks.&aliases") as tb + then + create Result.make (tb.count) + across + tb as ic + loop + k := ic.key + v := ic.item + if v.is_valid_as_string_8 then + l_block_id := v.to_string_8 + if k.is_valid_as_string_8 then + l_alias_id := k.to_string_8 + if is_block_included (l_alias_id, False) then + lst := Result.item (l_block_id) + if lst = Void then + create {ARRAYED_LIST [READABLE_STRING_8]} lst.make (1) + end + lst.force (l_alias_id) + Result.force (lst, l_block_id) + end + else + check valid_alias_id: False end + end + else + check valid_block_id: False end + end + end + end + end + feature -- Blocks regions regions: STRING_TABLE [CMS_BLOCK_REGION] -- Layout regions, that contains blocks. + blocks: STRING_TABLE [CMS_BLOCK] + -- Blocks indexed by their block id. + block_region_settings: STRING_TABLE [STRING] block_region (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8): CMS_BLOCK_REGION @@ -551,6 +610,34 @@ feature -- Blocks regions end end +feature {NONE} -- Blocks + + put_core_block (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8; is_block_included_by_default: BOOLEAN; a_alias_table: like block_alias_table) + -- Add block `b' to associated region or `a_default_region' if provided + -- and check optional associated condition. + -- If no condition then use `is_block_included_by_default' to + -- decide if block is included or not. + local + l_region: detachable like block_region + do + if is_block_included (b.name, is_block_included_by_default) then + l_region := block_region (b, a_default_region) + l_region.extend (b) + blocks.force (b, b.name) + end + -- Included alias block ids. + if + a_alias_table /= Void and then + attached a_alias_table.item (b.name) as l_aliases + then + across + l_aliases as ic + loop + add_block (create {CMS_ALIAS_BLOCK}.make_with_block (ic.item, b), a_default_region) + end + end + end + feature -- Blocks put_block (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8; is_block_included_by_default: BOOLEAN) @@ -564,6 +651,7 @@ feature -- Blocks if is_block_included (b.name, is_block_included_by_default) then l_region := block_region (b, a_default_region) l_region.extend (b) + blocks.force (b, b.name) end end @@ -575,37 +663,37 @@ feature -- Blocks do l_region := block_region (b, a_default_region) l_region.extend (b) + blocks.force (b, b.name) + end + + remove_block (b: CMS_BLOCK) + -- Remove block `b' from associated region. + local + l_region: detachable like block_region + l_found: BOOLEAN + do + across + regions as reg_ic + until + l_found + loop + l_region := reg_ic.item + l_found := l_region.blocks.has (b) + if l_found then + l_region.remove (b) + end + end + blocks.remove (b.name) end get_blocks -- Get block from CMS core, and from modules. local l_region: CMS_BLOCK_REGION + b: CMS_BLOCK do - debug ("refactor_fixme") - fixme ("find a way to have this in configuration or database, and allow different order") - end - put_block (top_header_block, "top", True) - put_block (header_block, "header", True) - if attached message_block as m then - put_block (m, "content", True) - end - if attached primary_tabs_block as m then - put_block (m, "content", True) - end - add_block (content_block, "content") -- Can not be disabled! - - if attached management_menu_block as l_block then - put_block (l_block, "sidebar_first", True) - end - if attached navigation_menu_block as l_block then - put_block (l_block, "sidebar_first", True) - end - if attached user_menu_block as l_block then - put_block (l_block, "sidebar_second", True) - end - - hooks.invoke_block (Current) + get_core_blocks + get_module_blocks across regions as reg_ic @@ -620,10 +708,48 @@ feature -- Blocks end debug ("cms") - put_block (create {CMS_CONTENT_BLOCK}.make ("made_with", Void, "Made with EWF", Void), "footer", True) + create {CMS_CONTENT_BLOCK} b.make ("made_with", Void, "Made with EWF", Void) + b.set_weight (99) + put_block (b, "footer", True) end end + get_core_blocks + -- Get blocks provided by the CMS core. + local + l_alias_table: like block_alias_table + do + -- Get included aliased blocks. + l_alias_table := block_alias_table + + put_core_block (top_header_block, "top", True, l_alias_table) + put_core_block (header_block, "header", True, l_alias_table) + if attached message_block as m then + put_core_block (m, "content", True, l_alias_table) + end + if attached primary_tabs_block as m then + put_core_block (m, "content", True, l_alias_table) + end + add_block (content_block, "content") -- Can not be disabled! + + if attached management_menu_block as l_block then + put_core_block (l_block, "sidebar_first", True, l_alias_table) + end + if attached navigation_menu_block as l_block then + put_core_block (l_block, "sidebar_first", True, l_alias_table) + end + if attached user_menu_block as l_block then + put_core_block (l_block, "sidebar_second", True, l_alias_table) + end + end + + get_module_blocks + -- Get blocks provided by modules. + do + -- Get block from modules, and related alias. + hooks.invoke_block (Current) + end + primary_menu_block: detachable CMS_MENU_BLOCK do if attached primary_menu as m and then not m.is_empty then From d2d86ecdf251ac0ab5270244678955232c87156f Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Fri, 16 Oct 2015 23:11:44 +0200 Subject: [PATCH 03/15] Added notion of block options, declared in cms.ini as [blocks] {block_id}.options[name]=value {block_id}.options[size]=123 --- modules/recent_changes/cms_recent_changes_module.e | 12 +++++++++++- src/service/response/cms_response.e | 8 ++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/recent_changes/cms_recent_changes_module.e b/modules/recent_changes/cms_recent_changes_module.e index bf26f46..f5c6a41 100644 --- a/modules/recent_changes/cms_recent_changes_module.e +++ b/modules/recent_changes/cms_recent_changes_module.e @@ -70,6 +70,7 @@ feature -- Hook b: CMS_CONTENT_BLOCK s, l_content: STRING gen: FEED_TO_XHTML_VISITOR + nb: NATURAL_32 do if a_block_id.same_string_general ("recent_changes") then create l_content.make (1024) @@ -81,7 +82,16 @@ feature -- Hook s.append_string ("") gen.set_footer (s) - recent_changes_feed (a_response, 10, Void).accept (gen) + nb := 10 + if + attached a_response.block_options (a_block_id) as l_options and then + attached {READABLE_STRING_GENERAL} l_options.item ("size") as l_size and then + l_size.is_integer + then + nb := l_size.to_natural_32 + end + + recent_changes_feed (a_response, nb, Void).accept (gen) create b.make (a_block_id, Void, l_content, Void) a_response.put_block (b, Void, False) diff --git a/src/service/response/cms_response.e b/src/service/response/cms_response.e index 2ff4f46..75e9a21 100644 --- a/src/service/response/cms_response.e +++ b/src/service/response/cms_response.e @@ -465,6 +465,14 @@ feature -- Block management end end + block_options (a_block_id: READABLE_STRING_8): detachable STRING_TABLE [READABLE_STRING_32] + -- Options associated with `a_block_id' in configuration, if any. + do + if attached setup.text_table_item ("blocks." + a_block_id + ".options") as tb then + Result := tb + end + end + is_block_included (a_block_id: READABLE_STRING_8; dft: BOOLEAN): BOOLEAN -- Is block `a_block_id' included in current response? -- If no preference, return `dft'. From 23c395513b90a7291ff26424255ace09f233775c Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Fri, 16 Oct 2015 23:46:18 +0200 Subject: [PATCH 04/15] Fixed handling of block and optional block. - All blocks behavior can be specified and overwritten via the configuaration. - And optional block are not displayed by default. --- src/hooks/cms_hook_core_manager.e | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/hooks/cms_hook_core_manager.e b/src/hooks/cms_hook_core_manager.e index ddf16de..2198897 100644 --- a/src/hooks/cms_hook_core_manager.e +++ b/src/hooks/cms_hook_core_manager.e @@ -140,7 +140,6 @@ feature -- Hook: block local bl, l_alias: READABLE_STRING_8 bl_optional: BOOLEAN - l_ok: BOOLEAN l_block_cache: detachable TUPLE [block: CMS_CACHE_BLOCK; region: READABLE_STRING_8; expired: BOOLEAN] l_alias_table: detachable STRING_TABLE [LIST [READABLE_STRING_8]] --| block_id => [alias_ids..] l_origin_block: detachable CMS_BLOCK @@ -155,19 +154,13 @@ feature -- Hook: block across h.block_list as blst loop - l_ok := False bl := blst.item bl_optional := bl.count > 0 and bl[1] = '?' if bl_optional then bl := bl.substring (2, bl.count) - if a_response.is_block_included (bl, False) then - l_ok := True - end - else - l_ok := True end - if l_ok then + if a_response.is_block_included (bl, not bl_optional) then l_block_cache := a_response.block_cache (bl) if l_block_cache /= Void and then not l_block_cache.expired then a_response.add_block (l_block_cache.block, l_block_cache.region) From 62bf58ce6dc48e9a401a76c0798306b2f1e9fdd3 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Sat, 17 Oct 2015 00:17:59 +0200 Subject: [PATCH 05/15] Added support for block options for the feed aggregator blocks. Updated weight for primary_tabs block. --- .../feed_aggregator/feed_aggregator_module.e | 11 +++++++++- src/service/response/cms_response.e | 21 ++++++++++--------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/modules/feed_aggregator/feed_aggregator_module.e b/modules/feed_aggregator/feed_aggregator_module.e index a55e955..e0a4aee 100644 --- a/modules/feed_aggregator/feed_aggregator_module.e +++ b/modules/feed_aggregator/feed_aggregator_module.e @@ -230,6 +230,7 @@ feature -- Hook s: READABLE_STRING_8 b: CMS_CONTENT_BLOCK pref: STRING + nb: INTEGER do if attached feed_aggregator_api as l_feed_api then pref := "feed." @@ -238,7 +239,15 @@ feature -- Hook else s := a_block_id end - if attached feed_to_html (s, 0, True, a_response) as l_content then + nb := 0 + if + attached a_response.block_options (a_block_id) as l_options and then + attached {READABLE_STRING_GENERAL} l_options.item ("size") as l_size and then + l_size.is_integer + then + nb := l_size.to_integer + end + if attached feed_to_html (s, nb, True, a_response) as l_content then create b.make (a_block_id, Void, l_content, Void) b.set_is_raw (True) a_response.add_block (b, "feed_" + s) diff --git a/src/service/response/cms_response.e b/src/service/response/cms_response.e index 75e9a21..fbb3156 100644 --- a/src/service/response/cms_response.e +++ b/src/service/response/cms_response.e @@ -786,16 +786,6 @@ feature -- Blocks end end - primary_tabs_block: detachable CMS_MENU_BLOCK - do - if attached primary_tabs as m and then not m.is_empty then - create Result.make (m) - Result.is_horizontal := True - Result.set_is_raw (True) - Result.add_css_class ("tabs") - end - end - top_header_block: CMS_CONTENT_BLOCK local s: STRING @@ -846,7 +836,18 @@ feature -- Blocks if attached message as m and then not m.is_empty then create Result.make ("message", Void, "
" + m + "
", Void) Result.set_is_raw (True) + Result.set_weight (-3) + end + end + + primary_tabs_block: detachable CMS_MENU_BLOCK + do + if attached primary_tabs as m and then not m.is_empty then + create Result.make (m) + Result.is_horizontal := True + Result.set_is_raw (True) Result.set_weight (-2) + Result.add_css_class ("tabs") end end From 57430193e3c205e216c2092ef53ee820471025cf Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Sun, 18 Oct 2015 19:24:43 +0200 Subject: [PATCH 06/15] Fixed compilation of CMS_FILE_BLOCK. --- src/kernel/content/cms_file_block.e | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/kernel/content/cms_file_block.e b/src/kernel/content/cms_file_block.e index be49275..e99873d 100644 --- a/src/kernel/content/cms_file_block.e +++ b/src/kernel/content/cms_file_block.e @@ -48,9 +48,6 @@ feature -- Access name: READABLE_STRING_8 -- - title: detachable READABLE_STRING_32 - -- - location: PATH -- Location of file. @@ -105,12 +102,6 @@ feature -- Element change name := n end - set_title (a_title: like title) - -- Set `title' to `a_title'. - do - title := a_title - end - feature -- Conversion to_html (a_theme: CMS_THEME): STRING_8 From 7c99f2dc8376e155a1ddd67f938e08d67d300bf1 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Sun, 18 Oct 2015 20:47:33 +0200 Subject: [PATCH 07/15] Added recent_changes.ecf --- modules/recent_changes/recent_changes.ecf | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 modules/recent_changes/recent_changes.ecf diff --git a/modules/recent_changes/recent_changes.ecf b/modules/recent_changes/recent_changes.ecf new file mode 100644 index 0000000..3b85b4a --- /dev/null +++ b/modules/recent_changes/recent_changes.ecf @@ -0,0 +1,26 @@ + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + + + + + + + + + + + + + + From 7fcacad5ebfbf4f21136d0305c527ca32db28485 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 19 Oct 2015 11:20:04 +0200 Subject: [PATCH 08/15] Use extended type support from EiffelStore to handle STRING_32, and other extended types. --- .../store_mysql/src/cms_storage_store_mysql_builder.e | 1 + .../persistence/store_odbc/src/cms_storage_store_odbc_builder.e | 1 + 2 files changed, 2 insertions(+) diff --git a/library/persistence/store_mysql/src/cms_storage_store_mysql_builder.e b/library/persistence/store_mysql/src/cms_storage_store_mysql_builder.e index 21cdec6..4ea17aa 100644 --- a/library/persistence/store_mysql/src/cms_storage_store_mysql_builder.e +++ b/library/persistence/store_mysql/src/cms_storage_store_mysql_builder.e @@ -35,6 +35,7 @@ feature -- Factory if conn.is_connected then create Result.make (conn) set_map_zero_null_value (False) --| This way we map 0 to 0, instead of Null as default. + set_use_extended_types (True) --| Use extended types: STRING_32 etc. if Result.is_available then if not Result.is_initialized then initialize (a_setup, Result) diff --git a/library/persistence/store_odbc/src/cms_storage_store_odbc_builder.e b/library/persistence/store_odbc/src/cms_storage_store_odbc_builder.e index 80f9630..9deb926 100644 --- a/library/persistence/store_odbc/src/cms_storage_store_odbc_builder.e +++ b/library/persistence/store_odbc/src/cms_storage_store_odbc_builder.e @@ -48,6 +48,7 @@ feature -- Factory if conn.is_connected then create Result.make_with_driver (conn, l_database_config.item ("Driver")) set_map_zero_null_value (False) --| This way we map 0 to 0, instead of Null as default. + set_use_extended_types (True) --| Use extended types: STRING_32 etc. if Result.is_available then if not Result.is_initialized then initialize (a_setup, Result) From eb5ae32e46873ce689c33824387f22ab6e1cff6c Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 5 Oct 2015 16:04:10 +0200 Subject: [PATCH 09/15] Added persistence support for Eiffel sqlite3 wrapper. Updated existing persistency solution to be more generic to any db solution. --- examples/demo/demo-safe.ecf | 1 + examples/demo/site/config/cms.ini | 5 +- examples/demo/site/config/demo.json | 9 +- examples/demo/src/ewf_roc_server_execution.e | 1 + .../store/cms_storage_store_sql.e | 47 +- library/persistence/sqlite3/sqlite3-safe.ecf | 33 ++ .../sqlite3/src/cms_storage_sqlite3.e | 408 ++++++++++++++++++ .../sqlite3/src/cms_storage_sqlite3_builder.e | 90 ++++ .../cms_node_storage_sql_blog_extension.e | 17 +- .../blog/persistence/cms_blog_storage_sql.e | 6 +- .../node/persistence/cms_node_storage_sql.e | 36 +- .../cms_node_storage_sql_page_extension.e | 16 +- .../persistence/cms_oauth_20_storage_sql.e | 58 ++- .../persitence/cms_openid_storage_sql.e | 30 +- src/persistence/core/cms_core_storage_sql_i.e | 40 +- src/persistence/sql/cms_proxy_storage_sql.e | 34 +- src/persistence/sql/cms_storage_sql_i.e | 49 +-- src/persistence/user/cms_user_storage_sql_i.e | 139 ++++-- 18 files changed, 859 insertions(+), 160 deletions(-) create mode 100644 library/persistence/sqlite3/sqlite3-safe.ecf create mode 100644 library/persistence/sqlite3/src/cms_storage_sqlite3.e create mode 100644 library/persistence/sqlite3/src/cms_storage_sqlite3_builder.e diff --git a/examples/demo/demo-safe.ecf b/examples/demo/demo-safe.ecf index 8f28c4b..522d166 100644 --- a/examples/demo/demo-safe.ecf +++ b/examples/demo/demo-safe.ecf @@ -26,6 +26,7 @@ + + + + /EIFGENs$ + /CVS$ + /.svn$ + /old$ + + + + diff --git a/library/persistence/sqlite3/src/cms_storage_sqlite3.e b/library/persistence/sqlite3/src/cms_storage_sqlite3.e new file mode 100644 index 0000000..27e81f2 --- /dev/null +++ b/library/persistence/sqlite3/src/cms_storage_sqlite3.e @@ -0,0 +1,408 @@ +note + description: "Summary description for {CMS_STORAGE_MYSQL}." + date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $" + revision: "$Revision: 96596 $" + +class + CMS_STORAGE_SQLITE3 + +inherit + CMS_STORAGE_SQL + redefine + sql_read_date_time, sql_read_integer_32 + end + + CMS_CORE_STORAGE_SQL_I + redefine + sql_read_date_time, sql_read_integer_32 + end + + CMS_USER_STORAGE_SQL_I + redefine + sql_read_date_time, sql_read_integer_32 + end + + SQLITE_BIND_ARG_MARSHALLER + + REFACTORING_HELPER + +create + make + +feature {NONE} -- Initialization + + make (db: SQLITE_DATABASE) + do + sqlite := db + create error_handler.make + end + + sqlite: SQLITE_DATABASE + -- Associated SQLite database. + +feature -- Status report + + is_initialized: BOOLEAN + -- Is storage initialized? + do + Result := has_user + end + +feature -- Status report + + is_available: BOOLEAN + -- Is storage available? + do + Result := sqlite.is_interface_usable + end + +feature -- Basic operation + + close + -- Close/disconnect current storage. + do + sqlite.close + end + +feature -- Execution + + transaction_depth: INTEGER + + sql_begin_transaction + -- Start a database transtaction. + do + if transaction_depth = 0 then + sqlite.begin_transaction (False) + end + transaction_depth := transaction_depth + 1 + end + + sql_rollback_transaction + -- Rollback updates in the database. + do + if sqlite.is_in_transaction then + sqlite.rollback + end + transaction_depth := transaction_depth - 1 + end + + sql_commit_transaction + -- Commit updates in the database. + do + if sqlite.is_in_transaction then + sqlite.commit + end + transaction_depth := transaction_depth - 1 + end + + sql_post_execution + -- Post database execution. + -- note: execute after each `sql_query' and `sql_change'. + do + -- FIXME + if sqlite.has_error then + write_critical_log (generator + ".post_execution Error occurred!") + end + end + +feature -- Operation + + last_statement: detachable SQLITE_STATEMENT + + last_sqlite_result_cursor: detachable SQLITE_STATEMENT_ITERATION_CURSOR + + sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) + -- + local + st: SQLITE_QUERY_STATEMENT + do + last_sqlite_result_cursor := Void + create st.make (a_sql_statement, sqlite) + last_statement := st + if st.is_compiled then + if a_params /= Void then + check st.has_arguments end + last_sqlite_result_cursor := st.execute_new_with_arguments (sqlite_arguments (a_params)) + else + last_sqlite_result_cursor := st.execute_new + end + else + error_handler.add_custom_error (1, "invalid query", "query compilation failed!") + end + end + + sql_finalize + -- Finalize sql query (i.e destroy previous query statement. + do + if attached last_statement as st then + st.dispose + end + last_sqlite_result_cursor := Void + last_statement := Void + end + + sql_insert (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) + -- + local + st: SQLITE_INSERT_STATEMENT + do + last_sqlite_result_cursor := Void + create st.make (a_sql_statement, sqlite) + last_statement := st + if st.is_compiled then + if a_params /= Void then + check st.has_arguments end + last_sqlite_result_cursor := st.execute_new_with_arguments (sqlite_arguments (a_params)) + else + last_sqlite_result_cursor := st.execute_new + end + else + error_handler.add_custom_error (1, "invalid query", "query compilation failed!") + end + end + + sql_modify (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) + -- + local + st: SQLITE_MODIFY_STATEMENT + do + last_sqlite_result_cursor := Void + create st.make (a_sql_statement, sqlite) + last_statement := st + if st.is_compiled then + if a_params /= Void then + check st.has_arguments end + last_sqlite_result_cursor := st.execute_new_with_arguments (sqlite_arguments (a_params)) + else + last_sqlite_result_cursor := st.execute_new + end + else + error_handler.add_custom_error (1, "invalid query", "query compilation failed!") + end + end + + sqlite_arguments (a_params: STRING_TABLE [detachable ANY]): ARRAYED_LIST [SQLITE_BIND_ARG [ANY]] + local + k: READABLE_STRING_GENERAL + k8: STRING + do + create Result.make (a_params.count) + across + a_params as ic + loop + k := ic.key + if k.is_valid_as_string_8 then + k8 := k.as_string_8 + else + k8 := (create {UTF_CONVERTER}).utf_32_string_to_utf_8_string_8 (k) + end + if attached {DATE_TIME} ic.item as dt then + + Result.force (new_binding_argument (date_time_to_string (dt), ":" + k8)) + else + Result.force (new_binding_argument (ic.item, ":" + k8)) + end + end + end + + date_time_to_string (dt: DATE_TIME): STRING + do + create Result.make (16) + Result.append_integer (dt.year) + Result.append_character ('-') + if dt.month <= 9 then + Result.append_character ('0') + end + Result.append_integer (dt.month) + Result.append_character ('-') + if dt.day <= 9 then + Result.append_character ('0') + end + Result.append_integer (dt.day) + Result.append_character (' ') + if dt.hour <= 9 then + Result.append_character ('0') + end + Result.append_integer (dt.hour) + Result.append_character (':') + if dt.minute <= 9 then + Result.append_character ('0') + end + Result.append_integer (dt.minute) + Result.append_character (':') + if dt.second <= 9 then + Result.append_character ('0') + end + Result.append_integer (dt.second) + end + + string_to_date_time (a_string: READABLE_STRING_GENERAL): DATE_TIME + local + y,m,d: INTEGER + h,min,sec: INTEGER + s: detachable READABLE_STRING_GENERAL + i,j: INTEGER + do + i := 1 + -- YYYY + j := a_string.index_of ('-', i) + s := a_string.substring (i, j - 1) + y := s.to_integer + i := j + 1 + -- /MM + j := a_string.index_of ('-', i) + s := a_string.substring (i, j - 1) + m := s.to_integer + i := j + 1 + -- /DD + j := a_string.index_of (' ', i) + s := a_string.substring (i, j - 1) + d := s.to_integer + i := j + 1 + -- %THour + j := a_string.index_of (':', i) + s := a_string.substring (i, j - 1) + h := s.to_integer + i := j + 1 + -- :Min + j := a_string.index_of (':', i) + s := a_string.substring (i, j - 1) + min := s.to_integer + i := j + 1 + -- :Sec + j := a_string.count + 1 + s := a_string.substring (i, j - 1) + sec := s.to_integer + + create Result.make (y,m,d,h,min,sec) + end + +feature -- Access + +-- sql_rows_count: INTEGER +-- -- Number of rows for last sql execution. +-- do +-- if attached last_sqlite_result_cursor as l_cursor then +-- -- FIXME: find better solution! +-- from +-- Result := 1 +-- until +-- not l_cursor.after +-- loop +-- Result := Result + 1 +-- end +-- end +-- end + + sql_start + -- Set the cursor on first element. + do + -- Already at first position if any ? + if attached last_sqlite_result_cursor as l_cursor then +-- l_cursor.start + end + end + + sql_after: BOOLEAN + -- Are there no more items to iterate over? + do + if attached last_sqlite_result_cursor as l_cursor then + Result := l_cursor.after + end + end + + sql_forth + -- Fetch next row from last sql execution, if any. + do + if attached last_sqlite_result_cursor as l_cursor then + l_cursor.forth + end + end + + sql_valid_item_index (a_index: INTEGER): BOOLEAN + local + l_row: SQLITE_RESULT_ROW + do + if attached last_sqlite_result_cursor as l_cursor then + l_row := l_cursor.item + Result := a_index > 0 and a_index.to_natural_32 <= l_row.count + end + end + + sql_item (a_index: INTEGER): detachable ANY + local + l_row: SQLITE_RESULT_ROW + do + if attached last_sqlite_result_cursor as l_cursor then + l_row := l_cursor.item + Result := l_row.value (a_index.to_natural_32) + end + end + + sql_read_integer_32 (a_index: INTEGER): INTEGER_32 + -- Retrieved value at `a_index' position in `item'. + local + l_item: like sql_item + i64: INTEGER_64 + do + l_item := sql_item (a_index) + if attached {INTEGER_32} l_item as i then + Result := i + elseif attached {INTEGER_32_REF} l_item as l_value then + Result := l_value.item + else + if attached {INTEGER_64} l_item as i then + i64 := i + elseif attached {INTEGER_64_REF} l_item as l_value then + i64 := l_value.item + else + check is_integer_32: False end + end + if i64 <= {INTEGER_32}.max_value then + Result := i64.to_integer_32 + else + check is_integer_32: False end + end + end + end + + sql_read_date_time (a_index: INTEGER): detachable DATE_TIME + -- Retrieved value at `a_index' position in `item'. + local + l_item: like sql_item + do + l_item := sql_item (a_index) + if attached {DATE_TIME} l_item as dt then + Result := dt + elseif attached {READABLE_STRING_GENERAL} l_item as s then + Result := string_to_date_time (s) + else + check is_date_time_nor_null: l_item = Void end + end + end + +feature -- Conversion + + sql_statement (a_statement: STRING): STRING + -- . + local + i: INTEGER + do + Result := a_statement + from + i := 1 + until + i = 0 + loop + i := a_statement.substring_index ("AUTO_INCREMENT", i) + if i > 0 then + if Result = a_statement then + create Result.make_from_string (a_statement) + end + Result.remove (i + 4) + i := i + 14 + end + end + end + +end diff --git a/library/persistence/sqlite3/src/cms_storage_sqlite3_builder.e b/library/persistence/sqlite3/src/cms_storage_sqlite3_builder.e new file mode 100644 index 0000000..ce5c267 --- /dev/null +++ b/library/persistence/sqlite3/src/cms_storage_sqlite3_builder.e @@ -0,0 +1,90 @@ +note + description: "[ + Objects that ... + ]" + author: "$Author: jfiat $" + date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $" + revision: "$Revision: 96616 $" + +class + CMS_STORAGE_SQLITE3_BUILDER + +inherit + CMS_STORAGE_SQL_BUILDER + +create + make + +feature {NONE} -- Initialization + + make + -- Initialize `Current'. + do + end + +feature -- Factory + + storage (a_setup: CMS_SETUP; a_error_handler: ERROR_HANDLER): detachable CMS_STORAGE_SQLITE3 + local + s: detachable READABLE_STRING_32 + p: PATH + db: detachable SQLITE_DATABASE + l_source: SQLITE_FILE_SOURCE + i,j: INTEGER + do + if + attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.environment.application_config_path) as l_database_config + then + if l_database_config.driver.is_case_insensitive_equal ("sqlite3") then + s := l_database_config.database_string + i := s.substring_index ("Database=", 1) + if i > 0 then + i := s.index_of ('=', i) + 1 + j := s.index_of (';', i) + if j = 0 then + j := s.count + 1 + end + create p.make_from_string (s.substring (i, j - 1)) + else + create p.make_from_string (s) + end + + if attached reuseable_connection.item as d then + if p.same_as (d.path) then + db := d.database + end + end + if db = Void or else db.is_closed then + create l_source.make (p.name) + create db.make (l_source) + if l_source.exists then + db.open_read_write + else + db.open_create_read_write + end + end + if not db.is_closed then + db.set_busy_timeout (1_000) -- FIXME + create Result.make (db) +-- set_map_zero_null_value (False) --| This way we map 0 to 0, instead of Null as default. + if Result.is_available then + if not Result.is_initialized then + initialize (a_setup, Result) + end + end + else + a_error_handler.add_custom_error (0, "Could not connect to the ODBC storage", Void) + end + else + -- Wrong mapping between storage name and storage builder! + end + end + end + + reuseable_connection: CELL [detachable TUPLE [path: PATH; database: SQLITE_DATABASE]] + once + create Result.put (Void) + end + + +end diff --git a/modules/blog/cms_node_storage_sql_blog_extension.e b/modules/blog/cms_node_storage_sql_blog_extension.e index 24d6844..fefff15 100644 --- a/modules/blog/cms_node_storage_sql_blog_extension.e +++ b/modules/blog/cms_node_storage_sql_blog_extension.e @@ -83,11 +83,11 @@ feature -- Persistence if l_update then if l_has_modif then - sql_change (sql_update_node_data, l_parameters) + sql_modify (sql_update_node_data, l_parameters) end else if l_has_modif then - sql_change (sql_insert_node_data, l_parameters) + sql_insert (sql_insert_node_data, l_parameters) else -- no page data, means everything is empty. -- FOR NOW: always record row @@ -116,7 +116,7 @@ feature -- Persistence if a_node.has_id then create l_parameters.make (1) l_parameters.put (a_node.id, "nid") - sql_change (sql_delete_node_data, l_parameters) + sql_modify (sql_delete_node_data, l_parameters) end end @@ -136,18 +136,21 @@ feature {NONE} -- Implementation l_parameters.put (a_node.revision, "revision") sql_query (sql_select_node_data, l_parameters) if not has_error then - n := sql_rows_count - if n = 1 then + if not sql_after then -- nid, revision, tags l_rev := sql_read_integer_64 (2) l_tags := sql_read_string_32 (3) if l_tags /= Void then Result := [l_rev, l_tags] end - else - check unique_data: n = 0 end + sql_forth + if not sql_after then + check unique_data: n = 0 end + Result := Void + end end end + sql_finalize ensure accepted_revision: Result /= Void implies Result.revision <= a_node.revision end diff --git a/modules/blog/persistence/cms_blog_storage_sql.e b/modules/blog/persistence/cms_blog_storage_sql.e index 0ac754a..0644b48 100644 --- a/modules/blog/persistence/cms_blog_storage_sql.e +++ b/modules/blog/persistence/cms_blog_storage_sql.e @@ -23,9 +23,10 @@ feature -- Access error_handler.reset write_information_log (generator + ".blogs_count") sql_query (sql_select_blog_count, Void) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := sql_read_integer_64 (1) end + sql_finalize end blogs_count_from_user (a_user: CMS_USER) : INTEGER_64 @@ -38,9 +39,10 @@ feature -- Access create l_parameters.make (2) l_parameters.put (a_user.id, "user") sql_query (sql_select_blog_count_from_user, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := sql_read_integer_64 (1) end + sql_finalize end blogs: LIST [CMS_NODE] diff --git a/modules/node/persistence/cms_node_storage_sql.e b/modules/node/persistence/cms_node_storage_sql.e index 6305ca1..33707cb 100644 --- a/modules/node/persistence/cms_node_storage_sql.e +++ b/modules/node/persistence/cms_node_storage_sql.e @@ -28,9 +28,10 @@ feature -- Access error_handler.reset write_information_log (generator + ".nodes_count") sql_query (sql_select_nodes_count, Void) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := sql_read_natural_64 (1) end + sql_finalize end @@ -175,9 +176,10 @@ feature -- Access 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 + if not has_error and not sql_after then Result := fetch_node end + sql_finalize end node_by_id_and_revision (a_node_id, a_revision: INTEGER_64): detachable CMS_NODE @@ -191,9 +193,10 @@ feature -- Access l_parameters.put (a_node_id, "nid") l_parameters.put (a_revision, "revision") sql_query (sql_select_node_by_id_and_revision, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := fetch_node end + sql_finalize end node_author (a_node: CMS_NODE): detachable CMS_USER @@ -207,9 +210,10 @@ feature -- Access l_parameters.put (a_node.id, "nid") l_parameters.put (a_node.revision, "revision") sql_query (Select_user_author, l_parameters) - if sql_rows_count >= 1 then + if not has_error and not sql_after then Result := fetch_author end + sql_finalize end last_inserted_node_id: INTEGER_64 @@ -218,9 +222,10 @@ feature -- Access 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 + if not has_error and not sql_after then Result := sql_read_integer_64 (1) end + sql_finalize end last_inserted_node_revision (a_node: detachable CMS_NODE): INTEGER_64 @@ -234,11 +239,16 @@ feature -- Access create l_parameters.make (1) l_parameters.force (a_node.id, "nid") sql_query (Sql_last_insert_node_revision_for_nid, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then if sql_item (1) /= Void then Result := sql_read_integer_64 (1) end + sql_forth + if not sql_after then + check no_more_than_one: False end + end end + sql_finalize end -- if Result = 0 and not has_error then --| include the case a_node = Void -- sql_query (Sql_last_insert_node_revision, Void) @@ -328,7 +338,7 @@ feature -- Change: Node l_parameters.put (create {DATE_TIME}.make_now_utc, "changed") l_parameters.put ({CMS_NODE_API}.trashed, "status") l_parameters.put (a_id, "nid") - sql_change (sql_trash_node, l_parameters) + sql_modify (sql_trash_node, l_parameters) end delete_node_base (a_node: CMS_NODE) @@ -343,11 +353,11 @@ feature -- Change: Node error_handler.reset create l_parameters.make (1) l_parameters.put (a_node.id, "nid") - sql_change (sql_delete_node, l_parameters) + sql_modify (sql_delete_node, l_parameters) -- we remove node_revisions and pages. -- Check: maybe we need a transaction. - sql_change (sql_delete_node_revisions, l_parameters) + sql_modify (sql_delete_node_revisions, l_parameters) if not error_handler.has_error then extended_delete (a_node) @@ -368,7 +378,7 @@ feature -- Change: Node l_parameters.put (l_time, "changed") l_parameters.put ({CMS_NODE_API}.not_published, "status") l_parameters.put (a_id, "nid") - sql_change (sql_restore_node, l_parameters) + sql_modify (sql_restore_node, l_parameters) end @@ -412,7 +422,7 @@ feature {NONE} -- Implementation create l_copy_parameters.make (2) l_copy_parameters.force (a_node.id, "nid") -- l_copy_parameters.force (l_rev - 1, "revision") - sql_change (sql_copy_node_to_revision, l_copy_parameters) + sql_insert (sql_copy_node_to_revision, l_copy_parameters) if not has_error then a_node.set_revision (l_rev) @@ -420,7 +430,7 @@ feature {NONE} -- Implementation -- Update l_parameters.put (a_node.id, "nid") l_parameters.put (a_node.revision, "revision") - sql_change (sql_update_node, l_parameters) + sql_modify (sql_update_node, l_parameters) if not error_handler.has_error then a_node.set_modification_date (now) @@ -431,7 +441,7 @@ feature {NONE} -- Implementation l_parameters.put (a_node.creation_date, "created") l_parameters.put (l_rev, "revision") - sql_change (sql_insert_node, l_parameters) + sql_insert (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) diff --git a/modules/node/persistence/cms_node_storage_sql_page_extension.e b/modules/node/persistence/cms_node_storage_sql_page_extension.e index cdffa57..380ade8 100644 --- a/modules/node/persistence/cms_node_storage_sql_page_extension.e +++ b/modules/node/persistence/cms_node_storage_sql_page_extension.e @@ -73,15 +73,15 @@ feature -- Persistence if l_update then if l_has_modif then - sql_change (sql_update_node_data, l_parameters) + sql_modify (sql_update_node_data, l_parameters) end else if l_has_modif then - sql_change (sql_insert_node_data, l_parameters) + sql_insert (sql_insert_node_data, l_parameters) else -- no page data, means everything is empty. -- FOR NOW: always record row - sql_change (sql_insert_node_data, l_parameters) + sql_insert (sql_insert_node_data, l_parameters) end end end @@ -121,7 +121,7 @@ feature -- Persistence if a_node.has_id then create l_parameters.make (1) l_parameters.put (a_node.id, "nid") - sql_change (sql_delete_node_data, l_parameters) + sql_modify (sql_delete_node_data, l_parameters) end end @@ -139,10 +139,14 @@ feature {NONE} -- Implementation l_parameters.put (a_node.revision, "revision") sql_query (sql_select_node_data, l_parameters) if not has_error then - n := sql_rows_count - if n = 1 then + if not sql_after then -- nid, revision, parent Result := [sql_read_integer_64 (2), sql_read_integer_64 (3)] + sql_forth + if not sql_after then + check unique_data: n = 0 end + Result := Void + end else check unique_data: n = 0 end end diff --git a/modules/oauth20/persistence/cms_oauth_20_storage_sql.e b/modules/oauth20/persistence/cms_oauth_20_storage_sql.e index 24f1273..610268c 100644 --- a/modules/oauth20/persistence/cms_oauth_20_storage_sql.e +++ b/modules/oauth20/persistence/cms_oauth_20_storage_sql.e @@ -53,11 +53,15 @@ feature -- Access User Outh create l_string.make_from_string (select_user_oauth2_template_by_id) l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer)) sql_query (l_string, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := fetch_user - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + if not sql_after then + check no_more_than_one: False end + Result := Void + end end + sql_finalize end user_oauth2_by_email (a_email: like {CMS_USER}.email; a_consumer: READABLE_STRING_GENERAL): detachable CMS_USER @@ -73,11 +77,15 @@ feature -- Access User Outh create l_string.make_from_string (select_user_oauth2_template_by_email) l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer)) sql_query (l_string, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := fetch_user - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + if not sql_after then + check no_more_than_one: False end + Result := Void + end end + sql_finalize end user_oauth2_by_token (a_token: READABLE_STRING_GENERAL; a_consumer: READABLE_STRING_GENERAL): detachable CMS_USER @@ -93,11 +101,15 @@ feature -- Access User Outh create l_string.make_from_string (select_user_by_oauth2_template_token) l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer)) sql_query (l_string, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := fetch_user - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + if not sql_after then + check no_more_than_one: False end + Result := Void + end end + sql_finalize end @@ -134,11 +146,15 @@ feature --Access: Consumers create l_parameters.make (1) l_parameters.put (a_name, "name") sql_query (sql_oauth_consumer_name, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := fetch_consumer - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + if not sql_after then + check no_more_than_one: False end + Result := Void + end end + sql_finalize end oauth_consumer_by_callback (a_callback: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER @@ -151,11 +167,15 @@ feature --Access: Consumers create l_parameters.make (1) l_parameters.put (a_callback, "name") sql_query (sql_oauth_consumer_callback, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := fetch_consumer - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + if not sql_after then + check no_more_than_one: False end + Result := Void + end end + sql_finalize end feature -- Change: User OAuth @@ -181,7 +201,7 @@ feature -- Change: User OAuth create l_string.make_from_string (sql_insert_oauth2_template) l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer)) - sql_change (l_string, l_parameters) + sql_insert (l_string, l_parameters) sql_commit_transaction end @@ -202,7 +222,7 @@ feature -- Change: User OAuth create l_string.make_from_string (sql_update_oauth2_template) l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer)) - sql_change (l_string, l_parameters) + sql_modify (l_string, l_parameters) sql_commit_transaction end @@ -221,7 +241,7 @@ feature -- Change: User OAuth create l_string.make_from_string (sql_remove_oauth2_template) l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer)) - sql_change (l_string, l_parameters) + sql_modify (l_string, l_parameters) sql_commit_transaction end @@ -342,7 +362,7 @@ feature {NONE} -- User OAuth2 Sql_remove_oauth2_template: STRING = "DELETE FROM $table_name WHERE uid =:uid;" - Sql_oauth_consumers: STRING = "SELECT name FROM oauth2_consumers"; + Sql_oauth_consumers: STRING = "SELECT name FROM oauth2_consumers;" Sql_oauth2_table_prefix: STRING = "oauth2_" diff --git a/modules/openid/persitence/cms_openid_storage_sql.e b/modules/openid/persitence/cms_openid_storage_sql.e index ab85c2d..05714f7 100644 --- a/modules/openid/persitence/cms_openid_storage_sql.e +++ b/modules/openid/persitence/cms_openid_storage_sql.e @@ -33,11 +33,15 @@ feature -- Access User Outh l_parameters.put (a_uid, "uid") l_parameters.put (a_identity, "identity") sql_query (Select_user_openid_by_id, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := fetch_user - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + if not sql_after then + check no_more_than_one: False end + Result := Void + end end + sql_finalize end user_openid_by_identity (a_identity: READABLE_STRING_GENERAL): detachable CMS_USER @@ -50,10 +54,15 @@ feature -- Access User Outh create l_parameters.make (1) l_parameters.put (a_identity, "identity") sql_query (Select_user_by_openid_identity, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := fetch_user + sql_forth + if not sql_after then + check no_more_than_one: False end + Result := Void + end else - check no_more_than_one: sql_rows_count = 0 end + check no_more_than_one: False end end end @@ -91,11 +100,14 @@ feature --Access: Consumers create l_parameters.make (1) l_parameters.put (a_name, "name") sql_query (sql_openid_consumer_name, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := fetch_consumer - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + if not sql_after then + check no_more_than_one: False end + end end + sql_finalize end feature -- Change: User OAuth @@ -114,7 +126,7 @@ feature -- Change: User OAuth l_parameters.put (a_user.id, "uid") l_parameters.put (a_identity, "identity") l_parameters.put (create {DATE_TIME}.make_now_utc, "utc_date") - sql_change (Sql_insert_openid, l_parameters) + sql_insert (Sql_insert_openid, l_parameters) sql_commit_transaction end diff --git a/src/persistence/core/cms_core_storage_sql_i.e b/src/persistence/core/cms_core_storage_sql_i.e index c21305f..8a27dee 100644 --- a/src/persistence/core/cms_core_storage_sql_i.e +++ b/src/persistence/core/cms_core_storage_sql_i.e @@ -37,7 +37,7 @@ feature -- URL aliases error_handler.add_custom_error (0, "alias exists", "Path alias %"" + a_alias + "%" already exists!") end else - sql_change (sql_insert_path_alias, l_parameters) + sql_insert (sql_insert_path_alias, l_parameters) end end @@ -63,7 +63,7 @@ feature -- URL aliases l_parameters.put (l_previous_alias, "old") l_parameters.put (a_alias, "alias") - sql_change (sql_update_path_alias, l_parameters) + sql_modify (sql_update_path_alias, l_parameters) end end @@ -79,7 +79,7 @@ feature -- URL aliases -- Found create l_parameters.make (1) l_parameters.put (a_alias, "alias") - sql_change (sql_delete_path_alias, l_parameters) + sql_modify (sql_delete_path_alias, l_parameters) else error_handler.add_custom_error (0, "alias mismatch", "Path alias %"" + a_alias + "%" is not related to source %"" + a_source + "%"!") end @@ -97,11 +97,12 @@ feature -- URL aliases create l_parameters.make (1) l_parameters.put (a_source, "source") sql_query (sql_select_path_source, l_parameters) - if not has_error then - if sql_rows_count = 1 then - Result := sql_read_string (1) - end + if not has_error and not sql_after then + Result := sql_read_string (1) + sql_forth + check one_row: sql_after end end + sql_finalize end source_of_path_alias (a_alias: READABLE_STRING_8): detachable READABLE_STRING_8 @@ -114,10 +115,13 @@ feature -- URL aliases l_parameters.put (a_alias, "alias") sql_query (sql_select_path_alias, l_parameters) if not has_error then - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := sql_read_string (1) + sql_forth + check one_row: sql_after end end end + sql_finalize end sql_select_path_alias: STRING = "SELECT source FROM path_aliases WHERE alias=:alias ;" @@ -166,7 +170,7 @@ feature -- Logs l_parameters.put (Void, "link") end l_parameters.put (now, "date") - sql_change (sql_insert_log, l_parameters) + sql_insert (sql_insert_log, l_parameters) end sql_insert_log: STRING = "INSERT INTO logs (category, level, uid, message, info, link, date) VALUES (:category, :level, :uid, :message, :info, :link, :date);" @@ -193,10 +197,10 @@ feature -- Misc if a_value.same_string (l_value) then -- already up to date else - sql_change (sql_update_custom_value, l_parameters) + sql_modify (sql_update_custom_value, l_parameters) end else - sql_change (sql_insert_custom_value, l_parameters) + sql_insert (sql_insert_custom_value, l_parameters) end end @@ -214,7 +218,7 @@ feature -- Misc l_parameters.put (a_type, "default") end l_parameters.put (a_name, "name") - sql_change (sql_delete_custom_value, l_parameters) + sql_modify (sql_delete_custom_value, l_parameters) end custom_value (a_name: READABLE_STRING_GENERAL; a_type: detachable READABLE_STRING_8): detachable READABLE_STRING_32 @@ -232,11 +236,12 @@ feature -- Misc end l_parameters.put (a_name, "name") sql_query (sql_select_custom_value, l_parameters) - if not has_error then - if sql_rows_count = 1 then - Result := sql_read_string_32 (1) - end + if not has_error and not sql_after then + Result := sql_read_string_32 (1) + sql_forth + check one_row: sql_after end end + sql_finalize end sql_select_custom_value: STRING = "SELECT value FROM custom_values WHERE type=:type AND name=:name;" @@ -252,4 +257,7 @@ feature -- Misc -- SQL delete custom value; +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/src/persistence/sql/cms_proxy_storage_sql.e b/src/persistence/sql/cms_proxy_storage_sql.e index 10a37b2..694f542 100644 --- a/src/persistence/sql/cms_proxy_storage_sql.e +++ b/src/persistence/sql/cms_proxy_storage_sql.e @@ -68,19 +68,24 @@ feature -- Operation sql_storage.sql_query (a_sql_statement, a_params) end - sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) + sql_finalize + -- Finalize sql query (i.e destroy previous query statement. do - sql_storage.sql_change (a_sql_statement, a_params) + sql_storage.sql_finalize + end + + sql_insert (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) + do + sql_storage.sql_insert (a_sql_statement, a_params) + end + + sql_modify (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) + do + sql_storage.sql_modify (a_sql_statement, a_params) end feature -- Access - sql_rows_count: INTEGER - -- Number of rows for last sql execution. - do - Result := sql_storage.sql_rows_count - end - sql_start -- Set the cursor on first element. do @@ -109,6 +114,16 @@ feature -- Access Result:= sql_storage.sql_item (a_index) end + sql_read_integer_32 (a_index: INTEGER_32): INTEGER_32 + do + Result := sql_storage.sql_read_integer_32 (a_index) + end + + sql_read_date_time (a_index: INTEGER_32): detachable DATE_TIME + do + Result := sql_storage.sql_read_date_time (a_index) + end + feature -- Conversion sql_statement (a_statement: STRING): STRING @@ -117,4 +132,7 @@ feature -- Conversion Result := sql_storage.sql_statement (a_statement) end +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/src/persistence/sql/cms_storage_sql_i.e b/src/persistence/sql/cms_storage_sql_i.e index 2a73152..c183c4d 100644 --- a/src/persistence/sql/cms_storage_sql_i.e +++ b/src/persistence/sql/cms_storage_sql_i.e @@ -119,12 +119,22 @@ feature -- Operation end sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) - -- + -- Execute sql query `a_sql_statement' with optional parameters `a_params'. deferred end - sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) - -- + sql_finalize + -- Finalize sql query (i.e destroy previous query statement. + deferred + end + + sql_insert (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) + -- Execute sql insert `a_sql_statement' with optional parameters `a_params'. + deferred + end + + sql_modify (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) + -- Execute sql modify `a_sql_statement' with optional parameters `a_params'. deferred end @@ -179,7 +189,11 @@ feature -- Helper loop if attached next_sql_statement (a_sql_script, i, cl) as s then if not s.is_whitespace then - sql_change (sql_statement (s), a_params) + if s.starts_with ("INSERT") then + sql_insert (sql_statement (s), a_params) + else + sql_modify (sql_statement (s), a_params) + end err := err or has_error reset_error end @@ -217,11 +231,6 @@ feature -- Helper feature -- Access - sql_rows_count: INTEGER - -- Number of rows for last sql execution. - deferred - end - sql_start -- Set the cursor on first element. deferred @@ -279,17 +288,7 @@ feature -- Access sql_read_integer_32 (a_index: INTEGER): INTEGER_32 -- Retrieved value at `a_index' position in `item'. - local - l_item: like sql_item - do - l_item := sql_item (a_index) - if attached {INTEGER_32} l_item as i then - Result := i - elseif attached {INTEGER_32_REF} l_item as l_value then - Result := l_value.item - else - check is_integer_32: False end - end + deferred end sql_read_string (a_index: INTEGER): detachable STRING @@ -329,15 +328,7 @@ feature -- Access sql_read_date_time (a_index: INTEGER): detachable DATE_TIME -- Retrieved value at `a_index' position in `item'. - local - l_item: like sql_item - do - l_item := sql_item (a_index) - if attached {DATE_TIME} l_item as dt then - Result := dt - else - check is_date_time_nor_null: l_item = Void end - end + deferred end sql_read_boolean (a_index: INTEGER): detachable BOOLEAN diff --git a/src/persistence/user/cms_user_storage_sql_i.e b/src/persistence/user/cms_user_storage_sql_i.e index 1434d14..34304da 100644 --- a/src/persistence/user/cms_user_storage_sql_i.e +++ b/src/persistence/user/cms_user_storage_sql_i.e @@ -30,10 +30,12 @@ feature -- Access: user write_information_log (generator + ".user_count") sql_query (select_users_count, Void) - if sql_rows_count = 1 then - Result := sql_read_integer_32 (1) + if not has_error and then not sql_after then + Result := sql_read_integer_64 (1).to_integer_32 + sql_forth + check one_row: sql_after end end - error_handler.reset + sql_finalize end users: LIST [CMS_USER] @@ -47,13 +49,14 @@ feature -- Access: user sql_query (select_users, Void) sql_start until - sql_after + sql_after or has_error loop if attached fetch_user as l_user then Result.force (l_user) end sql_forth end + sql_finalize end user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER @@ -66,11 +69,12 @@ feature -- Access: user create l_parameters.make (1) l_parameters.put (a_id, "uid") sql_query (select_user_by_id, l_parameters) - if sql_rows_count = 1 then + if not has_error and not sql_after then Result := fetch_user - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + check one_row: sql_after end end + sql_finalize end user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER @@ -83,11 +87,12 @@ feature -- Access: user create l_parameters.make (1) l_parameters.put (a_name, "name") sql_query (select_user_by_name, l_parameters) - if sql_rows_count = 1 then + if not sql_after then Result := fetch_user - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + check one_row: sql_after end end + sql_finalize end user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER @@ -100,11 +105,12 @@ feature -- Access: user create l_parameters.make (1) l_parameters.put (a_email, "email") sql_query (select_user_by_email, l_parameters) - if sql_rows_count = 1 then + if not sql_after then Result := fetch_user - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + check one_row: sql_after end end + sql_finalize end user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER @@ -117,11 +123,12 @@ feature -- Access: user create l_parameters.make (1) l_parameters.put (a_token, "token") sql_query (select_user_by_activation_token, l_parameters) - if sql_rows_count = 1 then + if not sql_after then Result := fetch_user - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + check one_row: sql_after end end + sql_finalize end user_by_password_token (a_token: READABLE_STRING_32): detachable CMS_USER @@ -134,11 +141,12 @@ feature -- Access: user create l_parameters.make (1) l_parameters.put (a_token, "token") sql_query (select_user_by_password_token, l_parameters) - if sql_rows_count = 1 then + if not sql_after then Result := fetch_user - else - check no_more_than_one: sql_rows_count = 0 end + sql_forth + check one_row: sql_after end end + sql_finalize end is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN @@ -160,7 +168,6 @@ feature -- Access: user write_information_log (generator + ".is_valid_credential User:" + l_auth_login + "does not exist" ) end end - end recent_users (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_USER] @@ -187,6 +194,7 @@ feature -- Access: user end sql_forth end + sql_finalize end feature -- Change: user @@ -216,7 +224,7 @@ feature -- Change: user l_parameters.put (create {DATE_TIME}.make_now_utc, "created") l_parameters.put (a_user.status, "status") - sql_change (sql_insert_user, l_parameters) + sql_insert (sql_insert_user, l_parameters) if not error_handler.has_error then a_user.set_id (last_inserted_user_id) update_user_roles (a_user) @@ -226,6 +234,7 @@ feature -- Change: user else sql_rollback_transaction end + sql_finalize else -- set error error_handler.add_custom_error (-1, "bad request" , "Missing password or email") @@ -265,7 +274,7 @@ feature -- Change: user l_parameters.put (l_email, "email") l_parameters.put (a_user.status, "status") - sql_change (sql_update_user, l_parameters) + sql_modify (sql_update_user, l_parameters) if not error_handler.has_error then update_user_roles (a_user) end @@ -274,6 +283,7 @@ feature -- Change: user else sql_rollback_transaction end + sql_finalize else -- set error error_handler.add_custom_error (-1, "bad request" , "Missing password or email") @@ -290,8 +300,9 @@ feature -- Change: user write_information_log (generator + ".delete_user") create l_parameters.make (1) l_parameters.put (a_user.id, "uid") - sql_change (sql_delete_user, l_parameters) + sql_modify (sql_delete_user, l_parameters) sql_commit_transaction + sql_finalize end update_user_roles (a_user: CMS_USER) @@ -347,6 +358,7 @@ feature -- Change: user else sql_rollback_transaction end + sql_finalize end assign_role_to_user (a_role: CMS_USER_ROLE; a_user: CMS_USER) @@ -356,7 +368,8 @@ feature -- Change: user create l_parameters.make (2) l_parameters.put (a_user.id, "uid") l_parameters.put (a_role.id, "rid") - sql_change (sql_insert_role_to_user, l_parameters) + sql_insert (sql_insert_role_to_user, l_parameters) + sql_finalize end unassign_role_from_user (a_role: CMS_USER_ROLE; a_user: CMS_USER) @@ -366,7 +379,8 @@ feature -- Change: user create l_parameters.make (2) l_parameters.put (a_user.id, "uid") l_parameters.put (a_role.id, "rid") - sql_change (sql_delete_role_from_user, l_parameters) + sql_modify (sql_delete_role_from_user, l_parameters) + sql_finalize end feature -- Access: roles and permissions @@ -380,13 +394,16 @@ feature -- Access: roles and permissions create l_parameters.make (1) l_parameters.put (a_id, "rid") sql_query (select_user_role_by_id, l_parameters) - if sql_rows_count = 1 then + if not sql_after then Result := fetch_user_role + sql_forth + check one_row: sql_after end + sql_finalize if Result /= Void and not has_error then fill_user_role (Result) end else - check no_more_than_one: sql_rows_count = 0 end + sql_finalize end end @@ -400,13 +417,16 @@ feature -- Access: roles and permissions create l_parameters.make (1) l_parameters.put (a_name, "name") sql_query (select_user_role_by_name, l_parameters) - if sql_rows_count = 1 then + if not sql_after then Result := fetch_user_role + sql_forth + check one_row: sql_after end + sql_finalize if Result /= Void and not has_error then fill_user_role (Result) end else - check no_more_than_one: sql_rows_count = 0 end + sql_finalize end end @@ -431,6 +451,7 @@ feature -- Access: roles and permissions end sql_forth end + sql_finalize if not has_error then across Result as ic loop fill_user_role (ic.item) @@ -458,6 +479,7 @@ feature -- Access: roles and permissions end sql_forth end + sql_finalize if not has_error then across Result as ic loop fill_user_role (ic.item) @@ -501,6 +523,7 @@ feature -- Access: roles and permissions -- end sql_forth end + sql_finalize end role_permissions: LIST [READABLE_STRING_8] @@ -522,6 +545,7 @@ feature -- Access: roles and permissions end sql_forth end + sql_finalize end feature -- Change: roles and permissions @@ -550,7 +574,7 @@ feature -- Change: roles and permissions create l_parameters.make (2) l_parameters.put (a_user_role.id, "rid") l_parameters.put (a_user_role.name, "name") - sql_change (sql_update_user_role, l_parameters) + sql_modify (sql_update_user_role, l_parameters) end if not a_user_role.permissions.is_empty then -- FIXME: check if this is non set permissions,or none ... @@ -596,14 +620,17 @@ feature -- Change: roles and permissions else create l_parameters.make (1) l_parameters.put (a_user_role.name, "name") - sql_change (sql_insert_user_role, l_parameters) + sql_insert (sql_insert_user_role, l_parameters) if not error_handler.has_error then a_user_role.set_id (last_inserted_user_role_id) + sql_finalize across a_user_role.permissions as ic loop set_permission_for_role_id (ic.item, a_user_role.id) end + else + sql_finalize end end end @@ -619,7 +646,8 @@ feature -- Change: roles and permissions l_parameters.put (a_role_id, "rid") l_parameters.put (a_permission, "permission") l_parameters.put (Void, "module") -- FIXME: unsupported for now! - sql_change (sql_insert_user_role_permission, l_parameters) + sql_insert (sql_insert_user_role_permission, l_parameters) + sql_finalize end unset_permission_for_role_id (a_permission: READABLE_STRING_8; a_role_id: INTEGER) @@ -633,7 +661,8 @@ feature -- Change: roles and permissions create l_parameters.make (2) l_parameters.put (a_role_id, "rid") l_parameters.put (a_permission, "permission") - sql_change (sql_delete_user_role_permission, l_parameters) + sql_modify (sql_delete_user_role_permission, l_parameters) + sql_finalize end last_inserted_user_role_id: INTEGER_32 @@ -642,9 +671,12 @@ feature -- Change: roles and permissions error_handler.reset write_information_log (generator + ".last_inserted_user_role_id") sql_query (Sql_last_insert_user_role_id, Void) - if sql_rows_count = 1 then - Result := sql_read_integer_32 (1) + if not sql_after then + Result := sql_read_integer_64 (1).to_integer_32 + sql_forth + check one_row: sql_after end end + sql_finalize end @@ -658,9 +690,10 @@ feature -- Change: roles and permissions write_information_log (generator + ".delete_role") create l_parameters.make (1) l_parameters.put (a_role.id, "rid") - sql_change (sql_delete_role_permissions_by_role_id, l_parameters) - sql_change (sql_delete_role_by_id, l_parameters) + sql_modify (sql_delete_role_permissions_by_role_id, l_parameters) + sql_modify (sql_delete_role_by_id, l_parameters) sql_commit_transaction + sql_finalize end @@ -676,9 +709,12 @@ feature -- Access: User activation create l_parameters.make (1) l_parameters.put (a_token, "token") sql_query (sql_select_activation_expiration, l_parameters) - if sql_rows_count = 1 then + if not sql_after then Result := sql_read_integer_32 (1) + sql_forth + check one_row: sql_after end end + sql_finalize end user_id_by_activation (a_token: READABLE_STRING_32): INTEGER_64 @@ -691,9 +727,12 @@ feature -- Access: User activation create l_parameters.make (1) l_parameters.put (a_token, "token") sql_query (sql_select_userid_activation, l_parameters) - if sql_rows_count = 1 then + if not sql_after then Result := sql_read_integer_32 (1) + sql_forth + check one_row: sql_after end end + sql_finalize end feature -- Change: User activation @@ -712,8 +751,9 @@ feature -- Change: User activation l_parameters.put (a_token, "token") l_parameters.put (a_id, "uid") l_parameters.put (l_utc_date, "utc_date") - sql_change (sql_insert_activation, l_parameters) + sql_insert (sql_insert_activation, l_parameters) sql_commit_transaction + sql_finalize end remove_activation (a_token: READABLE_STRING_32) @@ -726,8 +766,9 @@ feature -- Change: User activation write_information_log (generator + ".remove_activation") create l_parameters.make (1) l_parameters.put (a_token, "token") - sql_change (sql_remove_activation, l_parameters) + sql_modify (sql_remove_activation, l_parameters) sql_commit_transaction + sql_finalize end feature -- Change: User password recovery @@ -746,8 +787,9 @@ feature -- Change: User password recovery l_parameters.put (a_token, "token") l_parameters.put (a_id, "uid") l_parameters.put (l_utc_date, "utc_date") - sql_change (sql_insert_password, l_parameters) + sql_insert (sql_insert_password, l_parameters) sql_commit_transaction + sql_finalize end remove_password (a_token: READABLE_STRING_32) @@ -760,8 +802,9 @@ feature -- Change: User password recovery write_information_log (generator + ".remove_password") create l_parameters.make (1) l_parameters.put (a_token, "token") - sql_change (sql_remove_password, l_parameters) + sql_modify (sql_remove_password, l_parameters) sql_commit_transaction + sql_finalize end feature {NONE} -- Implementation: User @@ -776,11 +819,14 @@ feature {NONE} -- Implementation: User create l_parameters.make (1) l_parameters.put (a_username, "name") sql_query (select_salt_by_username, l_parameters) - if sql_rows_count = 1 then + if not sql_after then if attached sql_read_string (1) as l_salt then Result := l_salt end + sql_forth + check one_row: sql_after end end + sql_finalize end fetch_user: detachable CMS_USER @@ -826,9 +872,12 @@ feature {NONE} -- Implementation: User error_handler.reset write_information_log (generator + ".last_inserted_user_id") sql_query (Sql_last_insert_user_id, Void) - if sql_rows_count = 1 then + if not sql_after then Result := sql_read_integer_64 (1) + sql_forth + check one_row: sql_after end end + sql_finalize end feature {NONE} -- Implementation: User role From a260bbc2c59d6b75062a3062b156a4d40f1f0ea1 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 19 Oct 2015 20:50:47 +0200 Subject: [PATCH 10/15] Removed obsolete usage of {TYPE}.attempt from CMS_MODULE_COLLECTION. --- src/service/cms_module_collection.e | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/service/cms_module_collection.e b/src/service/cms_module_collection.e index 041a78b..8722038 100644 --- a/src/service/cms_module_collection.e +++ b/src/service/cms_module_collection.e @@ -1,5 +1,7 @@ note - description: "Collection of CMS modules." + description: "[ + Collection of CMS modules. + ]" date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $" revision: "$Revision: 96596 $" @@ -38,7 +40,8 @@ feature -- Access -- Found elseif -- Hack: use conformance of type, and reverse conformance of type of type. - attached a_type.attempt (Result) and then attached l_type.generating_type.attempt (a_type) + attached a_type.attempted (Result) and then + attached l_type.generating_type.attempted (a_type) then -- Found else From f51ddc9796793f1dae0ff93d3fd1de48470e9462 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 19 Oct 2015 22:50:48 +0200 Subject: [PATCH 11/15] Extracted launcher code into cms/launcher/... libraries. (mostly to help new project based on ROC CMS). Renamed and simplified the roc cms server launcher, and the related cms execution. Updated cms.ini and extract blocks related management into blocks.ini. Added debug clauses for cms sqlite3 storage. --- examples/demo/demo-safe.ecf | 47 +++---- examples/demo/site/config/blocks.ini | 38 ++++++ examples/demo/site/config/cms.ini | 20 +-- ...erver_execution.e => demo_cms_execution.e} | 29 ++-- examples/demo/src/demo_cms_server.e | 18 +++ launcher/README.txt | 10 ++ launcher/any-safe.ecf | 18 +++ launcher/any.ecf | 19 +++ launcher/any/application_launcher.e | 19 +++ launcher/any/application_launcher_i.e | 127 ++++++++++++++++++ launcher/cgi-safe.ecf | 15 +++ launcher/default/application_launcher.e | 19 +++ launcher/default/application_launcher_i.e | 26 ++++ launcher/libfcgi-safe.ecf | 15 +++ launcher/libfcgi.ecf | 16 +++ .../roc_cms_launcher.e | 21 ++- launcher/standalone-safe.ecf | 16 +++ launcher/standalone.ecf | 17 +++ library/persistence/sqlite3/sqlite3-safe.ecf | 17 +-- .../sqlite3/src/cms_storage_sqlite3.e | 74 ++++++---- 20 files changed, 476 insertions(+), 105 deletions(-) create mode 100644 examples/demo/site/config/blocks.ini rename examples/demo/src/{ewf_roc_server_execution.e => demo_cms_execution.e} (80%) create mode 100644 examples/demo/src/demo_cms_server.e create mode 100644 launcher/README.txt create mode 100644 launcher/any-safe.ecf create mode 100644 launcher/any.ecf create mode 100644 launcher/any/application_launcher.e create mode 100644 launcher/any/application_launcher_i.e create mode 100644 launcher/cgi-safe.ecf create mode 100644 launcher/default/application_launcher.e create mode 100644 launcher/default/application_launcher_i.e create mode 100644 launcher/libfcgi-safe.ecf create mode 100644 launcher/libfcgi.ecf rename examples/demo/src/ewf_roc_server.e => launcher/roc_cms_launcher.e (74%) create mode 100644 launcher/standalone-safe.ecf create mode 100644 launcher/standalone.ecf diff --git a/examples/demo/demo-safe.ecf b/examples/demo/demo-safe.ecf index 522d166..c61f4c4 100644 --- a/examples/demo/demo-safe.ecf +++ b/examples/demo/demo-safe.ecf @@ -1,7 +1,8 @@ - + Example/demo for Eiffel ROC CMS library + /EIFGENs$ /CVS$ @@ -12,7 +13,12 @@ - + + + + @@ -24,35 +30,31 @@ - - - + + + - - - - - - + - - - + @@ -64,25 +66,14 @@ - - - - - - - - - - + - - - + diff --git a/examples/demo/site/config/blocks.ini b/examples/demo/site/config/blocks.ini new file mode 100644 index 0000000..deb55b7 --- /dev/null +++ b/examples/demo/site/config/blocks.ini @@ -0,0 +1,38 @@ +### Blocks settings + +#navigation.region=sidebar_first +#navigation.condition=is_front +management.conditions[]=path:admin* +management.conditions[]=is_front + +#Feeds +feed.news.weight=3 +feed.news.region=feed_news +feed.news.region=content +feed.news.condition= +feed.forum.weight=2 +feed.forum.region=feed_forum +feed.forum.region= +feed.forum.condition= +feed.forum.options[size]=15 + +#Updates +recent_changes.region=content +recent_changes.condition=is_front +recent_changes.title=Updates +recent_changes.options[size]=3 + +#Aliases +&aliases[foo]=management +&aliases[bar]=feed.forum + +foo.region=content +foo.condition=is_front +foo.weight=-10 + +bar.region=content +bar.condition=is_front +bar.title=Bar + + + diff --git a/examples/demo/site/config/cms.ini b/examples/demo/site/config/cms.ini index 157d916..14ecba6 100644 --- a/examples/demo/site/config/cms.ini +++ b/examples/demo/site/config/cms.ini @@ -21,28 +21,10 @@ output=@stderr # for each module, this can be overwritten with # module_name= on or off *=all -admin=on -auth=on -basic_auth=on -blog=on -debug=on -demo=on -node=on -oauth20=on -openid=on [blocks] -#navigation.region=sidebar_first -feed.news.region=feed_news -feed.news.condition=is_front - -feed.forum.region=feed_forum -feed.forum.condition=is_front - -#management.condition=is_front -#navigation.condition=is_front +@include=blocks.ini [admin] # CMS Installation, are accessible by "all", "none" or uppon "permission". (default is none) -installation_access=permission installation_access=all diff --git a/examples/demo/src/ewf_roc_server_execution.e b/examples/demo/src/demo_cms_execution.e similarity index 80% rename from examples/demo/src/ewf_roc_server_execution.e rename to examples/demo/src/demo_cms_execution.e index cbd008d..9006b56 100644 --- a/examples/demo/src/ewf_roc_server_execution.e +++ b/examples/demo/src/demo_cms_execution.e @@ -1,31 +1,21 @@ note - description: "Summary description for {EWF_ROC_SERVER_EXECUTION}." + description: "[ + CMS Execution for the demo server. + ]" date: "$Date$" revision: "$Revision$" class - EWF_ROC_SERVER_EXECUTION + DEMO_CMS_EXECUTION inherit CMS_EXECUTION - redefine - initialize - end - - REFACTORING_HELPER - - SHARED_LOGGER create make feature {NONE} -- Initialization - initialize - do - Precursor - end - initial_cms_setup: CMS_DEFAULT_SETUP -- CMS setup. local @@ -39,18 +29,17 @@ feature {NONE} -- Initialization create Result.make (l_env) end -feature -- CMS setup +feature -- CMS storage setup_storage (a_setup: CMS_SETUP) do - debug ("refactor_fixme") - to_implement ("To implement custom storage") - end --- a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_MYSQL_BUILDER}.make, "mysql") a_setup.storage_drivers.force (create {CMS_STORAGE_SQLITE3_BUILDER}.make, "sqlite3") - a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_ODBC_BUILDER}.make, "odbc") +-- a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_MYSQL_BUILDER}.make, "mysql") +-- a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_ODBC_BUILDER}.make, "odbc") end +feature -- CMS modules + setup_modules (a_setup: CMS_SETUP) -- Setup additional modules. local diff --git a/examples/demo/src/demo_cms_server.e b/examples/demo/src/demo_cms_server.e new file mode 100644 index 0000000..1e50b91 --- /dev/null +++ b/examples/demo/src/demo_cms_server.e @@ -0,0 +1,18 @@ +note + description: "[ + DEMO application server. + ]" + date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $" + revision: "$Revision: 96596 $" + +class + DEMO_CMS_SERVER + +inherit + ROC_CMS_LAUNCHER [DEMO_CMS_EXECUTION] + +create + make_and_launch + +end + diff --git a/launcher/README.txt b/launcher/README.txt new file mode 100644 index 0000000..b63b6e1 --- /dev/null +++ b/launcher/README.txt @@ -0,0 +1,10 @@ +Collection of ROC CMS launcher ready to use. + +- Include any-safe.ecf to use any of cgi, libfcgi or standalone connector. +- Include standalone-safe.ecf to use standalone connector. +- Include libfcgi-safe.ecf to use libfcgi connector. +- Include cgi-safe.ecf to use cgi connector. + +In application, the root class need to inherit from ROC_CMS_LAUNCHER with adapted CMS_EXECUTION +descendant. + diff --git a/launcher/any-safe.ecf b/launcher/any-safe.ecf new file mode 100644 index 0000000..4a7326a --- /dev/null +++ b/launcher/any-safe.ecf @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/launcher/any.ecf b/launcher/any.ecf new file mode 100644 index 0000000..9983098 --- /dev/null +++ b/launcher/any.ecf @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + diff --git a/launcher/any/application_launcher.e b/launcher/any/application_launcher.e new file mode 100644 index 0000000..bb184d0 --- /dev/null +++ b/launcher/any/application_launcher.e @@ -0,0 +1,19 @@ +note + description: "[ + Effective class for APPLICATION_LAUNCHER_I + + You can put modification in this class + ]" + date: "$Date: 2013-06-12 13:55:42 +0200 (mer., 12 juin 2013) $" + revision: "$Revision: 36 $" + +class + APPLICATION_LAUNCHER [G -> WSF_EXECUTION create make end] + +inherit + APPLICATION_LAUNCHER_I [G] + +feature -- Custom + +end + diff --git a/launcher/any/application_launcher_i.e b/launcher/any/application_launcher_i.e new file mode 100644 index 0000000..026d12f --- /dev/null +++ b/launcher/any/application_launcher_i.e @@ -0,0 +1,127 @@ +note + description: "[ + Specific application launcher + + DO NOT EDIT THIS CLASS + + you can customize APPLICATION_LAUNCHER + ]" + date: "$Date: 2013-06-12 13:55:42 +0200 (mer., 12 juin 2013) $" + revision: "$Revision: 36 $" + +deferred class + APPLICATION_LAUNCHER_I [G -> WSF_EXECUTION create make end] + +inherit + SHARED_EXECUTION_ENVIRONMENT + +feature -- Execution + + launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + nature: like launcher_nature + do + nature := launcher_nature + if nature = Void then + launch_standalone (opts) + elseif nature = nature_standalone then + launch_standalone (opts) + elseif nature = nature_nino then + launch_nino (opts) + elseif nature = nature_cgi then + launch_cgi (opts) + elseif nature = nature_libfcgi then + launch_libfcgi (opts) + else + -- bye bye + (create {EXCEPTIONS}).die (-1) + end + end + +feature {NONE} -- Access + + launcher_nature: detachable READABLE_STRING_8 + -- Initialize the launcher nature + -- either cgi, libfcgi, or nino. + --| We could extend with more connector if needed. + --| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time. + local + p: PATH + ext: detachable READABLE_STRING_32 + do + create p.make_from_string (execution_environment.arguments.command_name) + if attached p.entry as l_entry then + ext := l_entry.extension + end + if ext /= Void then + if ext.same_string (nature_standalone) then + Result := nature_standalone + end + if ext.same_string (nature_nino) then + Result := nature_nino + end + if ext.same_string (nature_cgi) then + Result := nature_cgi + end + if ext.same_string (nature_libfcgi) or else ext.same_string ("fcgi") then + Result := nature_libfcgi + end + end + Result := default_nature + end + +feature {NONE} -- standalone + + nature_standalone: STRING = "standalone" + + launch_standalone (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + launcher: WSF_STANDALONE_SERVICE_LAUNCHER [G] + do + create launcher.make_and_launch (opts) + end + +feature {NONE} -- nino + + nature_nino: STRING = "nino" + + launch_nino (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + launcher: WSF_NINO_SERVICE_LAUNCHER [G] + do + create launcher.make_and_launch (opts) + end + +feature {NONE} -- cgi + + nature_cgi: STRING = "cgi" + + launch_cgi (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + launcher: WSF_CGI_SERVICE_LAUNCHER [G] + do + create launcher.make_and_launch (opts) + end + +feature {NONE} -- libfcgi + + nature_libfcgi: STRING = "libfcgi" + + launch_libfcgi (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + launcher: WSF_LIBFCGI_SERVICE_LAUNCHER [G] + do + create launcher.make_and_launch (opts) + end + +feature -- Default + + default_nature: STRING + do + Result := nature_standalone + end + + +end + + diff --git a/launcher/cgi-safe.ecf b/launcher/cgi-safe.ecf new file mode 100644 index 0000000..678960d --- /dev/null +++ b/launcher/cgi-safe.ecf @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/launcher/default/application_launcher.e b/launcher/default/application_launcher.e new file mode 100644 index 0000000..bb184d0 --- /dev/null +++ b/launcher/default/application_launcher.e @@ -0,0 +1,19 @@ +note + description: "[ + Effective class for APPLICATION_LAUNCHER_I + + You can put modification in this class + ]" + date: "$Date: 2013-06-12 13:55:42 +0200 (mer., 12 juin 2013) $" + revision: "$Revision: 36 $" + +class + APPLICATION_LAUNCHER [G -> WSF_EXECUTION create make end] + +inherit + APPLICATION_LAUNCHER_I [G] + +feature -- Custom + +end + diff --git a/launcher/default/application_launcher_i.e b/launcher/default/application_launcher_i.e new file mode 100644 index 0000000..4d91129 --- /dev/null +++ b/launcher/default/application_launcher_i.e @@ -0,0 +1,26 @@ +note + description: "[ + Specific application launcher + + DO NOT EDIT THIS CLASS + + you can customize APPLICATION_LAUNCHER + ]" + date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $" + revision: "$Revision: 96596 $" + +deferred class + APPLICATION_LAUNCHER_I [G -> WSF_EXECUTION create make end] + +feature -- Execution + + launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + launcher: WSF_DEFAULT_SERVICE_LAUNCHER [G] + do + create launcher.make_and_launch (opts) + end + +end + + diff --git a/launcher/libfcgi-safe.ecf b/launcher/libfcgi-safe.ecf new file mode 100644 index 0000000..2e8fd5b --- /dev/null +++ b/launcher/libfcgi-safe.ecf @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/launcher/libfcgi.ecf b/launcher/libfcgi.ecf new file mode 100644 index 0000000..71a51e6 --- /dev/null +++ b/launcher/libfcgi.ecf @@ -0,0 +1,16 @@ + + + + + + + + + + + diff --git a/examples/demo/src/ewf_roc_server.e b/launcher/roc_cms_launcher.e similarity index 74% rename from examples/demo/src/ewf_roc_server.e rename to launcher/roc_cms_launcher.e index 1bfdcab..e3de748 100644 --- a/examples/demo/src/ewf_roc_server.e +++ b/launcher/roc_cms_launcher.e @@ -1,12 +1,12 @@ note description: "[ - application service + Reusable ROC CMS launcher. ]" date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $" revision: "$Revision: 96596 $" class - EWF_ROC_SERVER + ROC_CMS_LAUNCHER [G -> CMS_EXECUTION create make end] inherit WSF_LAUNCHABLE_SERVICE @@ -37,16 +37,27 @@ feature {NONE} -- Initialization -- Initialize current service. local env: CMS_ENVIRONMENT + l_app_name: detachable READABLE_STRING_32 do Precursor - create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("demo.ini") create env.make_default + l_app_name := optional_application_name + if l_app_name = Void then + l_app_name := env.name + end + create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file (l_app_name + ".ini") initialize_logger (env) end + optional_application_name: detachable READABLE_STRING_32 + -- Optional application name. + --| Redefine if needed. + do + end + feature {NONE} -- Launch operation - launcher: APPLICATION_LAUNCHER [EWF_ROC_SERVER_EXECUTION] + launcher: APPLICATION_LAUNCHER [G] launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) local @@ -70,7 +81,7 @@ feature {NONE} -- Launch operation l_message.append ("%N%N") end else - l_message.append ("The application crash without available information") + l_message.append ("The application crashed without information.") l_message.append ("%N%N") end -- send email shutdown diff --git a/launcher/standalone-safe.ecf b/launcher/standalone-safe.ecf new file mode 100644 index 0000000..092b77a --- /dev/null +++ b/launcher/standalone-safe.ecf @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/launcher/standalone.ecf b/launcher/standalone.ecf new file mode 100644 index 0000000..f9aa378 --- /dev/null +++ b/launcher/standalone.ecf @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/library/persistence/sqlite3/sqlite3-safe.ecf b/library/persistence/sqlite3/sqlite3-safe.ecf index d8b07c3..566217e 100644 --- a/library/persistence/sqlite3/sqlite3-safe.ecf +++ b/library/persistence/sqlite3/sqlite3-safe.ecf @@ -1,32 +1,33 @@ - + + - - + + + - + /old$ /EIFGENs$ /CVS$ /.svn$ - /old$ diff --git a/library/persistence/sqlite3/src/cms_storage_sqlite3.e b/library/persistence/sqlite3/src/cms_storage_sqlite3.e index 27e81f2..4c53138 100644 --- a/library/persistence/sqlite3/src/cms_storage_sqlite3.e +++ b/library/persistence/sqlite3/src/cms_storage_sqlite3.e @@ -75,6 +75,9 @@ feature -- Execution sqlite.begin_transaction (False) end transaction_depth := transaction_depth + 1 + debug ("roc_storage") + print ("# sql_begin_transaction (depth="+ transaction_depth.out +").%N") + end end sql_rollback_transaction @@ -84,6 +87,9 @@ feature -- Execution sqlite.rollback end transaction_depth := transaction_depth - 1 + debug ("roc_storage") + print ("# sql_rollback_transaction (depth="+ transaction_depth.out +").%N") + end end sql_commit_transaction @@ -93,12 +99,18 @@ feature -- Execution sqlite.commit end transaction_depth := transaction_depth - 1 + debug ("roc_storage") + print ("# sql_commit_transaction (depth="+ transaction_depth.out +").%N") + end end sql_post_execution -- Post database execution. -- note: execute after each `sql_query' and `sql_change'. do + debug ("roc_storage") + print ("# sql_post_execution.%N") + end -- FIXME if sqlite.has_error then write_critical_log (generator + ".post_execution Error occurred!") @@ -116,6 +128,9 @@ feature -- Operation local st: SQLITE_QUERY_STATEMENT do + debug ("roc_storage") + print ("> sql_query (" +a_sql_statement + ").%N") + end last_sqlite_result_cursor := Void create st.make (a_sql_statement, sqlite) last_statement := st @@ -129,16 +144,31 @@ feature -- Operation else error_handler.add_custom_error (1, "invalid query", "query compilation failed!") end + debug ("roc_storage") + print ("< sql_query (" +a_sql_statement + ").%N") + end end sql_finalize -- Finalize sql query (i.e destroy previous query statement. do - if attached last_statement as st then - st.dispose + debug ("roc_storage") + print ("> sql_finalize.%N") + end + if attached last_statement as st then + st.cleanup + end + if attached last_sqlite_result_cursor as cur then + if cur.statement /= last_statement then + check should_not_occurs: False end + cur.statement.cleanup + end + last_sqlite_result_cursor := Void end - last_sqlite_result_cursor := Void last_statement := Void + debug ("roc_storage") + print ("< sql_finalize.%N") + end end sql_insert (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) @@ -146,6 +176,9 @@ feature -- Operation local st: SQLITE_INSERT_STATEMENT do + debug ("roc_storage") + print ("> sql_insert (" +a_sql_statement + ").%N") + end last_sqlite_result_cursor := Void create st.make (a_sql_statement, sqlite) last_statement := st @@ -159,6 +192,9 @@ feature -- Operation else error_handler.add_custom_error (1, "invalid query", "query compilation failed!") end + debug ("roc_storage") + print ("< sql_insert (" +a_sql_statement + ").%N") + end end sql_modify (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) @@ -166,6 +202,9 @@ feature -- Operation local st: SQLITE_MODIFY_STATEMENT do + debug ("roc_storage") + print ("> sql_modify (" +a_sql_statement + ").%N") + end last_sqlite_result_cursor := Void create st.make (a_sql_statement, sqlite) last_statement := st @@ -179,6 +218,9 @@ feature -- Operation else error_handler.add_custom_error (1, "invalid query", "query compilation failed!") end + debug ("roc_storage") + print ("< sql_modify (" +a_sql_statement + ").%N") + end end sqlite_arguments (a_params: STRING_TABLE [detachable ANY]): ARRAYED_LIST [SQLITE_BIND_ARG [ANY]] @@ -279,32 +321,14 @@ feature -- Operation feature -- Access --- sql_rows_count: INTEGER --- -- Number of rows for last sql execution. --- do --- if attached last_sqlite_result_cursor as l_cursor then --- -- FIXME: find better solution! --- from --- Result := 1 --- until --- not l_cursor.after --- loop --- Result := Result + 1 --- end --- end --- end - sql_start - -- Set the cursor on first element. + -- . do - -- Already at first position if any ? - if attached last_sqlite_result_cursor as l_cursor then --- l_cursor.start - end + -- sqlite cursor `last_sqlite_result_cursor', already at first position if any. end sql_after: BOOLEAN - -- Are there no more items to iterate over? + -- . do if attached last_sqlite_result_cursor as l_cursor then Result := l_cursor.after @@ -312,7 +336,7 @@ feature -- Access end sql_forth - -- Fetch next row from last sql execution, if any. + -- . do if attached last_sqlite_result_cursor as l_cursor then l_cursor.forth From 782e9397a3a7878378a466ba80926c848c457edc Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 19 Oct 2015 23:33:17 +0200 Subject: [PATCH 12/15] Added missing sql_finalize which is used to cleanup as early as possible the last statement when it is not needed anymore. --- .../cms_node_storage_sql_blog_extension.e | 2 ++ .../blog/persistence/cms_blog_storage_sql.e | 3 +++ .../node/persistence/cms_node_storage_sql.e | 19 +++++++++++++++++-- .../cms_node_storage_sql_page_extension.e | 3 +++ modules/oauth20/cms_oauth_20_module.e | 2 ++ .../persistence/cms_oauth_20_storage_sql.e | 4 ++++ .../persitence/cms_openid_storage_sql.e | 4 +++- src/persistence/core/cms_core_storage_sql_i.e | 7 +++++++ src/persistence/sql/cms_storage_sql_i.e | 3 +++ src/persistence/user/cms_user_storage_sql_i.e | 13 ++++++------- 10 files changed, 50 insertions(+), 10 deletions(-) diff --git a/modules/blog/cms_node_storage_sql_blog_extension.e b/modules/blog/cms_node_storage_sql_blog_extension.e index fefff15..29eef63 100644 --- a/modules/blog/cms_node_storage_sql_blog_extension.e +++ b/modules/blog/cms_node_storage_sql_blog_extension.e @@ -94,6 +94,7 @@ feature -- Persistence -- sql_change (sql_insert_node_data, l_parameters) end end + sql_finalize end end @@ -117,6 +118,7 @@ feature -- Persistence create l_parameters.make (1) l_parameters.put (a_node.id, "nid") sql_modify (sql_delete_node_data, l_parameters) + sql_finalize end end diff --git a/modules/blog/persistence/cms_blog_storage_sql.e b/modules/blog/persistence/cms_blog_storage_sql.e index 0644b48..c804681 100644 --- a/modules/blog/persistence/cms_blog_storage_sql.e +++ b/modules/blog/persistence/cms_blog_storage_sql.e @@ -64,6 +64,7 @@ feature -- Access end sql_forth end + sql_finalize end blogs_limited (a_limit: NATURAL_32; a_offset: NATURAL_32): LIST [CMS_NODE] @@ -90,6 +91,7 @@ feature -- Access end sql_forth end + sql_finalize end blogs_from_user_limited (a_user: CMS_USER; a_limit: NATURAL_32; a_offset: NATURAL_32): LIST [CMS_NODE] @@ -117,6 +119,7 @@ feature -- Access end sql_forth end + sql_finalize end feature {NONE} -- Queries diff --git a/modules/node/persistence/cms_node_storage_sql.e b/modules/node/persistence/cms_node_storage_sql.e index 33707cb..80dcde3 100644 --- a/modules/node/persistence/cms_node_storage_sql.e +++ b/modules/node/persistence/cms_node_storage_sql.e @@ -34,7 +34,6 @@ feature -- Access sql_finalize end - nodes: LIST [CMS_NODE] -- List of nodes. do @@ -54,6 +53,7 @@ feature -- Access end sql_forth end + sql_finalize end node_revisions (a_node: CMS_NODE): LIST [CMS_NODE] @@ -81,6 +81,7 @@ feature -- Access end sql_forth end + sql_finalize end trashed_nodes (a_user: detachable CMS_USER): LIST [CMS_NODE] @@ -110,6 +111,7 @@ feature -- Access end sql_forth end + sql_finalize end recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE] @@ -136,6 +138,7 @@ feature -- Access end sql_forth end + sql_finalize end recent_node_changes_before (a_lower: INTEGER; a_count: INTEGER; a_date: DATE_TIME): LIST [CMS_NODE] @@ -164,6 +167,7 @@ feature -- Access end sql_forth end + sql_finalize end node_by_id (a_id: INTEGER_64): detachable CMS_NODE @@ -252,7 +256,7 @@ feature -- Access end -- if Result = 0 and not has_error then --| include the case a_node = Void -- sql_query (Sql_last_insert_node_revision, Void) --- if sql_rows_count = 1 then +-- if not has_error and not sql_after then -- if sql_item (1) /= Void then -- Result := sql_read_integer_64 (1) -- end @@ -285,6 +289,7 @@ feature -- Access: outline end sql_forth end + sql_finalize end available_parents_for_node (a_node: CMS_NODE): LIST [CMS_NODE] @@ -310,6 +315,7 @@ feature -- Access: outline end sql_forth end + sql_finalize end feature -- Change: Node @@ -339,6 +345,7 @@ feature -- Change: Node l_parameters.put ({CMS_NODE_API}.trashed, "status") l_parameters.put (a_id, "nid") sql_modify (sql_trash_node, l_parameters) + sql_finalize end delete_node_base (a_node: CMS_NODE) @@ -354,10 +361,12 @@ feature -- Change: Node create l_parameters.make (1) l_parameters.put (a_node.id, "nid") sql_modify (sql_delete_node, l_parameters) + sql_finalize -- we remove node_revisions and pages. -- Check: maybe we need a transaction. sql_modify (sql_delete_node_revisions, l_parameters) + sql_finalize if not error_handler.has_error then extended_delete (a_node) @@ -379,6 +388,7 @@ feature -- Change: Node l_parameters.put ({CMS_NODE_API}.not_published, "status") l_parameters.put (a_id, "nid") sql_modify (sql_restore_node, l_parameters) + sql_finalize end @@ -423,6 +433,8 @@ feature {NONE} -- Implementation l_copy_parameters.force (a_node.id, "nid") -- l_copy_parameters.force (l_rev - 1, "revision") sql_insert (sql_copy_node_to_revision, l_copy_parameters) + sql_finalize + if not has_error then a_node.set_revision (l_rev) @@ -431,6 +443,7 @@ feature {NONE} -- Implementation l_parameters.put (a_node.id, "nid") l_parameters.put (a_node.revision, "revision") sql_modify (sql_update_node, l_parameters) + sql_finalize if not error_handler.has_error then a_node.set_modification_date (now) @@ -442,6 +455,8 @@ feature {NONE} -- Implementation l_parameters.put (l_rev, "revision") sql_insert (sql_insert_node, l_parameters) + sql_finalize + if not error_handler.has_error then a_node.set_modification_date (now) a_node.set_id (last_inserted_node_id) diff --git a/modules/node/persistence/cms_node_storage_sql_page_extension.e b/modules/node/persistence/cms_node_storage_sql_page_extension.e index 380ade8..abfe110 100644 --- a/modules/node/persistence/cms_node_storage_sql_page_extension.e +++ b/modules/node/persistence/cms_node_storage_sql_page_extension.e @@ -84,6 +84,7 @@ feature -- Persistence sql_insert (sql_insert_node_data, l_parameters) end end + sql_finalize end end @@ -122,6 +123,7 @@ feature -- Persistence create l_parameters.make (1) l_parameters.put (a_node.id, "nid") sql_modify (sql_delete_node_data, l_parameters) + sql_finalize end end @@ -151,6 +153,7 @@ feature {NONE} -- Implementation check unique_data: n = 0 end end end + sql_finalize ensure accepted_revision: Result /= Void implies Result.revision <= a_node.revision end diff --git a/modules/oauth20/cms_oauth_20_module.e b/modules/oauth20/cms_oauth_20_module.e index a68227f..321f451 100644 --- a/modules/oauth20/cms_oauth_20_module.e +++ b/modules/oauth20/cms_oauth_20_module.e @@ -121,6 +121,7 @@ feature {CMS_API} -- Module management end l_sql_storage.sql_forth end + l_sql_storage.sql_finalize across l_consumers as ic loop if not l_sql_storage.sql_table_exists (ic.item) then if attached l_sql_storage.sql_script_content (api.module_resource_location (Current, (create {PATH}.make_from_string ("scripts")).extended ("oauth2_table.sql.tpl"))) as sql then @@ -131,6 +132,7 @@ feature {CMS_API} -- Module management end end end + l_sql_storage.sql_finalize Precursor {CMS_MODULE}(api) end end diff --git a/modules/oauth20/persistence/cms_oauth_20_storage_sql.e b/modules/oauth20/persistence/cms_oauth_20_storage_sql.e index 610268c..6b6f0b5 100644 --- a/modules/oauth20/persistence/cms_oauth_20_storage_sql.e +++ b/modules/oauth20/persistence/cms_oauth_20_storage_sql.e @@ -134,6 +134,7 @@ feature --Access: Consumers sql_forth end end + sql_finalize end oauth_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER @@ -203,6 +204,7 @@ feature -- Change: User OAuth l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer)) sql_insert (l_string, l_parameters) sql_commit_transaction + sql_finalize end update_user_oauth2 (a_token: READABLE_STRING_GENERAL; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer: READABLE_STRING_GENERAL ) @@ -224,6 +226,7 @@ feature -- Change: User OAuth l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer)) sql_modify (l_string, l_parameters) sql_commit_transaction + sql_finalize end remove_user_oauth2 (a_user: CMS_USER; a_consumer: READABLE_STRING_GENERAL) @@ -243,6 +246,7 @@ feature -- Change: User OAuth l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer)) sql_modify (l_string, l_parameters) sql_commit_transaction + sql_finalize end feature {NONE} -- Implementation OAuth Consumer diff --git a/modules/openid/persitence/cms_openid_storage_sql.e b/modules/openid/persitence/cms_openid_storage_sql.e index 05714f7..f44c975 100644 --- a/modules/openid/persitence/cms_openid_storage_sql.e +++ b/modules/openid/persitence/cms_openid_storage_sql.e @@ -64,9 +64,9 @@ feature -- Access User Outh else check no_more_than_one: False end end + sql_finalize end - feature --Access: Consumers openid_consumers: LIST [STRING] @@ -88,6 +88,7 @@ feature --Access: Consumers sql_forth end end + sql_finalize end openid_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OPENID_CONSUMER @@ -128,6 +129,7 @@ feature -- Change: User OAuth l_parameters.put (create {DATE_TIME}.make_now_utc, "utc_date") sql_insert (Sql_insert_openid, l_parameters) sql_commit_transaction + sql_finalize end feature {NONE} -- Implementation OAuth Consumer diff --git a/src/persistence/core/cms_core_storage_sql_i.e b/src/persistence/core/cms_core_storage_sql_i.e index 8a27dee..d0d234a 100644 --- a/src/persistence/core/cms_core_storage_sql_i.e +++ b/src/persistence/core/cms_core_storage_sql_i.e @@ -38,6 +38,7 @@ feature -- URL aliases end else sql_insert (sql_insert_path_alias, l_parameters) + sql_finalize end end @@ -64,6 +65,7 @@ feature -- URL aliases l_parameters.put (a_alias, "alias") sql_modify (sql_update_path_alias, l_parameters) + sql_finalize end end @@ -80,6 +82,7 @@ feature -- URL aliases create l_parameters.make (1) l_parameters.put (a_alias, "alias") sql_modify (sql_delete_path_alias, l_parameters) + sql_finalize else error_handler.add_custom_error (0, "alias mismatch", "Path alias %"" + a_alias + "%" is not related to source %"" + a_source + "%"!") end @@ -171,6 +174,7 @@ feature -- Logs end l_parameters.put (now, "date") sql_insert (sql_insert_log, l_parameters) + sql_finalize end sql_insert_log: STRING = "INSERT INTO logs (category, level, uid, message, info, link, date) VALUES (:category, :level, :uid, :message, :info, :link, :date);" @@ -198,9 +202,11 @@ feature -- Misc -- already up to date else sql_modify (sql_update_custom_value, l_parameters) + sql_finalize end else sql_insert (sql_insert_custom_value, l_parameters) + sql_finalize end end @@ -219,6 +225,7 @@ feature -- Misc end l_parameters.put (a_name, "name") sql_modify (sql_delete_custom_value, l_parameters) + sql_finalize end custom_value (a_name: READABLE_STRING_GENERAL; a_type: detachable READABLE_STRING_8): detachable READABLE_STRING_32 diff --git a/src/persistence/sql/cms_storage_sql_i.e b/src/persistence/sql/cms_storage_sql_i.e index c183c4d..8b2acef 100644 --- a/src/persistence/sql/cms_storage_sql_i.e +++ b/src/persistence/sql/cms_storage_sql_i.e @@ -207,6 +207,7 @@ feature -- Helper else sql_commit_transaction end + sql_finalize end sql_table_exists (a_table_name: READABLE_STRING_8): BOOLEAN @@ -216,6 +217,7 @@ feature -- Helper sql_query ("SELECT count(*) FROM " + a_table_name + " ;", Void) Result := not has_error -- FIXME: find better solution + sql_finalize reset_error end @@ -227,6 +229,7 @@ feature -- Helper if not has_error then Result := sql_read_integer_64 (1) end + sql_finalize end feature -- Access diff --git a/src/persistence/user/cms_user_storage_sql_i.e b/src/persistence/user/cms_user_storage_sql_i.e index 34304da..2a59b30 100644 --- a/src/persistence/user/cms_user_storage_sql_i.e +++ b/src/persistence/user/cms_user_storage_sql_i.e @@ -275,6 +275,7 @@ feature -- Change: user l_parameters.put (a_user.status, "status") sql_modify (sql_update_user, l_parameters) + sql_finalize if not error_handler.has_error then update_user_roles (a_user) end @@ -402,9 +403,8 @@ feature -- Access: roles and permissions if Result /= Void and not has_error then fill_user_role (Result) end - else - sql_finalize end + sql_finalize end user_role_by_name (a_name: READABLE_STRING_GENERAL): detachable CMS_USER_ROLE @@ -425,9 +425,8 @@ feature -- Access: roles and permissions if Result /= Void and not has_error then fill_user_role (Result) end - else - sql_finalize end + sql_finalize end user_roles_for (a_user: CMS_USER): LIST [CMS_USER_ROLE] @@ -575,6 +574,7 @@ feature -- Change: roles and permissions l_parameters.put (a_user_role.id, "rid") l_parameters.put (a_user_role.name, "name") sql_modify (sql_update_user_role, l_parameters) + sql_finalize end if not a_user_role.permissions.is_empty then -- FIXME: check if this is non set permissions,or none ... @@ -621,16 +621,14 @@ feature -- Change: roles and permissions create l_parameters.make (1) l_parameters.put (a_user_role.name, "name") sql_insert (sql_insert_user_role, l_parameters) + sql_finalize if not error_handler.has_error then a_user_role.set_id (last_inserted_user_role_id) - sql_finalize across a_user_role.permissions as ic loop set_permission_for_role_id (ic.item, a_user_role.id) end - else - sql_finalize end end end @@ -691,6 +689,7 @@ feature -- Change: roles and permissions create l_parameters.make (1) l_parameters.put (a_role.id, "rid") sql_modify (sql_delete_role_permissions_by_role_id, l_parameters) + sql_finalize sql_modify (sql_delete_role_by_id, l_parameters) sql_commit_transaction sql_finalize From 3f4e70b98c58e5a6ee1d6719e41bf306c881fde6 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 20 Oct 2015 11:29:16 +0200 Subject: [PATCH 13/15] Updated roc tools, and associated scripts. Also include Eiffel Store ODBC persistence. --- examples/demo/demo-safe.ecf | 4 ++-- examples/demo/src/demo_cms_execution.e | 2 +- tools/install.bat | 5 +++++ tools/roc/roc_install_command.e | 12 ++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/examples/demo/demo-safe.ecf b/examples/demo/demo-safe.ecf index c61f4c4..218ccb9 100644 --- a/examples/demo/demo-safe.ecf +++ b/examples/demo/demo-safe.ecf @@ -36,8 +36,8 @@ - @@ -52,7 +52,7 @@ - + diff --git a/examples/demo/src/demo_cms_execution.e b/examples/demo/src/demo_cms_execution.e index 9006b56..5dec891 100644 --- a/examples/demo/src/demo_cms_execution.e +++ b/examples/demo/src/demo_cms_execution.e @@ -35,7 +35,7 @@ feature -- CMS storage do a_setup.storage_drivers.force (create {CMS_STORAGE_SQLITE3_BUILDER}.make, "sqlite3") -- a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_MYSQL_BUILDER}.make, "mysql") --- a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_ODBC_BUILDER}.make, "odbc") + a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_ODBC_BUILDER}.make, "odbc") end feature -- CMS modules diff --git a/tools/install.bat b/tools/install.bat index 5770228..fc893ab 100644 --- a/tools/install.bat +++ b/tools/install.bat @@ -4,6 +4,7 @@ set TMP_EXCLUDE=%~dp0.install_ROC-copydir-exclude set COPYCMD= xcopy /EXCLUDE:%TMP_EXCLUDE% /I /E /Y set TMP_DIR=%~dp0.. set SAFE_RMDIR=rd /q/s +set SAFE_RM=del echo EIFGENs > %TMP_EXCLUDE% echo .git >> %TMP_EXCLUDE% @@ -61,6 +62,10 @@ echo Install ROC as CMS ewf %COPYCMD% %TMP_DIR%\modules %TMP_UNSTABLE_DIR%\library\web\cms\modules %COPYCMD% %TMP_DIR%\examples %TMP_UNSTABLE_DIR%\library\web\cms\examples +%COPYCMD% %TMP_DIR%\tools %TMP_UNSTABLE_DIR%\library\web\cms\tools +%SAFE_RM% %TMP_UNSTABLE_DIR%\library\web\cms\tools\install.bat +%SAFE_RM% %TMP_UNSTABLE_DIR%\library\web\cms\tools\safe_md.bat + copy %TMP_DIR%\cms.ecf %TMP_UNSTABLE_DIR%\library\web\cms\cms.ecf copy %TMP_DIR%\cms-safe.ecf %TMP_UNSTABLE_DIR%\library\web\cms\cms-safe.ecf copy %TMP_DIR%\README.md %TMP_UNSTABLE_DIR%\library\web\cms\README.md diff --git a/tools/roc/roc_install_command.e b/tools/roc/roc_install_command.e index df15f07..f73d274 100644 --- a/tools/roc/roc_install_command.e +++ b/tools/roc/roc_install_command.e @@ -170,6 +170,8 @@ feature -- Execution print ("%NCheck the module elements at ") print (l_dest_dir.path.name) print (".%N") + print ("Copied " + directories_count.out + " directories.%N") + print ("Copied " + files_count.out + " files.%N") else print ({STRING_32} "The CMS Application located at " + l_cms_path.name + "does not have the site or modules folders.%N") end @@ -202,9 +204,17 @@ feature -- Execution if not l_dest_dir.exists then l_dest_dir.create_dir end + files_count := 0 + directories_count := -1 copy_directory (l_src_dir, l_dest_dir, True) end + files_count: INTEGER + -- Number of copied files during installation. + + directories_count: INTEGER + -- Number of copied directories during installation. + feature {NONE} -- System/copy files copy_directory (a_src: DIRECTORY; a_dest: DIRECTORY; is_recursive: BOOLEAN) @@ -217,6 +227,7 @@ feature {NONE} -- System/copy files l_file: FILE ut: FILE_UTILITIES do + directories_count := directories_count + 1 across a_src.entries as ic loop @@ -259,6 +270,7 @@ feature {NONE} -- System/copy files a_file.copy_to (l_dest) a_file.close l_dest.close + files_count := files_count + 1 end end end From a84f86d7a295816448f32bc19fc1de72c15b508b Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 20 Oct 2015 18:49:40 +0200 Subject: [PATCH 14/15] Addressed various unicode related issues. Note this is using recent changes from text_filter library. --- .../sqlite3/src/cms_storage_sqlite3.e | 28 ++++++++++++++---- .../handler/role/cms_admin_roles_handler.e | 2 +- .../handler/user/cms_admin_users_handler.e | 2 +- modules/blog/cms_blog.e | 4 +-- modules/blog/handler/blog_user_handler.e | 2 +- modules/node/content/cms_node.e | 4 +-- modules/node/content/cms_partial_node.e | 4 +-- modules/node/content_type/cms_page.e | 4 +-- .../handler/cms_node_type_webform_manager.e | 29 +++++++++++++------ .../node/persistence/cms_node_storage_sql.e | 2 +- src/persistence/sql/cms_storage_sql_i.e | 3 ++ 11 files changed, 58 insertions(+), 26 deletions(-) diff --git a/library/persistence/sqlite3/src/cms_storage_sqlite3.e b/library/persistence/sqlite3/src/cms_storage_sqlite3.e index 4c53138..0bcd73a 100644 --- a/library/persistence/sqlite3/src/cms_storage_sqlite3.e +++ b/library/persistence/sqlite3/src/cms_storage_sqlite3.e @@ -9,17 +9,20 @@ class inherit CMS_STORAGE_SQL redefine - sql_read_date_time, sql_read_integer_32 + sql_read_date_time, sql_read_integer_32, + sql_read_string_32 end CMS_CORE_STORAGE_SQL_I redefine - sql_read_date_time, sql_read_integer_32 + sql_read_date_time, sql_read_integer_32, + sql_read_string_32 end CMS_USER_STORAGE_SQL_I redefine - sql_read_date_time, sql_read_integer_32 + sql_read_date_time, sql_read_integer_32, + sql_read_string_32 end SQLITE_BIND_ARG_MARSHALLER @@ -227,6 +230,7 @@ feature -- Operation local k: READABLE_STRING_GENERAL k8: STRING + utf: UTF_CONVERTER do create Result.make (a_params.count) across @@ -236,11 +240,12 @@ feature -- Operation if k.is_valid_as_string_8 then k8 := k.as_string_8 else - k8 := (create {UTF_CONVERTER}).utf_32_string_to_utf_8_string_8 (k) + k8 := utf.utf_32_string_to_utf_8_string_8 (k) end if attached {DATE_TIME} ic.item as dt then - Result.force (new_binding_argument (date_time_to_string (dt), ":" + k8)) + elseif attached {READABLE_STRING_32} ic.item as s32 then + Result.force (new_binding_argument (utf.utf_32_string_to_utf_8_string_8 (s32), ":" + k8)) else Result.force (new_binding_argument (ic.item, ":" + k8)) end @@ -363,6 +368,19 @@ feature -- Access end end + sql_read_string_32 (a_index: INTEGER): detachable STRING_32 + -- + local + utf: UTF_CONVERTER + do + Result := Precursor (a_index) + if Result = Void then + if attached sql_read_string (a_index) as s8 then + Result := utf.utf_8_string_8_to_string_32 (s8) + end + end + end + sql_read_integer_32 (a_index: INTEGER): INTEGER_32 -- Retrieved value at `a_index' position in `item'. local diff --git a/modules/admin/handler/role/cms_admin_roles_handler.e b/modules/admin/handler/role/cms_admin_roles_handler.e index 229473e..aeedba8 100644 --- a/modules/admin/handler/role/cms_admin_roles_handler.e +++ b/modules/admin/handler/role/cms_admin_roles_handler.e @@ -93,7 +93,7 @@ feature -- HTTP Methods s.append ("") - s.append (u.name) + s.append (html_encoded (u.name)) s.append ("") s.append ("%N") end diff --git a/modules/admin/handler/user/cms_admin_users_handler.e b/modules/admin/handler/user/cms_admin_users_handler.e index d087c6c..4a47833 100644 --- a/modules/admin/handler/user/cms_admin_users_handler.e +++ b/modules/admin/handler/user/cms_admin_users_handler.e @@ -106,7 +106,7 @@ feature -- HTTP Methods s.append ("") - s.append (u.name) + s.append (html_encoded (u.name)) s.append ("") s.append ("%N") end diff --git a/modules/blog/cms_blog.e b/modules/blog/cms_blog.e index 2d2a6d3..78a0d14 100644 --- a/modules/blog/cms_blog.e +++ b/modules/blog/cms_blog.e @@ -50,10 +50,10 @@ feature -- Access feature -- Access: node - summary: detachable READABLE_STRING_8 + summary: detachable READABLE_STRING_32 -- A short summary of the node. - content: detachable READABLE_STRING_8 + content: detachable READABLE_STRING_32 -- Content of the node. format: detachable READABLE_STRING_8 diff --git a/modules/blog/handler/blog_user_handler.e b/modules/blog/handler/blog_user_handler.e index de1997f..8a50809 100644 --- a/modules/blog/handler/blog_user_handler.e +++ b/modules/blog/handler/blog_user_handler.e @@ -123,7 +123,7 @@ feature -- HTML Output do a_output.append ("

Posts from ") if attached user as l_user then - a_output.append (l_user.name) + a_output.append (html_encoded (l_user.name)) else a_output.append ("unknown user") end diff --git a/modules/node/content/cms_node.e b/modules/node/content/cms_node.e index 696d011..41ab55d 100644 --- a/modules/node/content/cms_node.e +++ b/modules/node/content/cms_node.e @@ -103,12 +103,12 @@ feature -- Access -- Full title of the node. -- Required! - summary: detachable READABLE_STRING_8 + summary: detachable READABLE_STRING_32 -- A short summary of the node. deferred end - content: detachable READABLE_STRING_8 + content: detachable READABLE_STRING_32 -- Content of the node. deferred end diff --git a/modules/node/content/cms_partial_node.e b/modules/node/content/cms_partial_node.e index 8ab6aa2..0cba1f6 100644 --- a/modules/node/content/cms_partial_node.e +++ b/modules/node/content/cms_partial_node.e @@ -33,10 +33,10 @@ feature -- Access: code feature -- Access: content - summary: detachable READABLE_STRING_8 + summary: detachable READABLE_STRING_32 -- A short summary of the node. - content: detachable READABLE_STRING_8 + content: detachable READABLE_STRING_32 -- Content of the node. format: detachable READABLE_STRING_8 diff --git a/modules/node/content_type/cms_page.e b/modules/node/content_type/cms_page.e index 5bb3cbd..d90f194 100644 --- a/modules/node/content_type/cms_page.e +++ b/modules/node/content_type/cms_page.e @@ -44,10 +44,10 @@ feature -- Access feature -- Access: content - summary: detachable READABLE_STRING_8 + summary: detachable READABLE_STRING_32 -- A short summary of the node. - content: detachable READABLE_STRING_8 + content: detachable READABLE_STRING_32 -- Content of the node. format: detachable READABLE_STRING_8 diff --git a/modules/node/handler/cms_node_type_webform_manager.e b/modules/node/handler/cms_node_type_webform_manager.e index 33da381..4876844 100644 --- a/modules/node/handler/cms_node_type_webform_manager.e +++ b/modules/node/handler/cms_node_type_webform_manager.e @@ -100,6 +100,7 @@ feature -- Forms ... local ti: WSF_FORM_TEXT_INPUT l_uri: detachable READABLE_STRING_8 + l_iri: detachable READABLE_STRING_32 do -- Path alias create ti.make ("path_alias") @@ -111,7 +112,8 @@ feature -- Forms ... if attached a_node.link as lnk then l_uri := lnk.location else - l_uri := percent_encoder.percent_decoded_string (response.api.location_alias (response.node_api.node_path (a_node))) + l_iri := percent_encoder.percent_decoded_string (response.api.location_alias (response.node_api.node_path (a_node))) + l_uri := l_iri.to_string_8 end ti.set_text_value (l_uri) ti.set_description ("Optionally specify an alternative URL path by which this content can be accessed. For example, type 'about' when writing an about page. Use a relative path or the URL alias won't work.") @@ -151,10 +153,9 @@ feature -- Forms ... end end - update_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: CMS_NODE) local - b,s: detachable READABLE_STRING_8 + b,s: detachable READABLE_STRING_32 f: detachable CONTENT_FORMAT do if attached fd.integer_item ("id") as l_id and then l_id > 0 then @@ -193,7 +194,7 @@ feature -- Forms ... new_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: detachable CMS_NODE): G -- local - b,s: detachable READABLE_STRING_8 + b,s: detachable READABLE_STRING_32 f: detachable CONTENT_FORMAT l_node: detachable like new_node do @@ -304,7 +305,7 @@ feature -- Output s.append ("
") if attached a_node.author as l_author then s.append (" by ") - s.append (l_author.name) + s.append (a_response.html_encoded (l_author.name)) end if attached a_node.modification_date as l_modified then s.append (" (modified: ") @@ -321,9 +322,9 @@ feature -- Output -- if attached a_node.summary as l_summary then -- s.append ("

") -- if attached node_api.cms_api.format (a_node.format) as f then --- s.append (f.formatted_output (l_summary)) +-- append_formatted_output (l_content, f, s) -- else --- s.append (a_response.formats.default_format.formatted_output (l_summary)) +-- append_formatted_output (l_content, a_response.formats.default_format, s) -- end -- s.append ("

") @@ -333,9 +334,9 @@ feature -- Output if attached a_node.content as l_content then s.append ("

") if attached node_api.cms_api.format (a_node.format) as f then - s.append (f.formatted_output (l_content)) + append_formatted_output (l_content, f, s) else - s.append (a_response.formats.default_format.formatted_output (l_content)) + append_formatted_output (l_content, a_response.formats.default_format, s) end s.append ("

") @@ -346,5 +347,15 @@ feature -- Output a_response.set_main_content (s) end + append_formatted_output (a_content: READABLE_STRING_GENERAL; a_format: CONTENT_FORMAT; a_output: STRING_8) + -- Format `a_content' with format `a_format'. + do + if a_content.is_valid_as_string_8 then + a_output.append (a_format.formatted_output (a_content.to_string_8)) + else + a_format.append_formatted_to (a_content, a_output) + end + end + end diff --git a/modules/node/persistence/cms_node_storage_sql.e b/modules/node/persistence/cms_node_storage_sql.e index 80dcde3..2be4789 100644 --- a/modules/node/persistence/cms_node_storage_sql.e +++ b/modules/node/persistence/cms_node_storage_sql.e @@ -575,7 +575,7 @@ feature {NONE} -- Implementation 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 + if attached sql_read_string_32 (6) as l_content then Result.set_content (l_content) end if attached sql_read_string (7) as l_format then diff --git a/src/persistence/sql/cms_storage_sql_i.e b/src/persistence/sql/cms_storage_sql_i.e index 8b2acef..8798e22 100644 --- a/src/persistence/sql/cms_storage_sql_i.e +++ b/src/persistence/sql/cms_storage_sql_i.e @@ -315,11 +315,14 @@ feature -- Access -- Retrieved value at `a_index' position in `item'. local l_item: like sql_item + utf: UTF_CONVERTER do -- FIXME: handle string_32 ! l_item := sql_item (a_index) if attached {READABLE_STRING_32} l_item as l_string then Result := l_string + elseif attached {READABLE_STRING_8} l_item as l_string_8 then + Result := utf.utf_8_string_8_to_string_32 (l_string_8) else if attached sql_read_string (a_index) as s8 then Result := s8.to_string_32 -- FIXME: any escape? From 5b0ab7643472a09f680f675f6b2887836d7bc2b3 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 20 Oct 2015 19:02:04 +0200 Subject: [PATCH 15/15] Fixed more unicode issues, or being more flexible when loading from database. --- modules/blog/handler/blog_handler.e | 4 ++-- src/persistence/sql/cms_storage_sql_i.e | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/blog/handler/blog_handler.e b/modules/blog/handler/blog_handler.e index de30e17..c9038b0 100644 --- a/modules/blog/handler/blog_handler.e +++ b/modules/blog/handler/blog_handler.e @@ -230,9 +230,9 @@ feature -- HTML Output lnk := blog_api.node_api.node_link (n) a_output.append ("

") if attached api.format (n.format) as f then - a_output.append (f.formatted_output (l_summary)) + f.append_formatted_to (l_summary, a_output) else - a_output.append (page.formats.default_format.formatted_output (l_summary)) + page.formats.default_format.append_formatted_to (l_summary, a_output) end a_output.append ("
") a_output.append (page.link ("See more...", lnk.location, Void)) diff --git a/src/persistence/sql/cms_storage_sql_i.e b/src/persistence/sql/cms_storage_sql_i.e index 8798e22..4ddb2f3 100644 --- a/src/persistence/sql/cms_storage_sql_i.e +++ b/src/persistence/sql/cms_storage_sql_i.e @@ -302,6 +302,11 @@ feature -- Access l_item := sql_item (a_index) if attached {READABLE_STRING_8} l_item as l_string then Result := l_string + elseif + attached {READABLE_STRING_32} l_item as l_string_32 and then + l_string_32.is_valid_as_string_8 + then + Result := l_string_32.to_string_8 elseif attached {BOOLEAN} l_item as l_boolean then Result := l_boolean.out elseif attached {BOOLEAN_REF} l_item as l_boolean_ref then