Compare commits
39 Commits
minor_chan
...
storage_sq
| Author | SHA1 | Date | |
|---|---|---|---|
| db6afb6952 | |||
| d23cfbc300 | |||
| 4aa9c1e097 | |||
| a074a57d62 | |||
| bba0364a2c | |||
| 4dcc1b0e04 | |||
| db9e40cec4 | |||
|
|
792880aa7a | ||
|
|
5ad8c680a6 | ||
|
|
e2f02953f4 | ||
|
|
bd26deb6c1 | ||
|
|
a9109ca8f7 | ||
| 09e5dc4032 | |||
| d082326784 | |||
| 51462829c7 | |||
| ba58fcdf75 | |||
|
|
d84f164dbd | ||
|
|
c3d022ce46 | ||
|
|
aac01e093a | ||
|
|
fb62a1bb3e | ||
|
|
6162432d52 | ||
|
|
ebed52ae01 | ||
| b58eeeac26 | |||
|
|
9169bdcd43 | ||
|
|
e36465f86d | ||
| 76190de218 | |||
|
|
0edff7853b | ||
|
|
e20a7af301 | ||
|
|
089b367c95 | ||
|
|
503f2faf08 | ||
|
|
b887c13664 | ||
|
|
bbfe063b5c | ||
|
|
1a4e2935da | ||
|
|
c3a582f85c | ||
| 8bfb66af30 | |||
| 6aad460b11 | |||
|
|
0dc12b82b8 | ||
|
|
8047880c2b | ||
|
|
48283742aa |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
EIFGENs
|
EIFGENs
|
||||||
*.swp
|
*.swp
|
||||||
*.log*
|
*.log*
|
||||||
*.rc
|
*.rc
|
||||||
|
*.bak
|
||||||
@@ -25,7 +25,10 @@ The goal of the library is to provide the following features.
|
|||||||
- doc -- Documentation.
|
- doc -- Documentation.
|
||||||
|
|
||||||
**Documentation**
|
**Documentation**
|
||||||
>[CMS design](https://github.com/EiffelWebFramework/ROC).
|
|
||||||
>[CMS concepts](https://github.com/EiffelWebFramework/ROC).
|
>[CMS concepts](/doc/concepts.md).
|
||||||
|
|
||||||
|
>[CMS design](/doc/design.md).
|
||||||
|
|
||||||
|
>[CMS tutorial](/doc/tutorial.md).
|
||||||
|
|
||||||
|
|||||||
15
cms-safe.ecf
15
cms-safe.ecf
@@ -2,26 +2,25 @@
|
|||||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
|
||||||
<target name="cms">
|
<target name="cms">
|
||||||
<root all_classes="true"/>
|
<root all_classes="true"/>
|
||||||
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||||
</option>
|
</option>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
|
<library name="config" location=".\library\configuration\config-safe.ecf"/>
|
||||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
||||||
|
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||||
|
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
||||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||||
|
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
|
||||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
||||||
<library name="layout" location=".\library\layout\layout-safe.ecf"/>
|
<library name="layout" location=".\library\layout\layout-safe.ecf"/>
|
||||||
<library name="model" location=".\library\model\cms_model-safe.ecf" readonly="false"/>
|
<library name="model" location=".\library\model\cms_model-safe.ecf" readonly="false"/>
|
||||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf" readonly="false"/>
|
|
||||||
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
|
|
||||||
|
|
||||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
|
||||||
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
|
|
||||||
<library name="persistence_mysql" location=".\library\persistence\implementation\mysql\persistence_mysql-safe.ecf" readonly="false"/>
|
|
||||||
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/>
|
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/>
|
||||||
|
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
|
||||||
|
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||||
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
||||||
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf" readonly="false"/>
|
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf" readonly="false"/>
|
||||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
|
||||||
<cluster name="src" location=".\library\src\" recursive="true">
|
<cluster name="src" location=".\library\src\" recursive="true">
|
||||||
<file_rule>
|
<file_rule>
|
||||||
<exclude>/EIFGENs$</exclude>
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
|||||||
33
cms.ecf
Normal file
33
cms.ecf
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
|
||||||
|
<target name="cms">
|
||||||
|
<root all_classes="true"/>
|
||||||
|
<option warning="true" full_class_checking="false" void_safety="none" syntax="transitional">
|
||||||
|
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||||
|
</option>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
|
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
|
||||||
|
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf" readonly="false"/>
|
||||||
|
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
||||||
|
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
|
||||||
|
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization.ecf" readonly="false"/>
|
||||||
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||||
|
<library name="config" location=".\library\configuration\config.ecf"/>
|
||||||
|
<library name="layout" location=".\library\layout\layout.ecf"/>
|
||||||
|
<library name="model" location=".\library\model\cms_model.ecf" readonly="false"/>
|
||||||
|
<library name="persistence_mysql" location=".\library\persistence\implementation\mysql\persistence_mysql.ecf" readonly="false"/>
|
||||||
|
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty.ecf" readonly="false"/>
|
||||||
|
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter.ecf"/>
|
||||||
|
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||||
|
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/>
|
||||||
|
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension.ecf" readonly="false"/>
|
||||||
|
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html.ecf" readonly="false"/>
|
||||||
|
<cluster name="src" location=".\library\src\" recursive="true">
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/CVS$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
</cluster>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
93
doc/concepts.md
Normal file
93
doc/concepts.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
CMS Concepts
|
||||||
|
============
|
||||||
|
>Current implemented concepts
|
||||||
|
|
||||||
|
##### Table of Contents
|
||||||
|
|
||||||
|
1. [**Theme**](#theme)
|
||||||
|
2. [**Regions**](#regions)
|
||||||
|
- [**Default Page Layout**](#page_layout)
|
||||||
|
- [**Regions Holds blocks**](#regions_blocks)
|
||||||
|
3. [**Blocks**](#blocks)
|
||||||
|
4. [**Modules**](#modules)
|
||||||
|
5. [**Hooks**](#hooks)
|
||||||
|
|
||||||
|
|
||||||
|
<a name="theme"/>
|
||||||
|
Theme
|
||||||
|
-----
|
||||||
|
In a CMS , a theme is a collection of templates files (HTML, CSS, Images, etc ) that determine how a CMS web site looks. The goal of a theme is to let you change the look and feel of the site.
|
||||||
|
Eiffel CMS is inspired by Drupal, and use the same default region names as default drupal theme.
|
||||||
|
|
||||||
|
#### Important Classes
|
||||||
|
|
||||||
|
* [CMS_THEME] (/library/src/theme/cms_theme.e): Abstraction defining the interface of a CMS theme.
|
||||||
|
* [SMARTY_CMS_THEME] (/library/src/theme/smarty_theme/smarty_cms_theme.e): Theme implemented using the [Eiffel Smarty library] (https://github.com/eiffelhub/template-smarty).
|
||||||
|
* [CMS_TEMPLATE] (/library/src/theme/cms_template.e): Template Abstraction that contains theme, variables needed by template when rendering page as html. At the moment there is only one implementation SMARTY_CMS_PAGE_TEMPLATE. At the moment there is only one implementation [SMARTY_CMS_PAGE_TEMPLATE] (/library/src/theme/smarty_theme/smarty_cms_page_template.e).
|
||||||
|
|
||||||
|
<a name="regions"/>
|
||||||
|
Regions
|
||||||
|
-------
|
||||||
|
The layout of a CMS web page has predefined area called **regions**. The Eiffel CMS uses the same default regions as Drupal, so let's see them in the following image.
|
||||||
|
|
||||||
|
<a name="page_layout"/>
|
||||||
|

|
||||||
|
|
||||||
|
```
|
||||||
|
regions[page_top] = Top
|
||||||
|
regions[header] = Header
|
||||||
|
regions[content] = Content
|
||||||
|
regions[highlighted] = Highlighted
|
||||||
|
regions[help] = Help
|
||||||
|
regions[footer] = Footer
|
||||||
|
regions[first_sidebar] = first sidebar
|
||||||
|
regions[second_sidebar] = second sidebar
|
||||||
|
regions[page_bottom] = Bottom
|
||||||
|
```
|
||||||
|
<a name="regions_blocks"/>
|
||||||
|
**A Region holds blocks**
|
||||||
|
|
||||||
|
**What goes inside regions?**
|
||||||
|
Generally, regions hold smaller piece of content called blocks. Blocks hold chunks of content, like the user login form, navigation menu or the information for the footer.
|
||||||
|
|
||||||
|
Regions are defined in a configuration file theme.info.
|
||||||
|
|
||||||
|
|
||||||
|
<a name="blocks"/>
|
||||||
|
CMS_BLOCK
|
||||||
|
---------
|
||||||
|
**What is a cms block?**
|
||||||
|
Blocks are chunk of content that can be created to display whatever you want, and then can be placed in various resgions in your template (theme) layout.
|
||||||
|
|
||||||
|
#### Important Classes
|
||||||
|
|
||||||
|
* [CMS_BLOCK] (/library/src/kernel/content/cms_block.e): The deferred class CMS_BLOCK provides an abstraction to describe content to be placed inside Regions.
|
||||||
|
* [CMS_CONTENT_BLOCK] (/library/src/kernel/content/cms_content_block.e): The class CMS_CONTENT_BLOCK describe how to provide generic content.
|
||||||
|
* [CMS_MENU_BLOCK](/library/src/kernel/content/cms_menu_block.e): The class CMS_MENU_BLOCK describe how to provides a menu of navigational links.
|
||||||
|
* [CMS_SMARTY_TEMPLATE_BLOCK] (/library/src/kernel/content/cms_smarty_templateblock.e) The class CMS_SMARTY_TEMPLATE_BLOCK describe how to use a CMS block with smarty template file content.
|
||||||
|
|
||||||
|
|
||||||
|
<a name="modules"/>
|
||||||
|
CMS_MODULES
|
||||||
|
-----------
|
||||||
|
**What is a cms module?**
|
||||||
|
Modules are piece of code that adds one or more features to your web site.
|
||||||
|
Modules can be plugged and combined to provide a web site customized to your needs. There are modules for many purposes, for example Administratiton, Basic Authentication, etc.
|
||||||
|
|
||||||
|
#### Important Classes
|
||||||
|
* [CMS_MODULE] (/library/src/modules/cms_module.e): The deferred class CMS_MODULE provides an abstraction to describe a generic module that add features to your web site.
|
||||||
|
* [CMS_RESPONSE](/library/src/service/response/cms_response.e). The deferred class CMS_RESPONSE provide an abstraction to builds the content to get process to render the output.
|
||||||
|
|
||||||
|
|
||||||
|
<a name="hooks">
|
||||||
|
CMS_HOOK
|
||||||
|
--------
|
||||||
|
Hooks is a mechanism which provide a way for modules to interact with each other and extending blocks of the current CMS.
|
||||||
|
|
||||||
|
* [CMS_HOOK] (/library/src/hooks/cms_hook.e): The deferred class CMS_HOOK is a marker interface for CMS Hook
|
||||||
|
* [CMS_HOOK_AUTO_REGISTER] (/library/src/hooks/cms_hook_auto_register.e): The deferred class provides an abstraction that when inheriting from this class, the declared hooks are automatically registered, otherwise, each descendant has to add it to the cms service itself.
|
||||||
|
* [CMS_HOOK_BLOCK](/library/src/hooks/cms_hook_block.e): The class CMS_HOOK_BLOCK describe a hook providing a way to alter a generic block.
|
||||||
|
* [CMS_HOOK_FORM_ALTER](/library/src/hooks/cms_hook_form_alter.e): The class CMS_HOOK_FORM_ATLER describe a hook providing a way to alter a form.
|
||||||
|
* [CMS_HOOK_MENU_ALTER](/library/src/hooks/cms_hook_menu_alter.e): The class CMS_HOOK_MENU_ATLER describe a hook providing a way to alter a menu.
|
||||||
|
* [CMS_HOOK_MENU_SYSTEM_ALTER](/library/src/hooks/cms_hook_menu_system_alter.e): The class CMS_HOOK_MENU_SYSTEM_ALTER describe a hook providing a way to alter the CMS menu system.
|
||||||
|
* [CMS_HOOK_VALUE_TABLE_ALTER](/library/src/hooks/cms_hook_value_table_alter.e):: The class CMS_HOOK_VALUE_TABLE_ALTER describe a hook providing a way to alter the value table for a response.
|
||||||
121
doc/tutorial.md
Normal file
121
doc/tutorial.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
CMS Tutorial
|
||||||
|
============
|
||||||
|
[Work in progress]
|
||||||
|
|
||||||
|
##### Table of Contents
|
||||||
|
[Getting Started](#init)
|
||||||
|
[Building your module](#module)
|
||||||
|
[Lifecycle](#cycle)
|
||||||
|
|
||||||
|
|
||||||
|
<a name="init"/>
|
||||||
|
Getting Started
|
||||||
|
-------------
|
||||||
|
|
||||||
|
|
||||||
|
<a name="module"/>
|
||||||
|
Building your own module
|
||||||
|
------------------------
|
||||||
|
A [Module](/doc/concepts.md#modules) as we already describe it, enable us to add functionallity based on your needs.
|
||||||
|
|
||||||
|
Here we will describe the basics steps to write your own modules.
|
||||||
|
|
||||||
|
* The first thing to do is inherit from the class [CMS_MODULE] () and redefine the register_hooks (2) feature.
|
||||||
|
* Implement (via inheritance) the needed [Hooks] (/doc/concepts.md#hooks).
|
||||||
|
* Define the module API through route definition. (1)
|
||||||
|
* Define the list of block to be handle by the current module (3).
|
||||||
|
* Render the block (4) (could be defined in Eiffel itself or using a template file (smarty)).
|
||||||
|
* API implementation (5).
|
||||||
|
|
||||||
|
```
|
||||||
|
class MY_NEW_MODULE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
|
||||||
|
CMS_MODULE
|
||||||
|
redefine
|
||||||
|
register_hooks
|
||||||
|
end
|
||||||
|
|
||||||
|
CMS_HOOK_BLOCK
|
||||||
|
|
||||||
|
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||||
|
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make
|
||||||
|
-- Create current module
|
||||||
|
do
|
||||||
|
name := "new module"
|
||||||
|
version := "1.0"
|
||||||
|
description := "Eiffel new module"
|
||||||
|
package := "example"
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access: router
|
||||||
|
|
||||||
|
router (a_api: CMS_API): WSF_ROUTER
|
||||||
|
-- (1) Node router.
|
||||||
|
do
|
||||||
|
create Result.make (1)
|
||||||
|
Result.handle_with_request_methods ("/demo", create {WSF_URI_AGENT_HANDLER}.make (agent handle_demo (a_api, ?, ?)), Result.methods_head_get)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Hooks
|
||||||
|
|
||||||
|
register_hooks (a_response: CMS_RESPONSE)
|
||||||
|
do
|
||||||
|
-- (2)
|
||||||
|
a_response.subscribe_to_menu_system_alter_hook (Current)
|
||||||
|
a_response.subscribe_to_block_hook (Current)
|
||||||
|
end
|
||||||
|
|
||||||
|
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||||
|
do
|
||||||
|
-- (3) List of block names, managed by current object.
|
||||||
|
end
|
||||||
|
|
||||||
|
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||||
|
do
|
||||||
|
-- (4) Get block object identified by `a_block_id' and associate with `a_response'.
|
||||||
|
end
|
||||||
|
|
||||||
|
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
|
||||||
|
local
|
||||||
|
lnk: CMS_LOCAL_LINK
|
||||||
|
do
|
||||||
|
create lnk.make ("Demo", "/demo/")
|
||||||
|
a_menu_system.primary_menu.extend (lnk)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Handler
|
||||||
|
|
||||||
|
handle_demo (a_api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE;)
|
||||||
|
local
|
||||||
|
r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
|
||||||
|
do
|
||||||
|
-- (5)
|
||||||
|
create r.make (req, res, a_api)
|
||||||
|
r.set_main_content ("NODE module does not yet implement %"" + req.path_info + "%" ...")
|
||||||
|
r.add_error_message ("NODE Module: not yet implemented")
|
||||||
|
r.execute
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="cycle"/>
|
||||||
|
Lifecycle
|
||||||
|
---------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -9,10 +9,13 @@
|
|||||||
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
||||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||||
</option>
|
</option>
|
||||||
|
<setting name="concurrency" value="none"/>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
<library name="cms" location="..\..\cms-safe.ecf" readonly="false"/>
|
<library name="cms" location="..\..\cms-safe.ecf" readonly="false"/>
|
||||||
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
|
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
|
||||||
<library name="layout" location="..\..\library\layout\layout-safe.ecf" readonly="false"/>
|
<library name="layout" location="..\..\library\layout\layout-safe.ecf" readonly="false"/>
|
||||||
|
<library name="persistence_mysql" location="..\..\library\persistence\implementation\mysql\persistence_mysql-safe.ecf" readonly="false"/>
|
||||||
|
<library name="persistence_sqlite" location="..\..\library\persistence\implementation\sqlite\persistence_sqlite-safe.ecf" readonly="false"/>
|
||||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||||
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
||||||
</target>
|
</target>
|
||||||
@@ -26,6 +29,7 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="demo_nino" extends="common">
|
<target name="demo_nino" extends="common">
|
||||||
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
|
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
|
||||||
|
<setting name="concurrency" value="none"/>
|
||||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||||
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
|
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
|
||||||
<cluster name="src" location=".\src\" recursive="true"/>
|
<cluster name="src" location=".\src\" recursive="true"/>
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
{
|
{
|
||||||
"database": {
|
"database": {
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"driver": "MySQL",
|
"driver": "sqlite",
|
||||||
|
"environment": "sqlite_development"
|
||||||
|
},
|
||||||
|
"olddatasource": {
|
||||||
|
"driver": "null",
|
||||||
"environment": "development"
|
"environment": "development"
|
||||||
},
|
},
|
||||||
"environments": {
|
"environments": {
|
||||||
|
"sqlite_development": {
|
||||||
|
"connection_string":"Server=localhost;Port=3306;Database=site/cms_lite.db;Uid=root;Pwd=;"
|
||||||
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;"
|
"connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;"
|
||||||
},
|
},
|
||||||
@@ -29,4 +36,4 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
engine=smarty
|
[layout]
|
||||||
site.name=EWF Web CMS
|
root-dir=site/www
|
||||||
site.email=your@email.com
|
themes-dir=site/www/themes
|
||||||
var-dir=var
|
|
||||||
files-dir=files
|
[site]
|
||||||
|
name=Eiffel CMS
|
||||||
|
email=your@email.com
|
||||||
theme=bootstrap
|
theme=bootstrap
|
||||||
|
|
||||||
|
[misc]
|
||||||
|
smtp=localhost
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ note
|
|||||||
description: "[
|
description: "[
|
||||||
application service
|
application service
|
||||||
]"
|
]"
|
||||||
date: "$Date$"
|
date: "$Date: 2014-11-20 15:03:29 +0100 (jeu., 20 nov. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96138 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
EWF_ROC_SERVER
|
EWF_ROC_SERVER
|
||||||
@@ -101,7 +101,7 @@ feature {NONE} -- Launch operation
|
|||||||
|
|
||||||
feature -- CMS Initialization
|
feature -- CMS Initialization
|
||||||
|
|
||||||
cms_setup: CMS_CUSTOM_SETUP
|
cms_setup: CMS_DEFAULT_SETUP
|
||||||
do
|
do
|
||||||
if attached separate_character_option_value ('d') as l_dir then
|
if attached separate_character_option_value ('d') as l_dir then
|
||||||
log.write_debug (generator + ".cms_setup using a command line argument -d " + l_dir )
|
log.write_debug (generator + ".cms_setup using a command line argument -d " + l_dir )
|
||||||
@@ -135,11 +135,11 @@ feature -- CMS setup
|
|||||||
do
|
do
|
||||||
create {BASIC_AUTH_MODULE} m.make
|
create {BASIC_AUTH_MODULE} m.make
|
||||||
m.enable
|
m.enable
|
||||||
a_setup.modules.extend (m)
|
a_setup.register_module (m)
|
||||||
|
|
||||||
create {CMS_DEMO_MODULE} m.make
|
create {CMS_DEMO_MODULE} m.make
|
||||||
m.enable
|
m.enable
|
||||||
a_setup.modules.extend (m)
|
a_setup.register_module (m)
|
||||||
end
|
end
|
||||||
|
|
||||||
setup_storage (a_setup: CMS_SETUP)
|
setup_storage (a_setup: CMS_SETUP)
|
||||||
@@ -147,6 +147,9 @@ feature -- CMS setup
|
|||||||
debug ("refactor_fixme")
|
debug ("refactor_fixme")
|
||||||
to_implement ("To implement custom storage")
|
to_implement ("To implement custom storage")
|
||||||
end
|
end
|
||||||
|
a_setup.storage_drivers.force (create {CMS_STORAGE_MYSQL_BUILDER}.make, "mysql")
|
||||||
|
a_setup.storage_drivers.force (create {CMS_STORAGE_SQLITE_BUILDER}.make, "sqlite")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
16
library/configuration/config-safe.ecf
Normal file
16
library/configuration/config-safe.ecf
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="config" uuid="A3762109-D650-40A1-B55A-7D236A17903F" library_target="config">
|
||||||
|
<target name="config">
|
||||||
|
<root all_classes="true"/>
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/.git$</exclude>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
|
||||||
|
</option>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf"/>
|
||||||
|
<cluster name="src" location=".\src\" recursive="true"/>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
16
library/configuration/config.ecf
Normal file
16
library/configuration/config.ecf
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="config" uuid="A3762109-D650-40A1-B55A-7D236A17903F" library_target="config">
|
||||||
|
<target name="config">
|
||||||
|
<root all_classes="true"/>
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/.git$</exclude>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
<option warning="true" full_class_checking="true" is_attached_by_default="false" void_safety="none" syntax="standard">
|
||||||
|
</option>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf"/>
|
||||||
|
<cluster name="src" location=".\src\" recursive="true"/>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
10
library/configuration/license.lic
Normal file
10
library/configuration/license.lic
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
${NOTE_KEYWORD}
|
||||||
|
copyright: "2011-${YEAR}, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
121
library/configuration/src/config_reader.e
Normal file
121
library/configuration/src/config_reader.e
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CONFIG_READER}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date: 2014-12-18 16:37:11 +0100 (jeu., 18 déc. 2014) $"
|
||||||
|
revision: "$Revision: 96383 $"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CONFIG_READER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
SHARED_EXECUTION_ENVIRONMENT
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
has_item (k: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- Has item associated with key `k'?
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
has_error: BOOLEAN
|
||||||
|
-- Has error?
|
||||||
|
--| Syntax error, source not found, ...
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Query
|
||||||
|
|
||||||
|
resolved_text_item (k: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- String item associated with key `k' and expanded to resolved variables ${varname}.
|
||||||
|
do
|
||||||
|
if attached text_item (k) as s then
|
||||||
|
Result := resolved_expression (s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
text_item (k: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- String item associated with key `k'.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
integer_item (k: READABLE_STRING_GENERAL): INTEGER
|
||||||
|
-- Integer item associated with key `k'.
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
not has_item (k) implies Result = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
resolved_items: detachable STRING_TABLE [READABLE_STRING_32]
|
||||||
|
-- Resolved items indexed by expression.
|
||||||
|
|
||||||
|
resolved_expression (exp: READABLE_STRING_GENERAL): STRING_32
|
||||||
|
-- Resolved `exp' using `Current' or else environment variables.
|
||||||
|
local
|
||||||
|
i,n,b,e: INTEGER
|
||||||
|
k: detachable READABLE_STRING_GENERAL
|
||||||
|
c: CHARACTER_32
|
||||||
|
l_resolved_items: like resolved_items
|
||||||
|
l_text: detachable READABLE_STRING_GENERAL
|
||||||
|
do
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := exp.count
|
||||||
|
create Result.make (n)
|
||||||
|
until
|
||||||
|
i > n
|
||||||
|
loop
|
||||||
|
c := exp[i]
|
||||||
|
if i + 1 < n and then c = '$' and then exp[i+1] = '{' then
|
||||||
|
b := i + 2
|
||||||
|
e := exp.index_of ('}', b) - 1
|
||||||
|
if e > 0 then
|
||||||
|
k := exp.substring (b, e)
|
||||||
|
l_text := Void
|
||||||
|
l_resolved_items := resolved_items
|
||||||
|
if
|
||||||
|
l_resolved_items /= Void and then
|
||||||
|
attached l_resolved_items.item (k) as s
|
||||||
|
then
|
||||||
|
-- Already resolved, reuse value.
|
||||||
|
l_text := s
|
||||||
|
elseif attached text_item (k) as s then
|
||||||
|
-- has such item
|
||||||
|
l_text := s
|
||||||
|
elseif attached execution_environment.item (k) as v then
|
||||||
|
-- Or from environment
|
||||||
|
l_text := v
|
||||||
|
else
|
||||||
|
l_text := exp.substring (i, e + 1)
|
||||||
|
end
|
||||||
|
i := e + 1
|
||||||
|
Result.append_string_general (l_text)
|
||||||
|
else
|
||||||
|
Result.extend (c)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result.extend (c)
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Duplication
|
||||||
|
|
||||||
|
sub_config (k: READABLE_STRING_GENERAL): detachable CONFIG_READER
|
||||||
|
-- Configuration representing a subset of Current for key `k'.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
|
end
|
||||||
463
library/configuration/src/ini_config.e
Normal file
463
library/configuration/src/ini_config.e
Normal file
@@ -0,0 +1,463 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Object parsing a .ini file.
|
||||||
|
|
||||||
|
Lines starting by '#', or ';', or "--" are comments
|
||||||
|
Section are declared using brackets "[section_name]"
|
||||||
|
Values are declared as "key = value"
|
||||||
|
List values are declared as multiple lines "key[] = value"
|
||||||
|
example:
|
||||||
|
--------------------
|
||||||
|
[first_section]
|
||||||
|
one = abc
|
||||||
|
|
||||||
|
[second_section]
|
||||||
|
two = def
|
||||||
|
lst[] = a
|
||||||
|
lst[] = b
|
||||||
|
lst[] = c
|
||||||
|
|
||||||
|
[third_section]
|
||||||
|
three = ghi
|
||||||
|
table[a] = foo
|
||||||
|
table[b] = bar
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Values are accessible from `items' or by section from `sections'
|
||||||
|
`item' has smart support for '.'
|
||||||
|
|
||||||
|
item ("one") -> abc
|
||||||
|
item ("two") -> def
|
||||||
|
item ("second_section.two") -> def
|
||||||
|
item ("table[b]") -> foo
|
||||||
|
item ("table.b") -> foo
|
||||||
|
item ("third_section.table[b]") -> foo
|
||||||
|
item ("third_section.table.b") -> foo
|
||||||
|
|
||||||
|
notes:
|
||||||
|
it is considered that the .ini file is utf-8 encoded
|
||||||
|
keys are unicode string
|
||||||
|
values are stored UTF-8 string, but one can use unicode_string_item to convert to STRING_32
|
||||||
|
|
||||||
|
Additional features:
|
||||||
|
- Include other files:
|
||||||
|
@include=file-to-include
|
||||||
|
|
||||||
|
]"
|
||||||
|
date: "$Date: 2014-12-18 16:37:11 +0100 (jeu., 18 déc. 2014) $"
|
||||||
|
revision: "$Revision: 96383 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
INI_CONFIG
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CONFIG_READER
|
||||||
|
|
||||||
|
TABLE_ITERABLE [ANY, READABLE_STRING_GENERAL]
|
||||||
|
|
||||||
|
SHARED_EXECUTION_ENVIRONMENT
|
||||||
|
|
||||||
|
create
|
||||||
|
make_from_file,
|
||||||
|
make_from_string,
|
||||||
|
make_from_items
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make_from_file (p: PATH)
|
||||||
|
do
|
||||||
|
initialize
|
||||||
|
parse_file (p)
|
||||||
|
end
|
||||||
|
|
||||||
|
make_from_string (a_content: STRING_8)
|
||||||
|
do
|
||||||
|
initialize
|
||||||
|
parse_content (a_content)
|
||||||
|
end
|
||||||
|
|
||||||
|
make_from_items (a_items: like items)
|
||||||
|
do
|
||||||
|
initialize
|
||||||
|
across
|
||||||
|
a_items as ic
|
||||||
|
loop
|
||||||
|
items.force (ic.item, ic.key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
initialize
|
||||||
|
-- Initialize data.
|
||||||
|
do
|
||||||
|
associated_path := Void
|
||||||
|
create utf
|
||||||
|
create items.make (0)
|
||||||
|
create sections.make (0)
|
||||||
|
end
|
||||||
|
|
||||||
|
reset
|
||||||
|
-- Reset internal data.
|
||||||
|
do
|
||||||
|
has_error := False
|
||||||
|
items.wipe_out
|
||||||
|
sections.wipe_out
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
has_item (k: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- Has item associated with key `k'?
|
||||||
|
do
|
||||||
|
Result := item (k) /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
has_error: BOOLEAN
|
||||||
|
-- Has error?
|
||||||
|
--| Syntax error, source not found, ...
|
||||||
|
|
||||||
|
feature -- Access: Config Reader
|
||||||
|
|
||||||
|
text_item (k: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- String item associated with key `k'.
|
||||||
|
local
|
||||||
|
obj: like item
|
||||||
|
do
|
||||||
|
obj := item (k)
|
||||||
|
if attached {READABLE_STRING_32} obj as s32 then
|
||||||
|
Result := s32
|
||||||
|
elseif attached {READABLE_STRING_8} obj as s then
|
||||||
|
Result := utf.utf_8_string_8_to_escaped_string_32 (s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
integer_item (k: READABLE_STRING_GENERAL): INTEGER
|
||||||
|
-- Integer item associated with key `k'.
|
||||||
|
do
|
||||||
|
if attached {READABLE_STRING_GENERAL} item (k) as s then
|
||||||
|
Result := s.to_integer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
associated_path: detachable PATH
|
||||||
|
-- If current was built from a filename, return this path.
|
||||||
|
|
||||||
|
feature -- Duplication
|
||||||
|
|
||||||
|
sub_config (k: READABLE_STRING_GENERAL): detachable CONFIG_READER
|
||||||
|
-- Configuration representing a subset of Current for key `k'.
|
||||||
|
do
|
||||||
|
if attached sections.item (k) as l_items then
|
||||||
|
create {INI_CONFIG} Result.make_from_items (l_items)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
item (k: READABLE_STRING_GENERAL): detachable ANY
|
||||||
|
-- Value associated with key `k'.
|
||||||
|
local
|
||||||
|
i: INTEGER
|
||||||
|
s,sk: detachable READABLE_STRING_GENERAL
|
||||||
|
do
|
||||||
|
-- Try first directly in values
|
||||||
|
Result := items.item (k)
|
||||||
|
if Result = Void then
|
||||||
|
--| If there is a dot
|
||||||
|
--| this could be
|
||||||
|
--| section.variable
|
||||||
|
--| variable.name or variable[name]
|
||||||
|
i := k.index_of ('.', 1)
|
||||||
|
if i > 0 then
|
||||||
|
s := k.head (i - 1)
|
||||||
|
-- then search first in section
|
||||||
|
if attached sections.item (s) as l_section then
|
||||||
|
sk := k.substring (i + 1, k.count)
|
||||||
|
Result := l_section.item (sk)
|
||||||
|
if Result = Void then
|
||||||
|
Result := item_from_values (l_section, sk)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if Result = Void then
|
||||||
|
i := k.index_of ('.', i + 1)
|
||||||
|
if i > 0 then
|
||||||
|
-- There is another dot .. could be due to include
|
||||||
|
across
|
||||||
|
sections as ic
|
||||||
|
until
|
||||||
|
Result /= Void
|
||||||
|
loop
|
||||||
|
s := ic.key
|
||||||
|
-- If has other dot, this may be in sub sections ...
|
||||||
|
if s.has ('.') and then k.starts_with (s) and then k[s.count + 1] = '.' then
|
||||||
|
if attached sections.item (s) as l_section then
|
||||||
|
sk := k.substring (s.count + 2, k.count)
|
||||||
|
Result := l_section.item (sk)
|
||||||
|
if Result = Void then
|
||||||
|
Result := item_from_values (l_section, sk)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if Result = Void then
|
||||||
|
-- otherwise in values object.
|
||||||
|
Result := item_from_values (items, k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
--| Could be
|
||||||
|
--| variable[name]
|
||||||
|
Result := item_from_values (items, k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
items: STRING_TABLE [ANY]
|
||||||
|
|
||||||
|
sections: STRING_TABLE [like items]
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
new_cursor: TABLE_ITERATION_CURSOR [ANY, READABLE_STRING_GENERAL]
|
||||||
|
-- Fresh cursor associated with current structure
|
||||||
|
do
|
||||||
|
Result := items.new_cursor
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
item_from_values (a_values: STRING_TABLE [ANY]; k: READABLE_STRING_GENERAL): detachable ANY
|
||||||
|
local
|
||||||
|
i,j: INTEGER
|
||||||
|
s: READABLE_STRING_GENERAL
|
||||||
|
do
|
||||||
|
Result := a_values.item (k)
|
||||||
|
if Result = Void then
|
||||||
|
i := k.index_of ('.', 1)
|
||||||
|
if i > 0 then
|
||||||
|
s := k.head (i - 1)
|
||||||
|
if attached {STRING_TABLE [ANY]} a_values.item (s) as l_table then
|
||||||
|
Result := l_table.item (k.substring (i + 1, k.count))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
i := k.index_of ('[', 1)
|
||||||
|
if i > 0 then
|
||||||
|
j := k.index_of (']', i + 1)
|
||||||
|
if j = k.count then
|
||||||
|
s := k.head (i - 1)
|
||||||
|
if attached {STRING_TABLE [ANY]} a_values.item (s) as l_table then
|
||||||
|
Result := l_table.item (k.substring (i + 1, j - 1))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
record_in_section (obj: ANY; k: READABLE_STRING_GENERAL; a_section: READABLE_STRING_GENERAL)
|
||||||
|
local
|
||||||
|
v: detachable like items
|
||||||
|
do
|
||||||
|
v := sections.item (a_section)
|
||||||
|
if v = Void then
|
||||||
|
create v.make (1)
|
||||||
|
sections.force (v, a_section)
|
||||||
|
end
|
||||||
|
v.force (obj, k)
|
||||||
|
end
|
||||||
|
|
||||||
|
parse_content (a_content: STRING_8)
|
||||||
|
local
|
||||||
|
i,j,n: INTEGER
|
||||||
|
s: READABLE_STRING_8
|
||||||
|
do
|
||||||
|
last_section_name := Void
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := a_content.count
|
||||||
|
until
|
||||||
|
i > n
|
||||||
|
loop
|
||||||
|
j := a_content.index_of ('%N', i)
|
||||||
|
if j > 0 then
|
||||||
|
s := a_content.substring (i, j - 1)
|
||||||
|
i := j + 1
|
||||||
|
if i <= n and then a_content[i] = '%R' then
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
j := n
|
||||||
|
s := a_content.substring (i, j)
|
||||||
|
i := j + 1
|
||||||
|
end
|
||||||
|
analyze_line (s, Void)
|
||||||
|
variant
|
||||||
|
i
|
||||||
|
end
|
||||||
|
last_section_name := Void
|
||||||
|
rescue
|
||||||
|
last_section_name := Void
|
||||||
|
has_error := True
|
||||||
|
end
|
||||||
|
|
||||||
|
parse_file (p: PATH)
|
||||||
|
do
|
||||||
|
associated_path := p
|
||||||
|
last_section_name := Void
|
||||||
|
import_path (p, Void)
|
||||||
|
last_section_name := Void
|
||||||
|
end
|
||||||
|
|
||||||
|
import_path (p: PATH; a_section_prefix: detachable READABLE_STRING_32)
|
||||||
|
-- Import config from path `p'.
|
||||||
|
local
|
||||||
|
f: PLAIN_TEXT_FILE
|
||||||
|
l_last_section_name: like last_section_name
|
||||||
|
retried: BOOLEAN
|
||||||
|
do
|
||||||
|
if retried then
|
||||||
|
has_error := True
|
||||||
|
else
|
||||||
|
l_last_section_name := last_section_name
|
||||||
|
last_section_name := Void
|
||||||
|
create f.make_with_path (p)
|
||||||
|
if f.exists and then f.is_access_readable then
|
||||||
|
f.open_read
|
||||||
|
from
|
||||||
|
until
|
||||||
|
f.exhausted or f.end_of_file
|
||||||
|
loop
|
||||||
|
f.read_line_thread_aware
|
||||||
|
analyze_line (f.last_string, a_section_prefix)
|
||||||
|
end
|
||||||
|
f.close
|
||||||
|
else
|
||||||
|
-- File not readable
|
||||||
|
has_error := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
last_section_name := l_last_section_name
|
||||||
|
rescue
|
||||||
|
retried := True
|
||||||
|
retry
|
||||||
|
end
|
||||||
|
|
||||||
|
analyze_line (a_line: STRING_8; a_section_prefix: detachable READABLE_STRING_32)
|
||||||
|
-- Analyze line `a_line'.
|
||||||
|
local
|
||||||
|
k,sk: STRING_32
|
||||||
|
v: STRING_8
|
||||||
|
obj: detachable ANY
|
||||||
|
lst: LIST [STRING_8]
|
||||||
|
tb: STRING_TABLE [STRING_8]
|
||||||
|
i,j: INTEGER
|
||||||
|
l_section_name: like last_section_name
|
||||||
|
do
|
||||||
|
obj := Void
|
||||||
|
a_line.left_adjust
|
||||||
|
if
|
||||||
|
a_line.is_empty
|
||||||
|
or a_line.is_whitespace
|
||||||
|
or a_line.starts_with_general ("#")
|
||||||
|
or a_line.starts_with_general (";")
|
||||||
|
or a_line.starts_with_general ("--")
|
||||||
|
then
|
||||||
|
-- Ignore
|
||||||
|
elseif a_line.starts_with_general ("[") then
|
||||||
|
i := a_line.index_of (']', 1)
|
||||||
|
l_section_name := utf.utf_8_string_8_to_string_32 (a_line.substring (2, i - 1))
|
||||||
|
l_section_name.left_adjust
|
||||||
|
l_section_name.right_adjust
|
||||||
|
if a_section_prefix /= Void then
|
||||||
|
l_section_name.prepend_character ('.')
|
||||||
|
l_section_name.prepend (a_section_prefix)
|
||||||
|
end
|
||||||
|
last_section_name := l_section_name
|
||||||
|
else
|
||||||
|
i := a_line.index_of ('=', 1)
|
||||||
|
if i > 1 then
|
||||||
|
k := utf.utf_8_string_8_to_string_32 (a_line.head (i - 1))
|
||||||
|
k.right_adjust
|
||||||
|
v := a_line.substring (i + 1, a_line.count)
|
||||||
|
v.left_adjust
|
||||||
|
v.right_adjust
|
||||||
|
|
||||||
|
|
||||||
|
if k.is_case_insensitive_equal_general ("@include") then
|
||||||
|
import_path (create {PATH}.make_from_string (v), last_section_name)
|
||||||
|
else
|
||||||
|
i := k.index_of ('[', 1)
|
||||||
|
if i > 0 then
|
||||||
|
j := k.index_of (']', i + 1)
|
||||||
|
if j = i + 1 then -- ends_with "[]"
|
||||||
|
k.keep_head (i - 1)
|
||||||
|
if attached {LIST [STRING_8]} items.item (k) as l_list then
|
||||||
|
lst := l_list
|
||||||
|
else
|
||||||
|
create {ARRAYED_LIST [STRING_8]} lst.make (1)
|
||||||
|
record_item (lst, k, a_section_prefix)
|
||||||
|
end
|
||||||
|
lst.force (v)
|
||||||
|
obj := lst
|
||||||
|
elseif j > i then
|
||||||
|
-- table
|
||||||
|
sk := k.substring (i + 1, j - 1)
|
||||||
|
sk.left_adjust
|
||||||
|
sk.right_adjust
|
||||||
|
k.keep_head (i - 1)
|
||||||
|
if attached {STRING_TABLE [STRING_8]} items.item (k) as l_table then
|
||||||
|
tb := l_table
|
||||||
|
else
|
||||||
|
create tb.make (1)
|
||||||
|
record_item (tb, k, a_section_prefix)
|
||||||
|
end
|
||||||
|
tb.force (v, sk)
|
||||||
|
obj := tb
|
||||||
|
else
|
||||||
|
-- Error missing closing ']'
|
||||||
|
has_error := True
|
||||||
|
end
|
||||||
|
else
|
||||||
|
record_item (v, k, a_section_prefix)
|
||||||
|
obj := v
|
||||||
|
end
|
||||||
|
|
||||||
|
if attached last_section_name as l_session and then obj /= Void then
|
||||||
|
record_in_section (obj, k, l_session)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Error
|
||||||
|
has_error := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
record_item (v: ANY; k: READABLE_STRING_32; a_section_prefix: detachable READABLE_STRING_32)
|
||||||
|
do
|
||||||
|
if a_section_prefix /= Void then
|
||||||
|
items.force (v, a_section_prefix + {STRING_32} "." + k)
|
||||||
|
else
|
||||||
|
items.force (v, k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
last_section_name: detachable STRING_32
|
||||||
|
|
||||||
|
utf: UTF_CONVERTER
|
||||||
|
|
||||||
|
invariant
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
|
end
|
||||||
175
library/configuration/src/json_config.e
Normal file
175
library/configuration/src/json_config.e
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
note
|
||||||
|
description: "Object parsing a JSON configuration file."
|
||||||
|
date: "$Date: 2014-12-18 16:37:11 +0100 (jeu., 18 déc. 2014) $"
|
||||||
|
revision: "$Revision: 96383 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
JSON_CONFIG
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CONFIG_READER
|
||||||
|
|
||||||
|
create
|
||||||
|
make_from_file,
|
||||||
|
make_from_string,
|
||||||
|
make_from_json_object
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make_from_file (p: PATH)
|
||||||
|
-- Create object from a file `p'
|
||||||
|
do
|
||||||
|
parse (p)
|
||||||
|
end
|
||||||
|
|
||||||
|
make_from_string (a_json: READABLE_STRING_8)
|
||||||
|
-- Create current config from string `a_json'.
|
||||||
|
local
|
||||||
|
l_parser: JSON_PARSER
|
||||||
|
do
|
||||||
|
create l_parser.make_with_string (a_json)
|
||||||
|
l_parser.parse_content
|
||||||
|
if
|
||||||
|
l_parser.is_valid and then
|
||||||
|
attached l_parser.parsed_json_object as j_o
|
||||||
|
then
|
||||||
|
make_from_json_object (j_o)
|
||||||
|
else
|
||||||
|
has_error := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
make_from_json_object (a_object: JSON_OBJECT)
|
||||||
|
-- Create current config from JSON `a_object'.
|
||||||
|
do
|
||||||
|
associated_path := Void
|
||||||
|
json_value := a_object
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
has_item (k: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- Has item associated with key `k'?
|
||||||
|
do
|
||||||
|
Result := item (k) /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
has_error: BOOLEAN
|
||||||
|
-- Has error?
|
||||||
|
--| Syntax error, source not found, ...
|
||||||
|
|
||||||
|
feature -- Access: Config Reader
|
||||||
|
|
||||||
|
text_item (k: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- String item associated with query `k'.
|
||||||
|
do
|
||||||
|
if attached {JSON_STRING} item (k) as l_string then
|
||||||
|
Result := l_string.unescaped_string_32
|
||||||
|
elseif attached {JSON_NUMBER} item (k) as l_number then
|
||||||
|
Result := l_number.item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
integer_item (k: READABLE_STRING_GENERAL): INTEGER
|
||||||
|
-- Integer item associated with key `k'.
|
||||||
|
do
|
||||||
|
if attached {JSON_NUMBER} item (k) as l_number then
|
||||||
|
Result := l_number.item.to_integer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
associated_path: detachable PATH
|
||||||
|
-- If current was built from a filename, return this path.
|
||||||
|
|
||||||
|
feature -- Duplication
|
||||||
|
|
||||||
|
sub_config (k: READABLE_STRING_GENERAL): detachable CONFIG_READER
|
||||||
|
-- Configuration representing a subset of Current for key `k'.
|
||||||
|
do
|
||||||
|
if attached {JSON_OBJECT} item (k) as j_o then
|
||||||
|
create {JSON_CONFIG} Result.make_from_json_object (j_o)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
item (k: READABLE_STRING_GENERAL): detachable JSON_VALUE
|
||||||
|
-- Item associated with query `k' if any.
|
||||||
|
-- `k' can be a single name such as "foo",
|
||||||
|
-- or a qualified name such as "foo.bar" (assuming that "foo" is associated with a JSON object).
|
||||||
|
do
|
||||||
|
if attached json_value as obj then
|
||||||
|
Result := object_json_value (obj, k.to_string_32)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
object_json_value (a_object: JSON_OBJECT; a_query: READABLE_STRING_32): detachable JSON_VALUE
|
||||||
|
-- Item associated with query `a_query' from object `a_object' if any.
|
||||||
|
local
|
||||||
|
i: INTEGER
|
||||||
|
h: READABLE_STRING_32
|
||||||
|
do
|
||||||
|
i := a_query.index_of ('.', 1)
|
||||||
|
if i > 1 then
|
||||||
|
h := a_query.head (i - 1)
|
||||||
|
if attached {JSON_OBJECT} a_object.item (h) as l_obj then
|
||||||
|
Result := object_json_value (l_obj, a_query.substring (i + 1, a_query.count))
|
||||||
|
else
|
||||||
|
-- This is not an object...
|
||||||
|
Result := Void
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := a_object.item (a_query)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
parse (a_path: PATH)
|
||||||
|
local
|
||||||
|
l_parser: JSON_PARSER
|
||||||
|
do
|
||||||
|
associated_path := a_path
|
||||||
|
has_error := False
|
||||||
|
if attached json_file_from (a_path) as json_file then
|
||||||
|
l_parser := new_json_parser (json_file)
|
||||||
|
l_parser.parse_content
|
||||||
|
if
|
||||||
|
l_parser.is_valid and then
|
||||||
|
attached l_parser.parsed_json_object as jv
|
||||||
|
then
|
||||||
|
json_value := jv
|
||||||
|
else
|
||||||
|
has_error := True
|
||||||
|
end
|
||||||
|
else
|
||||||
|
has_error := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- JSON
|
||||||
|
|
||||||
|
json_value: detachable JSON_OBJECT
|
||||||
|
-- Possible json object representation.
|
||||||
|
|
||||||
|
json_file_from (a_fn: PATH): detachable STRING
|
||||||
|
do
|
||||||
|
Result := (create {JSON_FILE_READER}).read_json_from (a_fn.name.out)
|
||||||
|
end
|
||||||
|
|
||||||
|
new_json_parser (a_string: STRING): JSON_PARSER
|
||||||
|
do
|
||||||
|
create Result.make_with_string (a_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
|
end
|
||||||
18
library/configuration/tests/config_tests-safe.ecf
Normal file
18
library/configuration/tests/config_tests-safe.ecf
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="config_tests" uuid="AD1DE0F7-BC8A-4A17-9A44-56C917BD5604">
|
||||||
|
<target name="config_tests">
|
||||||
|
<root class="TEST_CONFIG_READER_SET" feature="default_create"/>
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/.git$</exclude>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="standard">
|
||||||
|
</option>
|
||||||
|
<setting name="concurrency" value="none"/>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
|
<library name="config" location="..\config-safe.ecf" readonly="false"/>
|
||||||
|
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
|
||||||
|
<tests name="src" location=".\"/>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
18
library/configuration/tests/config_tests.ecf
Normal file
18
library/configuration/tests/config_tests.ecf
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="config_tests" uuid="AD1DE0F7-BC8A-4A17-9A44-56C917BD5604">
|
||||||
|
<target name="config_tests">
|
||||||
|
<root class="TEST_CONFIG_READER_SET" feature="default_create"/>
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/.git$</exclude>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
|
||||||
|
</option>
|
||||||
|
<setting name="concurrency" value="none"/>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
|
<library name="config" location="..\config.ecf" readonly="false"/>
|
||||||
|
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
|
||||||
|
<tests name="src" location=".\"/>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
177
library/configuration/tests/test_config_reader_set.e
Normal file
177
library/configuration/tests/test_config_reader_set.e
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Testing suite for CONFIG_READER .
|
||||||
|
]"
|
||||||
|
author: "$Author: jfiat $"
|
||||||
|
date: "$Date: 2014-12-18 16:37:11 +0100 (jeu., 18 déc. 2014) $"
|
||||||
|
revision: "$Revision: 96383 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
TEST_CONFIG_READER_SET
|
||||||
|
|
||||||
|
inherit
|
||||||
|
EQA_TEST_SET
|
||||||
|
|
||||||
|
feature -- Test
|
||||||
|
|
||||||
|
test_ini
|
||||||
|
local
|
||||||
|
cfg: CONFIG_READER
|
||||||
|
do
|
||||||
|
create {INI_CONFIG} cfg.make_from_string ("[
|
||||||
|
foo = bar
|
||||||
|
|
||||||
|
[first]
|
||||||
|
abc = 1
|
||||||
|
def = and so on
|
||||||
|
ghi = "path"
|
||||||
|
|
||||||
|
[ second ]
|
||||||
|
this = 1
|
||||||
|
is = 2
|
||||||
|
the = 3
|
||||||
|
end = 4
|
||||||
|
|
||||||
|
]")
|
||||||
|
|
||||||
|
assert ("is valid", not cfg.has_error)
|
||||||
|
assert ("has_item (foo)", cfg.has_item ("foo"))
|
||||||
|
assert ("has_item (abc)", cfg.has_item ("abc"))
|
||||||
|
assert ("has_item (def)", cfg.has_item ("def"))
|
||||||
|
assert ("has_item (ghi)", cfg.has_item ("ghi"))
|
||||||
|
assert ("has_item (this)", cfg.has_item ("this"))
|
||||||
|
assert ("has_item (is)", cfg.has_item ("is"))
|
||||||
|
assert ("has_item (the)", cfg.has_item ("the"))
|
||||||
|
assert ("has_item (end)", cfg.has_item ("end"))
|
||||||
|
|
||||||
|
assert ("item (foo)", attached cfg.text_item ("foo") as v and then v.same_string_general ("bar"))
|
||||||
|
assert ("item (abc)", attached cfg.text_item ("abc") as v and then v.same_string_general ("1"))
|
||||||
|
assert ("item (def)", attached cfg.text_item ("def") as v and then v.same_string_general ("and so on"))
|
||||||
|
assert ("item (ghi)", attached cfg.text_item ("ghi") as v and then v.same_string_general ("%"path%""))
|
||||||
|
assert ("item (this)", attached cfg.text_item ("this") as v and then v.same_string_general ("1"))
|
||||||
|
assert ("item (is)", attached cfg.text_item ("is") as v and then v.same_string_general ("2"))
|
||||||
|
assert ("item (the)", attached cfg.text_item ("the") as v and then v.same_string_general ("3"))
|
||||||
|
assert ("item (end)", attached cfg.text_item ("end") as v and then v.same_string_general ("4"))
|
||||||
|
|
||||||
|
assert ("has_item (first.abc)", cfg.has_item ("first.abc"))
|
||||||
|
assert ("item (first.abc)", attached cfg.text_item ("first.abc") as v and then v.same_string_general ("1"))
|
||||||
|
assert ("has_item (second.is)", cfg.has_item ("second.is"))
|
||||||
|
assert ("item (second.is)", attached cfg.text_item ("second.is") as v and then v.same_string_general ("2"))
|
||||||
|
|
||||||
|
if attached cfg.sub_config ("second") as cfg_second then
|
||||||
|
assert ("has_item (is)", cfg_second.has_item ("is"))
|
||||||
|
assert ("item (is)", attached cfg_second.text_item ("is") as v and then v.same_string_general ("2"))
|
||||||
|
|
||||||
|
else
|
||||||
|
assert ("has second", False)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
test_resolver_ini
|
||||||
|
local
|
||||||
|
cfg: CONFIG_READER
|
||||||
|
do
|
||||||
|
create {INI_CONFIG} cfg.make_from_string ("[
|
||||||
|
foo = bar
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
a.b.c = abc
|
||||||
|
|
||||||
|
[expression]
|
||||||
|
text = ${foo}/${a.b.c}
|
||||||
|
]")
|
||||||
|
|
||||||
|
assert ("is valid", not cfg.has_error)
|
||||||
|
assert ("has_item (extra.a.b.c)", cfg.has_item ("extra.a.b.c"))
|
||||||
|
assert ("has_item (extra.a.b.c)", cfg.has_item ("extra.a.b.c"))
|
||||||
|
assert ("has_item (expression.text)", cfg.has_item ("expression.text"))
|
||||||
|
assert ("item (expression.text)", attached cfg.resolved_text_item ("expression.text") as s and then s.same_string_general ("bar/abc"))
|
||||||
|
end
|
||||||
|
|
||||||
|
test_deep_ini
|
||||||
|
local
|
||||||
|
cfg: CONFIG_READER
|
||||||
|
f: RAW_FILE
|
||||||
|
do
|
||||||
|
|
||||||
|
create f.make_with_name ("test_deep.ini")
|
||||||
|
f.create_read_write
|
||||||
|
f.put_string ("[
|
||||||
|
test = extra
|
||||||
|
[new]
|
||||||
|
enabled = true
|
||||||
|
]"
|
||||||
|
)
|
||||||
|
f.close
|
||||||
|
create {INI_CONFIG} cfg.make_from_string ("[
|
||||||
|
foo = bar
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
a.b.c = abc
|
||||||
|
|
||||||
|
[outside]
|
||||||
|
before = include
|
||||||
|
@include=test_deep.ini
|
||||||
|
|
||||||
|
]")
|
||||||
|
f.delete
|
||||||
|
|
||||||
|
assert ("is valid", not cfg.has_error)
|
||||||
|
assert ("has_item (extra.a.b.c)", cfg.has_item ("extra.a.b.c"))
|
||||||
|
assert ("has_item (extra.a.b.c)", cfg.has_item ("extra.a.b.c"))
|
||||||
|
assert ("has_item (outside.new.enabled)", cfg.has_item ("outside.new.enabled"))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
test_json
|
||||||
|
local
|
||||||
|
cfg: CONFIG_READER
|
||||||
|
do
|
||||||
|
create {JSON_CONFIG} cfg.make_from_string ("[
|
||||||
|
{
|
||||||
|
"foo": "bar",
|
||||||
|
"first": {
|
||||||
|
"abc": 1,
|
||||||
|
"def": "and so on",
|
||||||
|
"ghi": "\"path\""
|
||||||
|
},
|
||||||
|
"second": {
|
||||||
|
"this": 1,
|
||||||
|
"is": 2,
|
||||||
|
"the": 3,
|
||||||
|
"end": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]")
|
||||||
|
|
||||||
|
assert ("is valid", not cfg.has_error)
|
||||||
|
assert ("has_item (foo)", cfg.has_item ("foo"))
|
||||||
|
assert ("has_item (first.abc)", cfg.has_item ("first.abc"))
|
||||||
|
assert ("has_item (first.def)", cfg.has_item ("first.def"))
|
||||||
|
assert ("has_item (first.ghi)", cfg.has_item ("first.ghi"))
|
||||||
|
assert ("has_item (second.this)", cfg.has_item ("second.this"))
|
||||||
|
assert ("has_item (second.is)", cfg.has_item ("second.is"))
|
||||||
|
assert ("has_item (second.the)", cfg.has_item ("second.the"))
|
||||||
|
assert ("has_item (second.end)", cfg.has_item ("second.end"))
|
||||||
|
|
||||||
|
assert ("item (foo)", attached cfg.text_item ("foo") as v and then v.same_string_general ("bar"))
|
||||||
|
assert ("item (first.abc)", attached cfg.text_item ("first.abc") as v and then v.same_string_general ("1"))
|
||||||
|
assert ("item (first.def)", attached cfg.text_item ("first.def") as v and then v.same_string_general ("and so on"))
|
||||||
|
assert ("item (first.ghi)", attached cfg.text_item ("first.ghi") as v and then v.same_string_general ("%"path%""))
|
||||||
|
assert ("item (second.this)", attached cfg.text_item ("second.this") as v and then v.same_string_general ("1"))
|
||||||
|
assert ("item (second.is)", attached cfg.text_item ("second.is") as v and then v.same_string_general ("2"))
|
||||||
|
assert ("item (second.the)", attached cfg.text_item ("second.the") as v and then v.same_string_general ("3"))
|
||||||
|
assert ("item (second.end)", attached cfg.text_item ("second.end") as v and then v.same_string_general ("4"))
|
||||||
|
|
||||||
|
if attached cfg.sub_config ("second") as cfg_second then
|
||||||
|
assert ("has_item (is)", cfg_second.has_item ("is"))
|
||||||
|
assert ("item (is)", attached cfg_second.text_item ("is") as v and then v.same_string_general ("2"))
|
||||||
|
|
||||||
|
else
|
||||||
|
assert ("has second", False)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="layout" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" library_target="layout">
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="layout" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" library_target="layout">
|
||||||
<target name="layout">
|
<target name="layout">
|
||||||
<root all_classes="true"/>
|
<root all_classes="true"/>
|
||||||
<option warning="true">
|
<option warning="true" void_safety="all">
|
||||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||||
</option>
|
</option>
|
||||||
<setting name="console_application" value="true"/>
|
<setting name="console_application" value="true"/>
|
||||||
|
|||||||
21
library/layout/layout.ecf
Normal file
21
library/layout/layout.ecf
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="layout" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" library_target="layout">
|
||||||
|
<target name="layout">
|
||||||
|
<root all_classes="true"/>
|
||||||
|
<option warning="true" void_safety="none">
|
||||||
|
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||||
|
</option>
|
||||||
|
<setting name="console_application" value="true"/>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||||
|
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>
|
||||||
|
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
|
||||||
|
<cluster name="src" location=".\src\" recursive="true">
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/CVS$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
</cluster>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
note
|
||||||
|
description: "Provide access to json configuration"
|
||||||
|
date: "$Date: 2015-01-14 16:13:47 +0100 (mer., 14 janv. 2015) $"
|
||||||
|
revision: "$Revision: 96454 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
APPLICATION_JSON_CONFIGURATION_HELPER
|
||||||
|
|
||||||
|
feature -- Application Configuration
|
||||||
|
|
||||||
|
new_smtp_configuration (a_path: PATH): READABLE_STRING_32
|
||||||
|
-- Build a new database configuration.
|
||||||
|
local
|
||||||
|
l_parser: JSON_PARSER
|
||||||
|
do
|
||||||
|
Result := ""
|
||||||
|
if attached json_file_from (a_path) as json_file then
|
||||||
|
l_parser := new_json_parser (json_file)
|
||||||
|
l_parser.parse_content
|
||||||
|
if
|
||||||
|
l_parser.is_valid and then
|
||||||
|
attached {JSON_OBJECT} l_parser.parsed_json_value as jv and then
|
||||||
|
attached {JSON_OBJECT} jv.item ("smtp") as l_smtp and then
|
||||||
|
attached {JSON_STRING} l_smtp.item ("server") as l_server
|
||||||
|
then
|
||||||
|
Result := l_server.item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
new_database_configuration (a_path: PATH): detachable DATABASE_CONFIGURATION
|
||||||
|
-- Build a new database configuration.
|
||||||
|
local
|
||||||
|
l_parser: JSON_PARSER
|
||||||
|
do
|
||||||
|
if attached json_file_from (a_path) as json_file then
|
||||||
|
l_parser := new_json_parser (json_file)
|
||||||
|
l_parser.parse_content
|
||||||
|
if
|
||||||
|
l_parser.is_valid and then
|
||||||
|
attached {JSON_OBJECT} l_parser.parsed_json_value as jv and then
|
||||||
|
attached {JSON_OBJECT} jv.item ("database") as l_database and then
|
||||||
|
attached {JSON_OBJECT} l_database.item ("datasource") as l_datasource and then
|
||||||
|
attached {JSON_STRING} l_datasource.item ("driver") as l_driver and then
|
||||||
|
attached {JSON_STRING} l_datasource.item ("environment") as l_envrionment and then
|
||||||
|
attached {JSON_OBJECT} l_database.item ("environments") as l_environments and then
|
||||||
|
attached {JSON_OBJECT} l_environments.item (l_envrionment.item) as l_environment_selected and then
|
||||||
|
attached {JSON_STRING} l_environment_selected.item ("connection_string") as l_connection_string
|
||||||
|
then
|
||||||
|
create Result.make (l_driver.item, l_connection_string.unescaped_string_32)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
new_logger_level_configuration (a_path: PATH): READABLE_STRING_32
|
||||||
|
-- Retrieve a new logger level configuration.
|
||||||
|
-- By default, level is set to `DEBUG'.
|
||||||
|
local
|
||||||
|
l_parser: JSON_PARSER
|
||||||
|
do
|
||||||
|
Result := "DEBUG"
|
||||||
|
if attached json_file_from (a_path) as json_file then
|
||||||
|
l_parser := new_json_parser (json_file)
|
||||||
|
l_parser.parse_content
|
||||||
|
if
|
||||||
|
l_parser.is_valid and then
|
||||||
|
attached {JSON_OBJECT} l_parser.parsed_json_value as jv and then
|
||||||
|
attached {JSON_OBJECT} jv.item ("logger") as l_logger and then
|
||||||
|
attached {JSON_STRING} l_logger.item ("level") as l_level
|
||||||
|
then
|
||||||
|
Result := l_level.item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
new_database_configuration_test (a_path: PATH): detachable DATABASE_CONFIGURATION
|
||||||
|
-- Build a new database configuration for testing purposes.
|
||||||
|
local
|
||||||
|
l_parser: JSON_PARSER
|
||||||
|
do
|
||||||
|
if attached json_file_from (a_path) as json_file then
|
||||||
|
l_parser := new_json_parser (json_file)
|
||||||
|
l_parser.parse_content
|
||||||
|
if
|
||||||
|
l_parser.is_valid and then
|
||||||
|
attached {JSON_OBJECT} l_parser.parsed_json_value as jv and then
|
||||||
|
l_parser.is_parsed and then
|
||||||
|
attached {JSON_OBJECT} jv.item ("database") as l_database and then
|
||||||
|
attached {JSON_OBJECT} l_database.item ("datasource") as l_datasource and then
|
||||||
|
attached {JSON_STRING} l_datasource.item ("driver") as l_driver and then
|
||||||
|
attached {JSON_STRING} l_datasource.item ("environment") as l_envrionment and then
|
||||||
|
attached {JSON_STRING} l_datasource.item ("trusted") as l_trusted and then
|
||||||
|
attached {JSON_OBJECT} l_database.item ("environments") as l_environments and then
|
||||||
|
attached {JSON_OBJECT} l_environments.item ("test") as l_environment_selected and then
|
||||||
|
attached {JSON_STRING} l_environment_selected.item ("connection_string") as l_connection_string and then
|
||||||
|
attached {JSON_STRING} l_environment_selected.item ("name") as l_name
|
||||||
|
then
|
||||||
|
create Result.make (l_driver.item, l_connection_string.unescaped_string_8)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- JSON
|
||||||
|
|
||||||
|
json_file_from (a_fn: PATH): detachable STRING
|
||||||
|
do
|
||||||
|
Result := (create {JSON_FILE_READER}).read_json_from (a_fn.name.out)
|
||||||
|
end
|
||||||
|
|
||||||
|
new_json_parser (a_string: STRING): JSON_PARSER
|
||||||
|
do
|
||||||
|
create Result.make_with_string (a_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Object that represent Database configuration settings"
|
description: "Object that represent Database configuration settings"
|
||||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
date: "$Date: 2015-01-14 16:13:47 +0100 (mer., 14 janv. 2015) $"
|
||||||
revision: "$Revision: 95678 $"
|
revision: "$Revision: 96454 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
DATABASE_CONFIGURATION
|
DATABASE_CONFIGURATION
|
||||||
@@ -25,18 +25,73 @@ feature {NONE} -- Initialization
|
|||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
driver: READABLE_STRING_32
|
driver: READABLE_STRING_32
|
||||||
--Database driver.
|
--Database driver.
|
||||||
|
|
||||||
database_string: READABLE_STRING_32
|
database_string: READABLE_STRING_32
|
||||||
-- Database connection.
|
-- Database connection.
|
||||||
|
|
||||||
connection_string: READABLE_STRING_32
|
connection_string: READABLE_STRING_32
|
||||||
-- Connection string
|
-- Connection string
|
||||||
do
|
do
|
||||||
Result := "Driver={"+driver+"};" + database_string;
|
Result := "Driver={" + driver + "};" + database_string
|
||||||
end
|
end
|
||||||
|
|
||||||
|
item (a_param: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
local
|
||||||
|
s: READABLE_STRING_32
|
||||||
|
lower_s: READABLE_STRING_32
|
||||||
|
i,j: INTEGER
|
||||||
|
k: STRING_32
|
||||||
|
do
|
||||||
|
create k.make_from_string_general (a_param)
|
||||||
|
k.to_lower
|
||||||
|
|
||||||
|
s := database_string
|
||||||
|
lower_s := s.as_lower
|
||||||
|
i := lower_s.substring_index (k + {STRING_32} "=", 1)
|
||||||
|
if i > 0 then
|
||||||
|
if i = 1 or else s[i-1] = ';' then
|
||||||
|
j := s.index_of (';', i + k.count + 1)
|
||||||
|
if j = 0 then
|
||||||
|
j := s.count + 1
|
||||||
|
end
|
||||||
|
Result := s.substring (i + k.count + 1, j - 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
server_name: detachable READABLE_STRING_32
|
||||||
|
do
|
||||||
|
Result := item ("Server")
|
||||||
|
end
|
||||||
|
|
||||||
|
port: INTEGER
|
||||||
|
do
|
||||||
|
if
|
||||||
|
attached item ("Port") as l_port and then
|
||||||
|
l_port.is_integer
|
||||||
|
then
|
||||||
|
Result := l_port.to_integer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
database_name: detachable READABLE_STRING_32
|
||||||
|
do
|
||||||
|
Result := item ("Database")
|
||||||
|
end
|
||||||
|
|
||||||
|
user_id: detachable READABLE_STRING_32
|
||||||
|
do
|
||||||
|
Result := item ("Uid")
|
||||||
|
end
|
||||||
|
|
||||||
|
user_password: detachable READABLE_STRING_32
|
||||||
|
do
|
||||||
|
Result := item ("Pwd")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Provide access to json configuration"
|
|
||||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
|
||||||
revision: "$Revision: 95678 $"
|
|
||||||
|
|
||||||
class
|
|
||||||
JSON_CONFIGURATION
|
|
||||||
|
|
||||||
feature -- Application Configuration
|
|
||||||
|
|
||||||
new_smtp_configuration (a_path: PATH): READABLE_STRING_32
|
|
||||||
-- Build a new database configuration.
|
|
||||||
local
|
|
||||||
l_parser: JSON_PARSER
|
|
||||||
do
|
|
||||||
Result := ""
|
|
||||||
if attached json_file_from (a_path) as json_file then
|
|
||||||
l_parser := new_json_parser (json_file)
|
|
||||||
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
|
|
||||||
attached {JSON_OBJECT} jv.item ("smtp") as l_smtp and then
|
|
||||||
attached {JSON_STRING} l_smtp.item ("server") as l_server then
|
|
||||||
Result := l_server.item
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
new_database_configuration (a_path: PATH): detachable DATABASE_CONFIGURATION
|
|
||||||
-- Build a new database configuration.
|
|
||||||
local
|
|
||||||
l_parser: JSON_PARSER
|
|
||||||
do
|
|
||||||
if attached json_file_from (a_path) as json_file then
|
|
||||||
l_parser := new_json_parser (json_file)
|
|
||||||
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
|
|
||||||
attached {JSON_OBJECT} jv.item ("database") as l_database and then
|
|
||||||
attached {JSON_OBJECT} l_database.item ("datasource") as l_datasource and then
|
|
||||||
attached {JSON_STRING} l_datasource.item ("driver") as l_driver and then
|
|
||||||
attached {JSON_STRING} l_datasource.item ("environment") as l_envrionment and then
|
|
||||||
attached {JSON_OBJECT} l_database.item ("environments") as l_environments and then
|
|
||||||
attached {JSON_OBJECT} l_environments.item (l_envrionment.item) as l_environment_selected and then
|
|
||||||
attached {JSON_STRING} l_environment_selected.item ("connection_string") as l_connection_string then
|
|
||||||
create Result.make (l_driver.item, l_connection_string.unescaped_string_8)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
new_logger_level_configuration (a_path: PATH): READABLE_STRING_32
|
|
||||||
-- Retrieve a new logger level configuration.
|
|
||||||
-- By default, level is set to `DEBUG'.
|
|
||||||
local
|
|
||||||
l_parser: JSON_PARSER
|
|
||||||
do
|
|
||||||
Result := "DEBUG"
|
|
||||||
if attached json_file_from (a_path) as json_file then
|
|
||||||
l_parser := new_json_parser (json_file)
|
|
||||||
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
|
|
||||||
attached {JSON_OBJECT} jv.item ("logger") as l_logger and then
|
|
||||||
attached {JSON_STRING} l_logger.item ("level") as l_level then
|
|
||||||
Result := l_level.item
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
new_database_configuration_test (a_path: PATH): detachable DATABASE_CONFIGURATION
|
|
||||||
-- Build a new database configuration for testing purposes.
|
|
||||||
local
|
|
||||||
l_parser: JSON_PARSER
|
|
||||||
do
|
|
||||||
if attached json_file_from (a_path) as json_file then
|
|
||||||
l_parser := new_json_parser (json_file)
|
|
||||||
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
|
|
||||||
attached {JSON_OBJECT} jv.item ("database") as l_database and then
|
|
||||||
attached {JSON_OBJECT} l_database.item ("datasource") as l_datasource and then
|
|
||||||
attached {JSON_STRING} l_datasource.item ("driver") as l_driver and then
|
|
||||||
attached {JSON_STRING} l_datasource.item ("environment") as l_envrionment and then
|
|
||||||
attached {JSON_STRING} l_datasource.item ("trusted") as l_trusted and then
|
|
||||||
attached {JSON_OBJECT} l_database.item ("environments") as l_environments and then
|
|
||||||
attached {JSON_OBJECT} l_environments.item ("test") as l_environment_selected and then
|
|
||||||
attached {JSON_STRING} l_environment_selected.item ("connection_string") as l_connection_string and then
|
|
||||||
attached {JSON_STRING} l_environment_selected.item ("name") as l_name then
|
|
||||||
create Result.make (l_driver.item, l_connection_string.unescaped_string_8)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature {NONE} -- JSON
|
|
||||||
|
|
||||||
json_file_from (a_fn: PATH): detachable STRING
|
|
||||||
do
|
|
||||||
Result := (create {JSON_FILE_READER}).read_json_from (a_fn.name.out)
|
|
||||||
end
|
|
||||||
|
|
||||||
new_json_parser (a_string: STRING): JSON_PARSER
|
|
||||||
do
|
|
||||||
create Result.make_parser (a_string)
|
|
||||||
end
|
|
||||||
|
|
||||||
note
|
|
||||||
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
||||||
end
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Provides logger information"
|
description: "Provides logger information"
|
||||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
date: "$Date: 2015-01-15 00:00:58 +0100 (jeu., 15 janv. 2015) $"
|
||||||
revision: "$Revision: 95678 $"
|
revision: "$Revision: 96461 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
SHARED_LOGGER
|
SHARED_LOGGER
|
||||||
@@ -29,7 +29,7 @@ feature -- Logger
|
|||||||
create l_environment
|
create l_environment
|
||||||
if attached separate_character_option_value ('d') as l_dir then
|
if attached separate_character_option_value ('d') as l_dir then
|
||||||
l_path := create {PATH}.make_from_string (l_dir)
|
l_path := create {PATH}.make_from_string (l_dir)
|
||||||
create l_log_writer.make_at_location (l_path.extended ("..").appended ("\api.log"))
|
create l_log_writer.make_at_location (l_path.extended ("logs").appended ("\api.log"))
|
||||||
else
|
else
|
||||||
l_path := create {PATH}.make_current
|
l_path := create {PATH}.make_current
|
||||||
create l_log_writer.make_at_location (l_path.extended("api.log"))
|
create l_log_writer.make_at_location (l_path.extended("api.log"))
|
||||||
@@ -82,23 +82,26 @@ feature {NONE} -- JSON
|
|||||||
do
|
do
|
||||||
create Result
|
create Result
|
||||||
if attached json_file_from (a_path) as json_file then
|
if attached json_file_from (a_path) as json_file then
|
||||||
l_parser := new_json_parser (json_file)
|
l_parser := new_json_parser (json_file)
|
||||||
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
|
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
|
||||||
attached {JSON_OBJECT} jv.item ("logger") as l_logger and then
|
attached {JSON_OBJECT} jv.item ("logger") as l_logger and then
|
||||||
attached {JSON_STRING} l_logger.item ("backup_count") as l_count and then
|
attached {JSON_STRING} l_logger.item ("backup_count") as l_count and then
|
||||||
attached {JSON_STRING} l_logger.item ("level") as l_level then
|
attached {JSON_STRING} l_logger.item ("level") as l_level then
|
||||||
Result.set_level (l_level.item)
|
Result.set_level (l_level.item)
|
||||||
if l_count.item.is_natural then
|
if l_count.item.is_natural then
|
||||||
Result.set_backup_count (l_count.item.to_natural)
|
Result.set_backup_count (l_count.item.to_natural)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
json_file_from (a_fn: PATH): detachable STRING
|
json_file_from (a_fn: PATH): detachable STRING
|
||||||
|
local
|
||||||
|
ut: FILE_UTILITIES
|
||||||
do
|
do
|
||||||
Result := (create {JSON_FILE_READER}).read_json_from (a_fn.name.out)
|
if ut.file_path_exists (a_fn) then
|
||||||
|
Result := (create {JSON_FILE_READER}).read_json_from (a_fn.name)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
new_json_parser (a_string: STRING): JSON_PARSER
|
new_json_parser (a_string: STRING): JSON_PARSER
|
||||||
@@ -107,6 +110,6 @@ feature {NONE} -- JSON
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms_model" uuid="57C6F407-E894-4554-8A59-C8D1F3BBC5D7" library_target="cms_model">
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms_model" uuid="57C6F407-E894-4554-8A59-C8D1F3BBC5D7" library_target="cms_model">
|
||||||
<target name="cms_model">
|
<target name="cms_model">
|
||||||
<root all_classes="True"/>
|
<root all_classes="true"/>
|
||||||
<option warning="true">
|
<option warning="true" void_safety="all">
|
||||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||||
</option>
|
</option>
|
||||||
<setting name="console_application" value="true"/>
|
<setting name="console_application" value="true"/>
|
||||||
<library name="base" location="$ISE_LIBRARY/library/base/base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||||
<cluster name="cms_model" location=".\src" recursive="true">
|
<cluster name="cms_model" location=".\src\" recursive="true">
|
||||||
<file_rule>
|
<file_rule>
|
||||||
<exclude>/EIFGENs$</exclude>
|
<exclude>/EIFGENs$</exclude>
|
||||||
<exclude>/.svn$</exclude>
|
|
||||||
<exclude>/CVS$</exclude>
|
<exclude>/CVS$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
</file_rule>
|
</file_rule>
|
||||||
</cluster>
|
</cluster>
|
||||||
</target>
|
</target>
|
||||||
|
|||||||
19
library/model/cms_model.ecf
Normal file
19
library/model/cms_model.ecf
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms_model" uuid="57C6F407-E894-4554-8A59-C8D1F3BBC5D7" library_target="cms_model">
|
||||||
|
<target name="cms_model">
|
||||||
|
<root all_classes="true"/>
|
||||||
|
<option warning="true" void_safety="none">
|
||||||
|
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||||
|
</option>
|
||||||
|
<setting name="console_application" value="true"/>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
|
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||||
|
<cluster name="cms_model" location=".\src\" recursive="true">
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/CVS$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
</cluster>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
@@ -83,8 +83,8 @@ feature -- Access
|
|||||||
author: detachable CMS_USER
|
author: detachable CMS_USER
|
||||||
-- Author of current node.
|
-- Author of current node.
|
||||||
|
|
||||||
collaborators: detachable LIST[CMS_USER]
|
-- collaborators: detachable LIST[CMS_USER]
|
||||||
-- Users contributed to current Node.
|
-- -- Users contributed to current Node.
|
||||||
|
|
||||||
feature -- status report
|
feature -- status report
|
||||||
|
|
||||||
@@ -177,18 +177,18 @@ feature -- Element change
|
|||||||
auther_set: author = u
|
auther_set: author = u
|
||||||
end
|
end
|
||||||
|
|
||||||
add_collaborator (a_user: CMS_USER)
|
-- add_collaborator (a_user: CMS_USER)
|
||||||
-- Add collaborator `a_user' to the collaborators list.
|
-- -- Add collaborator `a_user' to the collaborators list.
|
||||||
local
|
-- local
|
||||||
lst: like collaborators
|
-- lst: like collaborators
|
||||||
do
|
-- do
|
||||||
lst := collaborators
|
-- lst := collaborators
|
||||||
if lst = Void then
|
-- if lst = Void then
|
||||||
create {ARRAYED_SET [CMS_USER]} lst.make (1)
|
-- create {ARRAYED_SET [CMS_USER]} lst.make (1)
|
||||||
collaborators := lst
|
-- collaborators := lst
|
||||||
end
|
-- end
|
||||||
lst.force (a_user)
|
-- lst.force (a_user)
|
||||||
end
|
-- end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
|||||||
@@ -13,19 +13,38 @@ inherit
|
|||||||
DEBUG_OUTPUT
|
DEBUG_OUTPUT
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make,
|
||||||
|
make_with_id -- MAYBE: export to CMS_STORAGE
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (a_name: READABLE_STRING_32)
|
make (a_name: READABLE_STRING_32)
|
||||||
-- Create an object with name `a_name'.
|
-- Create an object with name `a_name'.
|
||||||
|
require
|
||||||
|
a_name_not_empty: not a_name.is_whitespace
|
||||||
do
|
do
|
||||||
name := a_name
|
name := a_name
|
||||||
create creation_date.make_now_utc
|
initialize
|
||||||
ensure
|
ensure
|
||||||
name_set: name = a_name
|
name_set: name = a_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
make_with_id (a_id: INTEGER_64)
|
||||||
|
require
|
||||||
|
a_id_valid: a_id > 0
|
||||||
|
do
|
||||||
|
id := a_id
|
||||||
|
name := {STRING_32} ""
|
||||||
|
initialize
|
||||||
|
ensure
|
||||||
|
id_set: id = a_id
|
||||||
|
end
|
||||||
|
|
||||||
|
initialize
|
||||||
|
do
|
||||||
|
create creation_date.make_now_utc
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
id: INTEGER_64
|
id: INTEGER_64
|
||||||
@@ -35,7 +54,10 @@ feature -- Access
|
|||||||
-- User name.
|
-- User name.
|
||||||
|
|
||||||
password: detachable READABLE_STRING_32
|
password: detachable READABLE_STRING_32
|
||||||
-- User password.
|
-- User password (plain text password).
|
||||||
|
|
||||||
|
hashed_password: detachable READABLE_STRING_8
|
||||||
|
-- Hashed user password.
|
||||||
|
|
||||||
email: detachable READABLE_STRING_32
|
email: detachable READABLE_STRING_32
|
||||||
-- User email.
|
-- User email.
|
||||||
@@ -113,8 +135,20 @@ feature -- Change element
|
|||||||
-- Set `password' with `a_password'.
|
-- Set `password' with `a_password'.
|
||||||
do
|
do
|
||||||
password := a_password
|
password := a_password
|
||||||
|
hashed_password := Void
|
||||||
ensure
|
ensure
|
||||||
password_set: password = a_password
|
password_set: password = a_password
|
||||||
|
hashed_password_void: hashed_password = Void
|
||||||
|
end
|
||||||
|
|
||||||
|
set_hashed_password (a_hashed_password: like hashed_password)
|
||||||
|
-- Set `hashed_password' with `a_hashed_password'.
|
||||||
|
do
|
||||||
|
hashed_password := a_hashed_password
|
||||||
|
password := Void
|
||||||
|
ensure
|
||||||
|
password_void: password = Void
|
||||||
|
hashed_password_set: hashed_password = a_hashed_password
|
||||||
end
|
end
|
||||||
|
|
||||||
set_email (a_email: like email)
|
set_email (a_email: like email)
|
||||||
@@ -178,6 +212,10 @@ feature -- Change element: data
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
invariant
|
||||||
|
|
||||||
|
id_or_name_set: id > 0 or else not name.is_whitespace
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_STORAGE_STORE_SQL}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_STORAGE_STORE_SQL
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_STORAGE
|
||||||
|
|
||||||
|
CMS_STORAGE_SQL
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_connection: DATABASE_CONNECTION)
|
||||||
|
--
|
||||||
|
require
|
||||||
|
is_connected: a_connection.is_connected
|
||||||
|
do
|
||||||
|
connection := a_connection
|
||||||
|
log.write_information (generator + ".make - is database connected? "+ a_connection.is_connected.out )
|
||||||
|
|
||||||
|
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
||||||
|
|
||||||
|
create error_handler.make
|
||||||
|
-- error_handler.add_synchronization (db_handler.database_error_handler)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
db_handler: DATABASE_HANDLER
|
||||||
|
|
||||||
|
connection: DATABASE_CONNECTION
|
||||||
|
-- Current database connection.
|
||||||
|
|
||||||
|
feature -- Query
|
||||||
|
|
||||||
|
sql_post_execution
|
||||||
|
-- Post database execution.
|
||||||
|
do
|
||||||
|
error_handler.append (db_handler.database_error_handler)
|
||||||
|
if error_handler.has_error then
|
||||||
|
log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_begin_transaction
|
||||||
|
do
|
||||||
|
connection.begin_transaction
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_commit_transaction
|
||||||
|
do
|
||||||
|
connection.commit
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
|
do
|
||||||
|
check_sql_query_validity (a_sql_statement, a_params)
|
||||||
|
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
|
||||||
|
db_handler.execute_query
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
|
do
|
||||||
|
check_sql_query_validity (a_sql_statement, a_params)
|
||||||
|
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
|
||||||
|
db_handler.execute_change
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_rows_count: INTEGER
|
||||||
|
-- Number of rows for last sql execution.
|
||||||
|
do
|
||||||
|
Result := db_handler.count
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_start
|
||||||
|
-- Set the cursor on first element.
|
||||||
|
do
|
||||||
|
db_handler.start
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_after: BOOLEAN
|
||||||
|
-- Are there no more items to iterate over?
|
||||||
|
do
|
||||||
|
Result := db_handler.after
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_forth
|
||||||
|
-- Fetch next row from last sql execution, if any.
|
||||||
|
do
|
||||||
|
db_handler.forth
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_item (a_index: INTEGER): detachable ANY
|
||||||
|
do
|
||||||
|
if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then
|
||||||
|
Result := l_item.item (a_index)
|
||||||
|
else
|
||||||
|
check has_item_at_index: False end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Object that handle a database connection for ODBC"
|
description: "Object that handle a database connection for ODBC"
|
||||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
date: "$Date: 2014-11-13 12:23:47 -0300 (ju., 13 nov. 2014) $"
|
||||||
revision: "$Revision: 95678 $"
|
revision: "$Revision: 96085 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
DATABASE_CONNECTION_ODBC
|
DATABASE_CONNECTION_ODBC
|
||||||
@@ -13,6 +13,8 @@ inherit
|
|||||||
db_application
|
db_application
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SHARED_LOGGER
|
||||||
|
|
||||||
create
|
create
|
||||||
make, make_common, make_basic, login_with_connection_string
|
make, make_common, make_basic, login_with_connection_string
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@ feature -- Initialization
|
|||||||
l_retried: BOOLEAN
|
l_retried: BOOLEAN
|
||||||
do
|
do
|
||||||
create db_application.login (username, password)
|
create db_application.login (username, password)
|
||||||
|
create database_error_handler.make
|
||||||
if not l_retried then
|
if not l_retried then
|
||||||
db_application.set_hostname (hostname)
|
db_application.set_hostname (hostname)
|
||||||
db_application.set_data_source (database_name)
|
db_application.set_data_source (database_name)
|
||||||
@@ -34,14 +36,13 @@ feature -- Initialization
|
|||||||
if keep_connection then
|
if keep_connection then
|
||||||
connect
|
connect
|
||||||
end
|
end
|
||||||
set_successful
|
|
||||||
else
|
else
|
||||||
create db_control.make
|
create db_control.make
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
create db_control.make
|
create db_control.make
|
||||||
set_last_error_from_exception ("Connection execution")
|
-- set_last_error_from_exception ("Connection execution")
|
||||||
log.write_critical (generator + ".make_common:" + last_error_message)
|
-- log.write_critical (generator + ".make_common:" + last_error_message)
|
||||||
if is_connected then
|
if is_connected then
|
||||||
disconnect
|
disconnect
|
||||||
end
|
end
|
||||||
@@ -56,7 +57,7 @@ feature -- Initialization
|
|||||||
l_retried: BOOLEAN
|
l_retried: BOOLEAN
|
||||||
do
|
do
|
||||||
create db_application.login (username, password)
|
create db_application.login (username, password)
|
||||||
|
create database_error_handler.make
|
||||||
if not l_retried then
|
if not l_retried then
|
||||||
db_application.set_hostname (hostname)
|
db_application.set_hostname (hostname)
|
||||||
db_application.set_data_source (a_database_name)
|
db_application.set_data_source (a_database_name)
|
||||||
@@ -66,14 +67,13 @@ feature -- Initialization
|
|||||||
if keep_connection then
|
if keep_connection then
|
||||||
connect
|
connect
|
||||||
end
|
end
|
||||||
set_successful
|
|
||||||
else
|
else
|
||||||
create db_control.make
|
create db_control.make
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
create db_control.make
|
create db_control.make
|
||||||
set_last_error_from_exception ("Connection execution")
|
-- set_last_error_from_exception ("Connection execution")
|
||||||
log.write_critical (generator + ".make_common:" + last_error_message)
|
-- log.write_critical (generator + ".make_common:" + last_error_message)
|
||||||
if is_connected then
|
if is_connected then
|
||||||
disconnect
|
disconnect
|
||||||
end
|
end
|
||||||
@@ -88,6 +88,7 @@ feature -- Initialization
|
|||||||
-- `database_name' to `a_database_name'
|
-- `database_name' to `a_database_name'
|
||||||
-- `connection' to `a_connection'
|
-- `connection' to `a_connection'
|
||||||
do
|
do
|
||||||
|
create database_error_handler.make
|
||||||
create db_application.login (a_username, a_password)
|
create db_application.login (a_username, a_password)
|
||||||
db_application.set_hostname (a_hostname)
|
db_application.set_hostname (a_hostname)
|
||||||
db_application.set_data_source (a_database_name)
|
db_application.set_data_source (a_database_name)
|
||||||
@@ -104,6 +105,7 @@ feature -- Initialization
|
|||||||
do
|
do
|
||||||
log.write_debug (generator +".login_with_connection_string")
|
log.write_debug (generator +".login_with_connection_string")
|
||||||
create db_application.login_with_connection_string (a_string)
|
create db_application.login_with_connection_string (a_string)
|
||||||
|
create database_error_handler.make
|
||||||
db_application.set_base
|
db_application.set_base
|
||||||
create db_control.make
|
create db_control.make
|
||||||
log.write_debug (generator +".login_with_connection_string, is_keep_connection? "+ is_keep_connection.out )
|
log.write_debug (generator +".login_with_connection_string, is_keep_connection? "+ is_keep_connection.out )
|
||||||
|
|||||||
@@ -45,14 +45,14 @@ feature -- Functionality Store Procedures
|
|||||||
execute_store_reader
|
execute_store_reader
|
||||||
-- Execute a `store' to read data.
|
-- Execute a `store' to read data.
|
||||||
require
|
require
|
||||||
store_not_void: store /= void
|
store_not_void: store /= Void
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_store_writer
|
execute_store_writer
|
||||||
-- Execute a `store' to write data.
|
-- Execute a `store' to write data.
|
||||||
require
|
require
|
||||||
store_not_void: store /= void
|
store_not_void: store /= Void
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -61,14 +61,14 @@ feature -- SQL Queries
|
|||||||
execute_query
|
execute_query
|
||||||
-- Execute sql query, the read data from the database.
|
-- Execute sql query, the read data from the database.
|
||||||
require
|
require
|
||||||
query_not_void: query /= void
|
query_not_void: query /= Void
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_change
|
execute_change
|
||||||
-- Execute sql query that update/add data.
|
-- Execute sql query that update/add data.
|
||||||
require
|
require
|
||||||
query_not_void: query /= void
|
query_not_void: query /= Void
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -153,22 +153,22 @@ feature -- Status Report
|
|||||||
end
|
end
|
||||||
|
|
||||||
connection: DATABASE_CONNECTION
|
connection: DATABASE_CONNECTION
|
||||||
-- Database connection.
|
-- Database connection.
|
||||||
|
|
||||||
db_control: DB_CONTROL
|
db_control: DB_CONTROL
|
||||||
-- Database control.
|
-- Database control.
|
||||||
do
|
do
|
||||||
Result := connection.db_control
|
Result := connection.db_control
|
||||||
end
|
end
|
||||||
|
|
||||||
db_result: detachable DB_RESULT
|
db_result: detachable DB_RESULT
|
||||||
-- Database query result.
|
-- Database query result.
|
||||||
|
|
||||||
db_selection: detachable DB_SELECTION
|
db_selection: detachable DB_SELECTION
|
||||||
-- Database selection.
|
-- Database selection.
|
||||||
|
|
||||||
db_change: detachable DB_CHANGE
|
db_change: detachable DB_CHANGE
|
||||||
-- Database modification.
|
-- Database modification.
|
||||||
|
|
||||||
feature -- Error handling
|
feature -- Error handling
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ class
|
|||||||
DATABASE_QUERY
|
DATABASE_QUERY
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
|
|
||||||
SHARED_LOGGER
|
SHARED_LOGGER
|
||||||
@@ -17,7 +16,7 @@ create
|
|||||||
|
|
||||||
feature {NONE} -- Intialization
|
feature {NONE} -- Intialization
|
||||||
|
|
||||||
data_reader (a_query: STRING; a_parameters: STRING_TABLE [detachable ANY])
|
data_reader (a_query: STRING; a_parameters: like parameters)
|
||||||
-- SQL data reader for the query `a_query' with arguments `a_parameters'
|
-- SQL data reader for the query `a_query' with arguments `a_parameters'
|
||||||
do
|
do
|
||||||
log.write_information (generator + ".data_reader" + " execute query: " + a_query)
|
log.write_information (generator + ".data_reader" + " execute query: " + a_query)
|
||||||
@@ -65,7 +64,7 @@ feature -- Access
|
|||||||
query: STRING
|
query: STRING
|
||||||
-- SQL query to execute.
|
-- SQL query to execute.
|
||||||
|
|
||||||
parameters: STRING_TABLE [detachable ANY]
|
parameters: detachable STRING_TABLE [detachable ANY]
|
||||||
-- query parameters.
|
-- query parameters.
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
@@ -73,26 +72,24 @@ feature {NONE} -- Implementation
|
|||||||
set_map_name (a_base_selection: DB_EXPRESSION)
|
set_map_name (a_base_selection: DB_EXPRESSION)
|
||||||
-- Store parameters `item' and their `key'.
|
-- Store parameters `item' and their `key'.
|
||||||
do
|
do
|
||||||
from
|
if attached parameters as l_parameters then
|
||||||
parameters.start
|
across
|
||||||
until
|
l_parameters as ic
|
||||||
parameters.after
|
loop
|
||||||
loop
|
a_base_selection.set_map_name (ic.item, ic.key)
|
||||||
a_base_selection.set_map_name (parameters.item_for_iteration, parameters.key_for_iteration)
|
end
|
||||||
parameters.forth
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
unset_map_name (a_base_selection: DB_EXPRESSION)
|
unset_map_name (a_base_selection: DB_EXPRESSION)
|
||||||
-- Remove parameters item associated with key `key'.
|
-- Remove parameters item associated with key `key'.
|
||||||
do
|
do
|
||||||
from
|
if attached parameters as l_parameters then
|
||||||
parameters.start
|
across
|
||||||
until
|
l_parameters as ic
|
||||||
parameters.after
|
loop
|
||||||
loop
|
a_base_selection.unset_map_name (ic.key)
|
||||||
a_base_selection.unset_map_name (parameters.key_for_iteration)
|
end
|
||||||
parameters.forth
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -101,26 +98,25 @@ feature {NONE} -- Implementation
|
|||||||
-- exclude sensitive information.
|
-- exclude sensitive information.
|
||||||
do
|
do
|
||||||
create Result.make_empty
|
create Result.make_empty
|
||||||
from
|
if a_parameters /= Void then
|
||||||
a_parameters.start
|
across
|
||||||
until
|
a_parameters as ic
|
||||||
a_parameters.after
|
loop
|
||||||
loop
|
Result.append ("name:")
|
||||||
Result.append ("name:")
|
Result.append (ic.key.as_string_32)
|
||||||
Result.append (a_parameters.key_for_iteration.as_string_32)
|
Result.append (", value:")
|
||||||
Result.append (", value:")
|
if
|
||||||
if
|
ic.key.has_substring ("Password") or else
|
||||||
a_parameters.key_for_iteration.has_substring ("Password") or else
|
ic.key.has_substring ("password")
|
||||||
a_parameters.key_for_iteration.has_substring ("password")
|
then
|
||||||
then
|
-- Data to exclude
|
||||||
-- Data to exclude
|
else
|
||||||
else
|
if attached ic.item as l_item then
|
||||||
if attached a_parameters.item_for_iteration as l_item then
|
Result.append (l_item.out)
|
||||||
Result.append (l_item.out)
|
end
|
||||||
end
|
end
|
||||||
|
Result.append ("%N")
|
||||||
end
|
end
|
||||||
Result.append ("%N")
|
|
||||||
a_parameters.forth
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ note
|
|||||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
||||||
revision: "$Revision: 95678 $"
|
revision: "$Revision: 95678 $"
|
||||||
EIS: "SQL server injection", "src=http://blogs.msdn.com/b/raulga/archive/2007/01/04/dynamic-sql-sql-injection.aspx", "protocol=url"
|
EIS: "SQL server injection", "src=http://blogs.msdn.com/b/raulga/archive/2007/01/04/dynamic-sql-sql-injection.aspx", "protocol=url"
|
||||||
|
|
||||||
expanded class
|
expanded class
|
||||||
DATABASE_SQL_SERVER_ENCODER
|
DATABASE_SQL_SERVER_ENCODER
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@ inherit
|
|||||||
|
|
||||||
feature -- Escape SQL input
|
feature -- Escape SQL input
|
||||||
|
|
||||||
encode (a_string:READABLE_STRING_32): READABLE_STRING_32
|
encode (a_string: READABLE_STRING_32): READABLE_STRING_32
|
||||||
-- Escape single quote (') and braces ([,]).
|
-- Escape single quote (') and braces ([,]).
|
||||||
local
|
local
|
||||||
l_string: STRING
|
l_string: STRING
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Error from database"
|
description: "Error from database"
|
||||||
date: "$Date: 2013-08-08 16:39:49 -0300 (ju. 08 de ago. de 2013) $"
|
date: "$Date: 2014-11-13 16:23:47 +0100 (jeu., 13 nov. 2014) $"
|
||||||
revision: "$Revision: 195 $"
|
revision: "$Revision: 96085 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
DATABASE_ERROR
|
DATABASE_ERROR
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Database error handler"
|
description: "Database error handler"
|
||||||
date: "$Date: 2013-08-08 16:39:49 -0300 (ju. 08 de ago. de 2013) $"
|
date: "$Date: 2014-11-13 16:23:47 +0100 (jeu., 13 nov. 2014) $"
|
||||||
revision: "$Revision: 195 $"
|
revision: "$Revision: 96085 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
DATABASE_ERROR_HANDLER
|
DATABASE_ERROR_HANDLER
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {DATABASE_NO_CHANGE_ERROR}."
|
description: "Summary description for {DATABASE_NO_CHANGE_ERROR}."
|
||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date: 2014-11-13 16:23:47 +0100 (jeu., 13 nov. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96085 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
DATABASE_NO_CHANGE_ERROR
|
DATABASE_NO_CHANGE_ERROR
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {STRING_HELPER}."
|
|
||||||
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
|
|
||||||
revision: "$Revision: 95593 $"
|
|
||||||
|
|
||||||
class
|
|
||||||
STRING_HELPER
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
is_blank (s: detachable READABLE_STRING_32): BOOLEAN
|
|
||||||
local
|
|
||||||
i,n: INTEGER
|
|
||||||
do
|
|
||||||
Result := True
|
|
||||||
if s /= Void then
|
|
||||||
from
|
|
||||||
i := 1
|
|
||||||
n := s.count
|
|
||||||
until
|
|
||||||
i > n or not Result
|
|
||||||
loop
|
|
||||||
Result := s[i].is_space
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
indented_text (pre: READABLE_STRING_8; t: READABLE_STRING_8): READABLE_STRING_8
|
|
||||||
-- Indendted text.
|
|
||||||
local
|
|
||||||
s8: STRING_8
|
|
||||||
do
|
|
||||||
s8 := t.string
|
|
||||||
s8.prepend (pre)
|
|
||||||
s8.replace_substring_all ("%N", "%N" + pre)
|
|
||||||
Result := s8
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
json_encode (a_string: STRING): STRING
|
|
||||||
-- json encode `a_string'.
|
|
||||||
local
|
|
||||||
encode: SHARED_JSON_ENCODER
|
|
||||||
do
|
|
||||||
create encode
|
|
||||||
Result := encode.json_encoder.encoded_string (a_string)
|
|
||||||
debug
|
|
||||||
print ("%NResult" + Result)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -7,18 +7,23 @@
|
|||||||
</option>
|
</option>
|
||||||
<setting name="console_application" value="true"/>
|
<setting name="console_application" value="true"/>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
|
<library name="cms" location="..\..\..\..\cms-safe.ecf"/>
|
||||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
||||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
||||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
|
||||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
||||||
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
||||||
<library name="layout" location="..\..\..\layout\layout-safe.ecf"/>
|
<library name="layout" location="..\..\..\layout\layout-safe.ecf"/>
|
||||||
<library name="model" location="..\..\..\model\cms_model-safe.ecf"/>
|
|
||||||
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/>
|
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/>
|
||||||
|
<library name="model" location="..\..\..\model\cms_model-safe.ecf"/>
|
||||||
<library name="mysql" location="$ISE_LIBRARY\library\store\dbms\rdbms\mysql\mysql-safe.ecf"/>
|
<library name="mysql" location="$ISE_LIBRARY\library\store\dbms\rdbms\mysql\mysql-safe.ecf"/>
|
||||||
<library name="store" location="$ISE_LIBRARY\library\store\store-safe.ecf" readonly="false"/>
|
<library name="store" location="$ISE_LIBRARY\library\store\store-safe.ecf" readonly="false"/>
|
||||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||||
|
<cluster name="common" location="..\common\" recursive="true">
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/database/database_connection_odbc.e</exclude>
|
||||||
|
</file_rule>
|
||||||
|
</cluster>
|
||||||
<cluster name="persistence_mysql" location=".\src\" recursive="true">
|
<cluster name="persistence_mysql" location=".\src\" recursive="true">
|
||||||
<file_rule>
|
<file_rule>
|
||||||
<exclude>/EIFGENs$</exclude>
|
<exclude>/EIFGENs$</exclude>
|
||||||
@@ -26,12 +31,5 @@
|
|||||||
<exclude>/.svn$</exclude>
|
<exclude>/.svn$</exclude>
|
||||||
</file_rule>
|
</file_rule>
|
||||||
</cluster>
|
</cluster>
|
||||||
<cluster name="interface" location="..\..\interface\" recursive="true"/>
|
|
||||||
<cluster name="common" location="..\common\" recursive="true">
|
|
||||||
<file_rule>
|
|
||||||
<exclude>/database/database_connection_odbc.e</exclude>
|
|
||||||
</file_rule>
|
|
||||||
</cluster>
|
|
||||||
|
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="persistence_mysql" uuid="DC757CBD-D8C4-44D6-A07F-C1148D8D233E" library_target="persistence_mysql">
|
||||||
|
<target name="persistence_mysql">
|
||||||
|
<root all_classes="true"/>
|
||||||
|
<option warning="true" void_safety="none">
|
||||||
|
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||||
|
</option>
|
||||||
|
<setting name="console_application" value="true"/>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
|
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
|
||||||
|
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
|
||||||
|
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
||||||
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||||
|
<library name="layout" location="..\..\..\layout\layout.ecf"/>
|
||||||
|
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>
|
||||||
|
<library name="model" location="..\..\..\model\cms_model.ecf"/>
|
||||||
|
<library name="mysql" location="$ISE_LIBRARY\library\store\dbms\rdbms\mysql\mysql.ecf"/>
|
||||||
|
<library name="store" location="$ISE_LIBRARY\library\store\store.ecf" readonly="false"/>
|
||||||
|
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
|
||||||
|
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||||
|
<cluster name="common" location="..\common\" recursive="true">
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/database/database_connection_odbc.e</exclude>
|
||||||
|
</file_rule>
|
||||||
|
</cluster>
|
||||||
|
<cluster name="interface" location="..\..\interface\" recursive="true"/>
|
||||||
|
<cluster name="persistence_mysql" location=".\src\" recursive="true">
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/CVS$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
</cluster>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_NODE_STORAGE_MYSQL}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_NODE_STORAGE_MYSQL
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_NODE_STORAGE_SQL
|
||||||
|
redefine
|
||||||
|
nodes, recent_nodes
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
db_handler: DATABASE_HANDLER
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
nodes: LIST [CMS_NODE]
|
||||||
|
-- List of nodes.
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||||
|
across nodes_iterator as ic loop
|
||||||
|
Result.force (ic.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
||||||
|
-- List of recent `a_count' nodes with an offset of `lower'.
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_count)
|
||||||
|
across recent_nodes_iterator (a_lower, a_count) as c loop
|
||||||
|
Result.force (c.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access: iterator
|
||||||
|
|
||||||
|
nodes_iterator: DATABASE_ITERATION_CURSOR [CMS_NODE]
|
||||||
|
-- List of nodes.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".nodes_iterator")
|
||||||
|
create l_parameters.make (0)
|
||||||
|
sql_query (select_nodes, l_parameters)
|
||||||
|
create Result.make (db_handler, agent fetch_node)
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
recent_nodes_iterator (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [CMS_NODE]
|
||||||
|
-- The most recent `a_rows'.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
l_query: STRING
|
||||||
|
do
|
||||||
|
-- FIXME: check implementation...
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".recent_nodes_iterator")
|
||||||
|
create l_parameters.make (2)
|
||||||
|
l_parameters.put (a_rows, "rows")
|
||||||
|
l_parameters.put (a_lower, "offset")
|
||||||
|
create l_query.make_from_string (select_recent_nodes)
|
||||||
|
sql_query (l_query, l_parameters)
|
||||||
|
create Result.make (db_handler, agent fetch_node)
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -7,264 +7,106 @@ class
|
|||||||
CMS_STORAGE_MYSQL
|
CMS_STORAGE_MYSQL
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
CMS_STORAGE
|
CMS_STORAGE
|
||||||
|
|
||||||
|
CMS_STORAGE_STORE_SQL
|
||||||
|
|
||||||
|
CMS_USER_STORAGE_MYSQL
|
||||||
|
|
||||||
|
CMS_NODE_STORAGE_MYSQL
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
--feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (a_connection: DATABASE_CONNECTION)
|
-- make (a_connection: DATABASE_CONNECTION)
|
||||||
--
|
-- --
|
||||||
require
|
-- require
|
||||||
is_connected: a_connection.is_connected
|
-- is_connected: a_connection.is_connected
|
||||||
do
|
-- do
|
||||||
connection := a_connection
|
-- connection := a_connection
|
||||||
log.write_information (generator+".make_with_database is database connected? "+ a_connection.is_connected.out )
|
-- log.write_information (generator + ".make - is database connected? "+ a_connection.is_connected.out )
|
||||||
create node_provider.make (a_connection)
|
|
||||||
create user_provider.make (a_connection)
|
|
||||||
create error_handler.make
|
|
||||||
end
|
|
||||||
|
|
||||||
|
-- create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
||||||
|
|
||||||
feature -- Access: user
|
-- create error_handler.make
|
||||||
|
---- error_handler.add_synchronization (db_handler.database_error_handler)
|
||||||
|
-- end
|
||||||
|
|
||||||
has_user: BOOLEAN
|
-- db_handler: DATABASE_HANDLER
|
||||||
-- Has any user?
|
|
||||||
do
|
|
||||||
Result := user_provider.has_user
|
|
||||||
end
|
|
||||||
|
|
||||||
all_users: LIST [CMS_USER]
|
-- connection: DATABASE_CONNECTION
|
||||||
do
|
-- -- Current database connection.
|
||||||
to_implement (generator + ".all_users")
|
|
||||||
create {ARRAYED_LIST[CMS_USER]} Result.make (0)
|
|
||||||
end
|
|
||||||
|
|
||||||
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
|
--feature -- Query
|
||||||
do
|
|
||||||
Result := user_provider.user (a_id)
|
|
||||||
|
|
||||||
end
|
-- sql_post_execution
|
||||||
|
-- -- Post database execution.
|
||||||
|
-- do
|
||||||
|
-- error_handler.append (db_handler.database_error_handler)
|
||||||
|
-- if error_handler.has_error then
|
||||||
|
-- log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
|
-- sql_begin_transaction
|
||||||
do
|
-- do
|
||||||
Result := user_provider.user_by_name (a_name)
|
-- connection.begin_transaction
|
||||||
|
-- end
|
||||||
|
|
||||||
end
|
-- sql_commit_transaction
|
||||||
|
-- do
|
||||||
|
-- connection.commit
|
||||||
|
-- end
|
||||||
|
|
||||||
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
|
-- sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
do
|
-- do
|
||||||
Result := user_provider.user_by_email (a_email)
|
-- check_sql_query_validity (a_sql_statement, a_params)
|
||||||
|
-- db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
|
||||||
|
-- db_handler.execute_query
|
||||||
|
-- end
|
||||||
|
|
||||||
end
|
-- sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
|
-- do
|
||||||
|
-- check_sql_query_validity (a_sql_statement, a_params)
|
||||||
|
-- db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
|
||||||
|
-- db_handler.execute_change
|
||||||
|
-- end
|
||||||
|
|
||||||
is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN
|
-- sql_rows_count: INTEGER
|
||||||
local
|
-- -- Number of rows for last sql execution.
|
||||||
l_security: SECURITY_PROVIDER
|
-- do
|
||||||
do
|
-- Result := db_handler.count
|
||||||
if attached user_provider.user_salt (l_auth_login) as l_hash then
|
-- end
|
||||||
if attached user_provider.user_by_name (l_auth_login) as l_user then
|
|
||||||
create l_security
|
|
||||||
if
|
|
||||||
attached l_user.password as l_password and then
|
|
||||||
l_security.password_hash (l_auth_password, l_hash).is_case_insensitive_equal (l_password)
|
|
||||||
then
|
|
||||||
Result := True
|
|
||||||
else
|
|
||||||
log.write_information (generator + ".login_valid User: wrong username or password" )
|
|
||||||
end
|
|
||||||
else
|
|
||||||
log.write_information (generator + ".login_valid User:" + l_auth_login + "does not exist" )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
-- sql_start
|
||||||
|
-- -- Set the cursor on first element.
|
||||||
|
-- do
|
||||||
|
-- db_handler.start
|
||||||
|
-- end
|
||||||
|
|
||||||
feature -- User Nodes
|
-- sql_after: BOOLEAN
|
||||||
|
-- -- Are there no more items to iterate over?
|
||||||
|
-- do
|
||||||
|
-- Result := db_handler.after
|
||||||
|
-- end
|
||||||
|
|
||||||
user_collaborator_nodes (a_id: like {CMS_USER}.id): LIST[CMS_NODE]
|
-- sql_forth
|
||||||
-- Possible list of nodes where the user identified by `a_id', is a collaborator.
|
-- -- Fetch next row from last sql execution, if any.
|
||||||
do
|
-- do
|
||||||
to_implement (generator + ".user_collaborator_nodes")
|
-- db_handler.forth
|
||||||
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
|
-- end
|
||||||
end
|
|
||||||
|
|
||||||
user_author_nodes (a_id: like {CMS_USER}.id): LIST[CMS_NODE]
|
-- sql_item (a_index: INTEGER): detachable ANY
|
||||||
-- Possible list of nodes where the user identified by `a_id', is the author.
|
-- do
|
||||||
do
|
-- if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then
|
||||||
to_implement (generator + ".user_author_nodes")
|
-- Result := l_item.item (a_index)
|
||||||
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
|
-- else
|
||||||
end
|
-- check has_item_at_index: False end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
feature -- Access: roles and permissions
|
|
||||||
|
|
||||||
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
|
||||||
do
|
|
||||||
to_implement (generator + ".user_role_by_id")
|
|
||||||
end
|
|
||||||
|
|
||||||
user_roles: LIST [CMS_USER_ROLE]
|
|
||||||
do
|
|
||||||
to_implement (generator + ".user_roles")
|
|
||||||
create {ARRAYED_LIST[CMS_USER_ROLE]} Result.make (0)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Change: roles and permissions
|
|
||||||
|
|
||||||
save_user_role (a_user_role: CMS_USER_ROLE)
|
|
||||||
do
|
|
||||||
to_implement (generator + ".save_user_role")
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Change: user
|
|
||||||
|
|
||||||
save_user (a_user: CMS_USER)
|
|
||||||
-- Add a new user `a_user'.
|
|
||||||
do
|
|
||||||
|
|
||||||
if
|
|
||||||
attached a_user.password as l_password and then
|
|
||||||
attached a_user.email as l_email
|
|
||||||
then
|
|
||||||
connection.begin_transaction
|
|
||||||
user_provider.new_user (a_user.name, l_password, l_email)
|
|
||||||
connection.commit
|
|
||||||
else
|
|
||||||
debug ("refactor_fixme")
|
|
||||||
fixme ("maybe we should not always carry password, in this case, to implement the else part..")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access: node
|
|
||||||
|
|
||||||
nodes: LIST[CMS_NODE]
|
|
||||||
-- List of nodes.
|
|
||||||
do
|
|
||||||
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
|
|
||||||
across node_provider.nodes as c loop
|
|
||||||
Result.force (c.item)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
|
||||||
-- List of the `a_count' most recent nodes, starting from `a_lower'.
|
|
||||||
do
|
|
||||||
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
|
|
||||||
across node_provider.recent_nodes (a_lower,a_count) as c loop
|
|
||||||
Result.force (c.item)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
node (a_id: INTEGER_64): detachable CMS_NODE
|
|
||||||
-- <Precursor>
|
|
||||||
do
|
|
||||||
Result := node_provider.node (a_id)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
|
|
||||||
-- <Precursor>
|
|
||||||
do
|
|
||||||
Result := node_provider.node_author (a_id)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
node_collaborators (a_id: like {CMS_NODE}.id): LIST [CMS_USER]
|
|
||||||
-- Possible list of node's collaborator.
|
|
||||||
do
|
|
||||||
create {ARRAYED_LIST[CMS_USER]} Result.make (0)
|
|
||||||
across node_provider.node_collaborators (a_id) as c loop Result.force (c.item) end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Node
|
|
||||||
|
|
||||||
save_node (a_node: CMS_NODE)
|
|
||||||
-- <Precursor>
|
|
||||||
do
|
|
||||||
node_provider.new_node (a_node)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
delete_node (a_id: INTEGER_64)
|
|
||||||
do
|
|
||||||
node_provider.delete_from_user_nodes(a_id)
|
|
||||||
node_provider.delete_node (a_id)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node (a_id: like {CMS_USER}.id; a_node: CMS_NODE)
|
|
||||||
-- <Precursor>
|
|
||||||
do
|
|
||||||
node_provider.update_node (a_id, a_node)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_title (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
|
||||||
-- <Precursor>
|
|
||||||
do
|
|
||||||
node_provider.update_node_title (a_node_id, a_title)
|
|
||||||
internal_node_update (a_id, a_node_id)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_summary (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
|
||||||
-- <Precursor>
|
|
||||||
do
|
|
||||||
node_provider.update_node_summary (a_node_id, a_summary)
|
|
||||||
internal_node_update (a_id, a_node_id)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_content (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
|
||||||
-- <Precursor>
|
|
||||||
do
|
|
||||||
node_provider.update_node_content (a_node_id, a_content)
|
|
||||||
internal_node_update (a_id, a_node_id)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- NODE Implemenation
|
|
||||||
|
|
||||||
internal_node_update (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id)
|
|
||||||
-- Update node editor or add collaborator.
|
|
||||||
do
|
|
||||||
if not node_provider.is_collaborator (a_id, a_node_id) then
|
|
||||||
node_provider.add_collaborator (a_id, a_node_id)
|
|
||||||
else
|
|
||||||
node_provider.update_node_last_editor (a_id, a_node_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- User
|
|
||||||
|
|
||||||
new_user (a_user: CMS_USER)
|
|
||||||
-- Add a new user `a_user'.
|
|
||||||
do
|
|
||||||
if
|
|
||||||
attached a_user.password as l_password and then
|
|
||||||
attached a_user.email as l_email
|
|
||||||
then
|
|
||||||
user_provider.new_user (a_user.name, l_password, l_email)
|
|
||||||
else
|
|
||||||
-- set error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Post process
|
|
||||||
|
|
||||||
|
|
||||||
node_provider: NODE_DATA_PROVIDER
|
|
||||||
-- Node Data provider.
|
|
||||||
|
|
||||||
user_provider: USER_DATA_PROVIDER
|
|
||||||
-- User Data provider.
|
|
||||||
|
|
||||||
connection: DATABASE_CONNECTION
|
|
||||||
-- Current database connection.
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Objects that ...
|
||||||
|
]"
|
||||||
|
author: "$Author$"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_STORAGE_MYSQL_BUILDER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_STORAGE_BUILDER
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make
|
||||||
|
-- Initialize `Current'.
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Factory
|
||||||
|
|
||||||
|
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_MYSQL
|
||||||
|
local
|
||||||
|
conn: DATABASE_CONNECTION
|
||||||
|
do
|
||||||
|
if attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.layout.application_config_path) as l_database_config then
|
||||||
|
create {DATABASE_CONNECTION_MYSQL} conn.login_with_connection_string (l_database_config.connection_string)
|
||||||
|
if conn.is_connected then
|
||||||
|
create Result.make (conn)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_USER_STORAGE_MYSQL}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_USER_STORAGE_MYSQL
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_USER_STORAGE_SQL
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,511 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Database access for node uses cases."
|
|
||||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
|
||||||
revision: "$Revision: 95678 $"
|
|
||||||
|
|
||||||
class
|
|
||||||
NODE_DATA_PROVIDER
|
|
||||||
|
|
||||||
inherit
|
|
||||||
|
|
||||||
PARAMETER_NAME_HELPER
|
|
||||||
|
|
||||||
REFACTORING_HELPER
|
|
||||||
|
|
||||||
SHARED_LOGGER
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
feature -- Initialization
|
|
||||||
|
|
||||||
make (a_connection: DATABASE_CONNECTION)
|
|
||||||
-- Create a data provider.
|
|
||||||
do
|
|
||||||
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
|
||||||
create error_handler.make
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
db_handler: DATABASE_HANDLER
|
|
||||||
-- Db handler.
|
|
||||||
|
|
||||||
feature -- Status Report
|
|
||||||
|
|
||||||
is_successful: BOOLEAN
|
|
||||||
-- Is the last execution sucessful?
|
|
||||||
do
|
|
||||||
Result := not error_handler.has_error
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Error Handler
|
|
||||||
|
|
||||||
error_handler: ERROR_HANDLER
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
nodes: DATABASE_ITERATION_CURSOR [CMS_NODE]
|
|
||||||
-- List of nodes.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".nodes")
|
|
||||||
create l_parameters.make (0)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Select_nodes, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make (db_handler, agent fetch_node)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
recent_nodes (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [CMS_NODE]
|
|
||||||
-- The most recent `a_rows'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
l_query: STRING
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".recent_nodes")
|
|
||||||
create l_parameters.make (2)
|
|
||||||
l_parameters.put (a_rows, "rows")
|
|
||||||
create l_query.make_from_string (select_recent_nodes)
|
|
||||||
l_query.replace_substring_all ("$offset", a_lower.out)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (l_query, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make (db_handler, agent fetch_node)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
node (a_id: INTEGER_64): detachable CMS_NODE
|
|
||||||
-- Node for the given id `a_id', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".node")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id,"id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_node_by_id, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := fetch_node
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
count: INTEGER
|
|
||||||
-- Number of items nodes.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".count")
|
|
||||||
create l_parameters.make (0)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_count, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := db_handler.read_integer_32 (1)
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
last_inserted_node_id: INTEGER
|
|
||||||
-- Last insert node id.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".last_inserted_node_id")
|
|
||||||
create l_parameters.make (0)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Sql_last_insert_node_id, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := db_handler.read_integer_32 (1)
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Basic operations
|
|
||||||
|
|
||||||
new_node (a_node: CMS_NODE)
|
|
||||||
-- Create a new node.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".new_node")
|
|
||||||
create l_parameters.make (7)
|
|
||||||
l_parameters.put (a_node.title, "title")
|
|
||||||
l_parameters.put (a_node.summary, "summary")
|
|
||||||
l_parameters.put (a_node.content, "content")
|
|
||||||
l_parameters.put (a_node.publication_date, "publication_date")
|
|
||||||
l_parameters.put (a_node.creation_date, "creation_date")
|
|
||||||
l_parameters.put (a_node.modification_date, "modification_date")
|
|
||||||
if
|
|
||||||
attached a_node.author as l_author and then
|
|
||||||
l_author.id > 0
|
|
||||||
then
|
|
||||||
l_parameters.put (l_author.id, "author_id")
|
|
||||||
end
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_insert_node, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
|
|
||||||
a_node.set_id (last_inserted_node_id)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_title (a_id: INTEGER_64; a_title: READABLE_STRING_32)
|
|
||||||
-- Update node title for the corresponding the report with id `a_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".update_node_title")
|
|
||||||
create l_parameters.make (3)
|
|
||||||
l_parameters.put (a_title, "title")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
|
|
||||||
l_parameters.put (a_id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_update_node_title, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_summary (a_id: INTEGER_64; a_summary: READABLE_STRING_32)
|
|
||||||
-- Update node summary for the corresponding the report with id `a_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".update_node_summary")
|
|
||||||
create l_parameters.make (3)
|
|
||||||
l_parameters.put (a_summary, "summary")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
|
|
||||||
l_parameters.put (a_id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_update_node_summary, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_content (a_id: INTEGER_64; a_content: READABLE_STRING_32)
|
|
||||||
-- Update node content for the corresponding the report with id `a_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".update_node_content")
|
|
||||||
create l_parameters.make (3)
|
|
||||||
l_parameters.put (a_content, "content")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
|
|
||||||
l_parameters.put (a_id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_update_node_content, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node (a_id: like {CMS_USER}.id; a_node: CMS_NODE)
|
|
||||||
-- Update node.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".update_node")
|
|
||||||
create l_parameters.make (7)
|
|
||||||
l_parameters.put (a_node.title, "title")
|
|
||||||
l_parameters.put (a_node.summary, "summary")
|
|
||||||
l_parameters.put (a_node.content, "content")
|
|
||||||
l_parameters.put (a_node.publication_date, "publication_date")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
|
|
||||||
l_parameters.put (a_node.id, "id")
|
|
||||||
l_parameters.put (a_id, "editor")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_update_node, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
delete_node (a_id: INTEGER_64;)
|
|
||||||
-- Delete node with id `a_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".delete_node")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_delete_node, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
delete_from_user_nodes (a_id: INTEGER_64)
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".delete_from_user_nodes")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_delete_from_user_node, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Basic Operations: User_Nodes
|
|
||||||
|
|
||||||
add_author (a_user_id: INTEGER_64; a_node_id: INTEGER_64)
|
|
||||||
-- Add author `a_user_id' to node `a_node_id'
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".add_author")
|
|
||||||
create l_parameters.make (2)
|
|
||||||
l_parameters.put (a_user_id,"user_id")
|
|
||||||
l_parameters.put (a_node_id,"id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Sql_update_node_author, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
add_collaborator (a_user_id: INTEGER_64; a_node_id: INTEGER_64)
|
|
||||||
-- Add collaborator `a_user_id' to node `a_node_id'
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".add_collaborator")
|
|
||||||
create l_parameters.make (2)
|
|
||||||
l_parameters.put (a_user_id,"users_id")
|
|
||||||
l_parameters.put (a_node_id,"nodes_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Sql_insert_users_nodes, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_last_editor (a_user_id: INTEGER_64; a_node_id: INTEGER_64)
|
|
||||||
-- Update node last editor.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".add_collaborator")
|
|
||||||
create l_parameters.make (2)
|
|
||||||
l_parameters.put (a_user_id,"users_id")
|
|
||||||
l_parameters.put (a_node_id,"nodes_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Slq_update_editor, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
author_nodes (a_id:INTEGER_64): DATABASE_ITERATION_CURSOR [CMS_NODE]
|
|
||||||
-- List of Nodes for the given user `a_id'. (the user is the author of the node)
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".author_nodes")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id, "user_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Select_user_author, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make (db_handler, agent fetch_node)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
collaborator_nodes (a_id:INTEGER_64): DATABASE_ITERATION_CURSOR [CMS_NODE]
|
|
||||||
-- List of Nodes for the given user `a_id' as collaborator.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".collaborator_nodes")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id, "user_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Select_user_collaborator, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make (db_handler, agent fetch_node)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
node_author (a_id: INTEGER_64): detachable CMS_USER
|
|
||||||
-- Node's author for the given node id.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".node_author")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id, "node_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_node_author, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if not db_handler.after then
|
|
||||||
Result := fetch_user
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
node_collaborators (a_id: INTEGER_64): DATABASE_ITERATION_CURSOR [CMS_USER]
|
|
||||||
-- List of possible node's collaborator.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".node_collaborators")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id, "node_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_node_collaborators, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make (db_handler, agent fetch_user)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
is_collaborator (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id): BOOLEAN
|
|
||||||
-- Is the user `a_user_id' a collaborator of node `a_node_id'
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".node_collaborators")
|
|
||||||
create l_parameters.make (2)
|
|
||||||
l_parameters.put (a_user_id, "user_id")
|
|
||||||
l_parameters.put (a_node_id, "node_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_exist_user_node, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := db_handler.read_integer_32 (1) = 1
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Connection
|
|
||||||
|
|
||||||
connect
|
|
||||||
-- Connect to the database.
|
|
||||||
do
|
|
||||||
if not db_handler.is_connected then
|
|
||||||
db_handler.connect
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
disconnect
|
|
||||||
-- Disconnect to the database.
|
|
||||||
do
|
|
||||||
if db_handler.is_connected then
|
|
||||||
db_handler.disconnect
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Queries
|
|
||||||
|
|
||||||
Select_count: STRING = "select count(*) from Nodes;"
|
|
||||||
|
|
||||||
Select_nodes: STRING = "select * from Nodes;"
|
|
||||||
-- SQL Query to retrieve all nodes.
|
|
||||||
|
|
||||||
Select_node_by_id: STRING = "select * from Nodes where id =:id order by id desc, publication_date desc;"
|
|
||||||
|
|
||||||
Select_recent_nodes: STRING = "select * from Nodes order by id desc, publication_date desc Limit $offset , :rows "
|
|
||||||
|
|
||||||
SQL_Insert_node: STRING = "insert into nodes (title, summary, content, publication_date, creation_date, modification_date, author_id) values (:title, :summary, :content, :publication_date, :creation_date, :modification_date, :author_id);"
|
|
||||||
-- SQL Insert to add a new node.
|
|
||||||
|
|
||||||
SQL_Update_node_title: STRING ="update nodes SET title=:title, modification_date=:modification_date, version = version + 1 where id=:id;"
|
|
||||||
-- SQL update node title.
|
|
||||||
|
|
||||||
SQL_Update_node_summary: STRING ="update nodes SET summary=:summary, modification_date=:modification_date, version = version + 1 where id=:id;"
|
|
||||||
-- SQL update node summary.
|
|
||||||
|
|
||||||
SQL_Update_node_content: STRING ="update nodes SET content=:content, modification_date=:modification_date, version = version + 1 where id=:id;"
|
|
||||||
-- SQL node content.
|
|
||||||
|
|
||||||
Slq_update_editor: STRING ="update nodes SET editor_id=:users_id where id=:nodes_id;"
|
|
||||||
-- SQL node content.
|
|
||||||
|
|
||||||
SQL_Update_node : STRING = "update nodes SET title=:title, summary=:summary, content=:content, publication_date=:publication_date, modification_date=:modification_date, version = version + 1, editor_id=:editor where id=:id;"
|
|
||||||
-- SQL node.
|
|
||||||
|
|
||||||
SQL_Delete_node: STRING = "delete from nodes where id=:id;"
|
|
||||||
|
|
||||||
Sql_update_node_author: STRING = "update nodes SET author_id=:user_id where id=:id;"
|
|
||||||
|
|
||||||
Sql_last_insert_node_id: STRING = "SELECT MAX(id) from nodes;"
|
|
||||||
|
|
||||||
feature {NONE} -- Sql Queries: USER_ROLES collaborators, author
|
|
||||||
|
|
||||||
Sql_insert_users_nodes: STRING = "insert into users_nodes (users_id, nodes_id) values (:users_id, :nodes_id);"
|
|
||||||
|
|
||||||
select_node_collaborators: STRING = "SELECT * FROM Users INNER JOIN users_nodes ON users.id=users_nodes.users_id and users_nodes.nodes_id = :node_id;"
|
|
||||||
|
|
||||||
Select_user_author: STRING = "SELECT * FROM Nodes INNER JOIN users ON nodes.author_id=users.id and users.id = :user_id;"
|
|
||||||
|
|
||||||
Select_node_author: STRING = "SELECT * FROM Users INNER JOIN nodes ON nodes.author_id=users.id and nodes.id =:node_id;"
|
|
||||||
|
|
||||||
Select_user_collaborator: STRING = "SELECT * FROM Nodes INNER JOIN users_nodes ON users_nodes.nodes_id = nodes.id and users_nodes.users_id = :user_id;"
|
|
||||||
|
|
||||||
Select_exist_user_node: STRING= "Select Count(*) from Users_nodes where users_id=:user_id and nodes_id=:node_id;"
|
|
||||||
|
|
||||||
sql_delete_from_user_node: STRING = "delete from users_nodes where nodes_id=:id"
|
|
||||||
|
|
||||||
|
|
||||||
feature --
|
|
||||||
|
|
||||||
|
|
||||||
feature -- New Object
|
|
||||||
|
|
||||||
fetch_node: CMS_NODE
|
|
||||||
do
|
|
||||||
create Result.make ("", "", "")
|
|
||||||
if attached db_handler.read_integer_32 (1) as l_id then
|
|
||||||
Result.set_id (l_id)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_date_time (2) as l_pd then
|
|
||||||
Result.set_publication_date (l_pd)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_date_time (3) as l_cd then
|
|
||||||
Result.set_creation_date (l_cd)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_date_time (4) as l_md then
|
|
||||||
Result.set_modification_date (l_md)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (5) as l_t then
|
|
||||||
Result.set_title (l_t)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (6) as l_s then
|
|
||||||
Result.set_summary (l_s)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (7) as l_c then
|
|
||||||
Result.set_content (l_c)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
fetch_user: CMS_USER
|
|
||||||
do
|
|
||||||
create Result.make ("")
|
|
||||||
if attached db_handler.read_integer_32 (1) as l_id then
|
|
||||||
Result.set_id (l_id)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (2) as l_u then
|
|
||||||
Result.set_name (l_u)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (3) as l_p then
|
|
||||||
Result.set_password (l_p)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (5) as l_e then
|
|
||||||
Result.set_email (l_e)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
post_execution
|
|
||||||
-- Post database execution.
|
|
||||||
do
|
|
||||||
error_handler.add_synchronization (db_handler.database_error_handler)
|
|
||||||
if error_handler.has_error then
|
|
||||||
log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {ROLE_DATA_PROVIDER}."
|
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
ROLE_DATA_PROVIDER
|
|
||||||
|
|
||||||
inherit
|
|
||||||
|
|
||||||
PARAMETER_NAME_HELPER
|
|
||||||
|
|
||||||
SHARED_ERROR
|
|
||||||
|
|
||||||
REFACTORING_HELPER
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
feature -- Initialization
|
|
||||||
|
|
||||||
make (a_connection: DATABASE_CONNECTION)
|
|
||||||
-- Create a data provider.
|
|
||||||
do
|
|
||||||
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
db_handler: DATABASE_HANDLER
|
|
||||||
-- Db handler.
|
|
||||||
|
|
||||||
feature -- Status Report
|
|
||||||
|
|
||||||
is_successful: BOOLEAN
|
|
||||||
-- Is the last execution sucessful?
|
|
||||||
do
|
|
||||||
-- Result := db_handler.successful
|
|
||||||
end
|
|
||||||
|
|
||||||
has_roles: BOOLEAN
|
|
||||||
-- Has any role?
|
|
||||||
do
|
|
||||||
Result := count > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
roles: DATABASE_ITERATION_CURSOR [CMS_USER_ROLE]
|
|
||||||
-- List of roles.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".roles")
|
|
||||||
create l_parameters.make (0)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Select_roles, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make (db_handler, agent fetch_role)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Basic Operations
|
|
||||||
|
|
||||||
new_role (a_role: READABLE_STRING_32)
|
|
||||||
-- Create a new node.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".new_role")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_role,"name")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_insert_role, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
role (a_id: INTEGER_64): detachable CMS_USER_ROLE
|
|
||||||
-- Role for the given id `a_id', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".role")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id,"id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_role_by_id, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := fetch_role
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
role_by_name (a_name: READABLE_STRING_32): detachable CMS_USER_ROLE
|
|
||||||
-- Role for the given name `a_name', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".role_by_name")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_name,"name")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_role_by_name, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := fetch_role
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
count: INTEGER
|
|
||||||
-- Number of items users.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".count")
|
|
||||||
create l_parameters.make (0)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_count, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := db_handler.read_integer_32 (1)
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
save_role_permission (a_role_id: INTEGER; a_permission: READABLE_STRING_32)
|
|
||||||
-- Add permission `a_permission' to the role id `a_role_id'.
|
|
||||||
require
|
|
||||||
valid_id: a_role_id > 0
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".save_role_permission")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_permission,"name")
|
|
||||||
l_parameters.put (a_role_id,"id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (SQL_Insert_permissions, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
permission_by_role (a_role_id: INTEGER_64): DATABASE_ITERATION_CURSOR [READABLE_STRING_32]
|
|
||||||
-- List of permission by role `a_role_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".permission_by_role")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_role_id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Select_permissions, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make (db_handler, agent fetch_permission)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- New Object
|
|
||||||
|
|
||||||
fetch_role: CMS_USER_ROLE
|
|
||||||
do
|
|
||||||
create Result.make_with_id (0,"")
|
|
||||||
if attached db_handler.read_integer_32 (1) as l_id then
|
|
||||||
Result.set_id (l_id)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (2) as l_u then
|
|
||||||
Result.set_name (l_u)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
fetch_permission: STRING_32
|
|
||||||
do
|
|
||||||
create Result.make_empty
|
|
||||||
if attached db_handler.read_string (1) as l_u then
|
|
||||||
Result := l_u
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature {NONE} -- Sql Queries: Roles
|
|
||||||
|
|
||||||
Select_count: STRING = "select count(*) from Roles;"
|
|
||||||
-- Number of roles.
|
|
||||||
|
|
||||||
Select_roles: STRING = "select * from Roles;"
|
|
||||||
-- roles.
|
|
||||||
|
|
||||||
Select_role_by_id: STRING = "select * from Roles where id =:id;"
|
|
||||||
-- Retrieve role by id if exists.
|
|
||||||
|
|
||||||
Select_role_by_name: STRING = "select * from Roles where role =:name;"
|
|
||||||
-- Retrieve user by name if exists.
|
|
||||||
|
|
||||||
SQL_Insert_role: STRING = "insert into roles (role) values (:name);"
|
|
||||||
-- SQL Insert to add a new node.
|
|
||||||
|
|
||||||
|
|
||||||
feature {NONE} -- Sql Queries: Permissions
|
|
||||||
|
|
||||||
Select_permissions_count: STRING = "select count(*) from permissions where roles_id=:id;"
|
|
||||||
-- Number of permissions for a given role.
|
|
||||||
|
|
||||||
Select_permissions: STRING = "select * from permissions where roles_id=:id;"
|
|
||||||
-- List of permissions for a given role.
|
|
||||||
|
|
||||||
Select_permissions_by_id: STRING = "select name from permissions where roles_id=:id and id=:permissionid;"
|
|
||||||
-- Permission for a given role and permission id
|
|
||||||
|
|
||||||
SQL_Insert_permissions: STRING = "insert into permissions (name, roles_id) values (:name, :id);"
|
|
||||||
-- SQL Insert to add a new node.
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
post_execution
|
|
||||||
-- Post database execution.
|
|
||||||
do
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {USER_DATA_PROVIDER}."
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
USER_DATA_PROVIDER
|
|
||||||
|
|
||||||
inherit
|
|
||||||
|
|
||||||
PARAMETER_NAME_HELPER
|
|
||||||
|
|
||||||
REFACTORING_HELPER
|
|
||||||
|
|
||||||
SHARED_LOGGER
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
feature -- Initialization
|
|
||||||
|
|
||||||
make (a_connection: DATABASE_CONNECTION)
|
|
||||||
-- Create a data provider.
|
|
||||||
do
|
|
||||||
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
|
||||||
create error_handler.make
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
db_handler: DATABASE_HANDLER
|
|
||||||
-- Db handler.
|
|
||||||
|
|
||||||
feature -- Error Handler
|
|
||||||
|
|
||||||
error_handler: ERROR_HANDLER
|
|
||||||
|
|
||||||
|
|
||||||
feature -- Status Report
|
|
||||||
|
|
||||||
is_successful: BOOLEAN
|
|
||||||
-- Is the last execution sucessful?
|
|
||||||
do
|
|
||||||
Result := not error_handler.has_error
|
|
||||||
end
|
|
||||||
|
|
||||||
has_user: BOOLEAN
|
|
||||||
-- Has any user?
|
|
||||||
do
|
|
||||||
Result := count > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Basic Operations
|
|
||||||
|
|
||||||
new_user (a_user_name: READABLE_STRING_32; a_password: READABLE_STRING_32; a_email: READABLE_STRING_32)
|
|
||||||
-- Create a new node.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
l_password_salt, l_password_hash: STRING
|
|
||||||
l_security: SECURITY_PROVIDER
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
create l_security
|
|
||||||
l_password_salt := l_security.salt
|
|
||||||
l_password_hash := l_security.password_hash (a_password, l_password_salt)
|
|
||||||
|
|
||||||
log.write_information (generator + ".new_user")
|
|
||||||
create l_parameters.make (4)
|
|
||||||
l_parameters.put (a_user_name,"username")
|
|
||||||
l_parameters.put (l_password_hash,"password")
|
|
||||||
l_parameters.put (l_password_salt,"salt")
|
|
||||||
l_parameters.put (a_email,"email")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_insert_user, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
user (a_id: INTEGER_64): detachable CMS_USER
|
|
||||||
-- User for the given id `a_id', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".user")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id,"id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_user_by_id, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := fetch_user
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
user_by_name (a_name: READABLE_STRING_32): detachable CMS_USER
|
|
||||||
-- User for the given name `a_name', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".user_by_name")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_name,"name")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_user_by_name, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := fetch_user
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
user_by_email (a_email: detachable READABLE_STRING_32): detachable CMS_USER
|
|
||||||
-- User for the given email `a_email', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".user_by_email")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_email,"email")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_user_by_email, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := fetch_user
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
user_salt (a_username: READABLE_STRING_32): detachable READABLE_STRING_32
|
|
||||||
-- User salt for the given user `a_username', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".user_salt")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_username,"name")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_salt_by_username, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
if attached db_handler.read_string (1) as l_salt then
|
|
||||||
Result := l_salt.as_string_32
|
|
||||||
end
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
count: INTEGER
|
|
||||||
-- Number of items users.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".count")
|
|
||||||
create l_parameters.make (0)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_count, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := db_handler.read_integer_32 (1)
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Basic operations: User Roles
|
|
||||||
|
|
||||||
add_role (a_user_id: INTEGER; a_role_id: INTEGER)
|
|
||||||
-- Add Role `a_role_id' to user `a_user_id'
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".add_role")
|
|
||||||
create l_parameters.make (2)
|
|
||||||
l_parameters.put (a_user_id,"users_id")
|
|
||||||
l_parameters.put (a_role_id,"roles_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (slq_insert_users_roles, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
user_roles (a_id:INTEGER_64): DATABASE_ITERATION_CURSOR [INTEGER]
|
|
||||||
-- List of Roles id for the given user `a_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".user_roles")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id, "user_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Select_user_roles, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make (db_handler, agent fetch_role_id)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature -- Basic operations: User Profiles
|
|
||||||
|
|
||||||
save_profile_item (a_user_id: INTEGER_64; a_key: READABLE_STRING_32; a_value: READABLE_STRING_32)
|
|
||||||
-- Save a profile item with (a_key and a_value) to the given user `user_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".save_profile_item")
|
|
||||||
create l_parameters.make (3)
|
|
||||||
l_parameters.put (a_key, "key")
|
|
||||||
l_parameters.put (a_value, "value")
|
|
||||||
l_parameters.put (a_user_id, "users_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Select_instert_profile_item, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
save_profile (a_user_id: INTEGER_64; a_user_profile: CMS_USER_PROFILE)
|
|
||||||
-- Save a profile item with (a_key and a_value) to the given user `user_id'.
|
|
||||||
local
|
|
||||||
l_cursor: TABLE_ITERATION_CURSOR [READABLE_STRING_8, READABLE_STRING_GENERAL]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".save_profile")
|
|
||||||
from
|
|
||||||
l_cursor := a_user_profile.new_cursor
|
|
||||||
until
|
|
||||||
l_cursor.after
|
|
||||||
loop
|
|
||||||
save_profile_item (a_user_id, l_cursor.key.as_string_32, l_cursor.item)
|
|
||||||
l_cursor.forth
|
|
||||||
end
|
|
||||||
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
user_profile (a_user_id: INTEGER_64): CMS_USER_PROFILE
|
|
||||||
-- User profile for a user with id `a_user_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
error_handler.reset
|
|
||||||
log.write_information (generator + ".user_profile")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_user_id, "users_id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Select_user_profile, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make
|
|
||||||
if not db_handler.after then
|
|
||||||
from
|
|
||||||
db_handler.start
|
|
||||||
until
|
|
||||||
db_handler.after
|
|
||||||
loop
|
|
||||||
if
|
|
||||||
attached db_handler.read_string (1) as l_key and then
|
|
||||||
attached db_handler.read_string (2) as l_value
|
|
||||||
then
|
|
||||||
Result.force (l_value, l_key)
|
|
||||||
end
|
|
||||||
db_handler.forth
|
|
||||||
end
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature -- New Object
|
|
||||||
|
|
||||||
fetch_user: CMS_USER
|
|
||||||
do
|
|
||||||
create Result.make ("")
|
|
||||||
if attached db_handler.read_integer_32 (1) as l_id then
|
|
||||||
Result.set_id (l_id)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (2) as l_u then
|
|
||||||
Result.set_name (l_u)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (3) as l_p then
|
|
||||||
Result.set_password (l_p)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (5) as l_e then
|
|
||||||
Result.set_email (l_e)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
fetch_role_id: INTEGER
|
|
||||||
do
|
|
||||||
if attached db_handler.read_integer_32 (1) as l_id then
|
|
||||||
Result := l_id
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Sql Queries: USER
|
|
||||||
|
|
||||||
Select_count: STRING = "select count(*) from Users;"
|
|
||||||
-- Number of users.
|
|
||||||
|
|
||||||
Select_user_by_id: STRING = "select * from Users where id =:id;"
|
|
||||||
-- Retrieve user by id if exists.
|
|
||||||
|
|
||||||
Select_user_by_name: STRING = "select * from Users where username =:name;"
|
|
||||||
-- Retrieve user by name if exists.
|
|
||||||
|
|
||||||
Select_user_by_email: STRING = "select * from Users where email =:email;"
|
|
||||||
-- Retrieve user by email if exists.
|
|
||||||
|
|
||||||
Select_salt_by_username: STRING = "select salt from Users where username =:name;"
|
|
||||||
-- Retrieve salt by username if exists.
|
|
||||||
|
|
||||||
SQL_Insert_user: STRING = "insert into users (username, password, salt, email) values (:username, :password, :salt, :email);"
|
|
||||||
-- SQL Insert to add a new node.
|
|
||||||
|
|
||||||
|
|
||||||
feature {NONE} -- Sql Queries: USER_ROLES
|
|
||||||
|
|
||||||
Slq_insert_users_roles: STRING = "insert into users_roles (users_id, roles_id) values (:users_id, :roles_id);"
|
|
||||||
|
|
||||||
Select_user_roles: STRING = "Select roles_id from users_roles where users_id = :user_id"
|
|
||||||
|
|
||||||
feature {NONE} -- SQL Queries: Profile
|
|
||||||
|
|
||||||
Select_instert_profile_item: STRING = "insert into profiles (profiles.key, value, users_id) values (:key, :value, :users_id);"
|
|
||||||
|
|
||||||
Select_user_profile: STRING = "Select profiles.key, value from profiles where users_id = :users_id;"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
post_execution
|
|
||||||
-- Post database execution.
|
|
||||||
do
|
|
||||||
error_handler.add_synchronization (db_handler.database_error_handler)
|
|
||||||
if error_handler.has_error then
|
|
||||||
log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
</option>
|
</option>
|
||||||
<setting name="concurrency" value="thread"/>
|
<setting name="concurrency" value="thread"/>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
|
<library name="cms" location="..\..\..\..\..\cms-safe.ecf"/>
|
||||||
<library name="model" location="..\..\..\..\model\cms_model-safe.ecf"/>
|
<library name="model" location="..\..\..\..\model\cms_model-safe.ecf"/>
|
||||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
||||||
<library name="persitence_mysql" location="..\persistence_mysql-safe.ecf" readonly="false"/>
|
<library name="persitence_mysql" location="..\persistence_mysql-safe.ecf" readonly="false"/>
|
||||||
|
|||||||
@@ -7,20 +7,19 @@
|
|||||||
</option>
|
</option>
|
||||||
<setting name="console_application" value="true"/>
|
<setting name="console_application" value="true"/>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
|
<library name="cms" location="..\..\..\..\cms-safe.ecf"/>
|
||||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
||||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
||||||
|
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
||||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
||||||
<library name="layout" location="..\..\..\layout\layout-safe.ecf"/>
|
<library name="layout" location="..\..\..\layout\layout-safe.ecf"/>
|
||||||
<library name="model" location="..\..\..\model\cms_model-safe.ecf"/>
|
|
||||||
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/>
|
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/>
|
||||||
<library name="mysql" location="$ISE_LIBRARY\library\store\dbms\rdbms\mysql\mysql-safe.ecf"/>
|
<library name="model" location="..\..\..\model\cms_model-safe.ecf"/>
|
||||||
<library name="odbc" location="$ISE_LIBRARY\library\store\dbms\rdbms\odbc\odbc-safe.ecf"/>
|
<library name="odbc" location="$ISE_LIBRARY\library\store\dbms\rdbms\odbc\odbc-safe.ecf"/>
|
||||||
<library name="store" location="$ISE_LIBRARY\library\store\store-safe.ecf" readonly="false"/>
|
<library name="store" location="$ISE_LIBRARY\library\store\store-safe.ecf" readonly="false"/>
|
||||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
|
||||||
<cluster name="common" location="..\common\" recursive="true"/>
|
<cluster name="common" location="..\common\" recursive="true"/>
|
||||||
<cluster name="interface" location="..\..\interface\" recursive="true"/>
|
|
||||||
<cluster name="persistence_sqlite" location=".\src\" recursive="true">
|
<cluster name="persistence_sqlite" location=".\src\" recursive="true">
|
||||||
<file_rule>
|
<file_rule>
|
||||||
<exclude>/EIFGENs$</exclude>
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="persistence_sqlite" uuid="8FD9D3B3-5FC1-495F-A05D-0205EC966841" library_target="persistence_sqlite">
|
||||||
|
<target name="persistence_sqlite">
|
||||||
|
<root all_classes="true"/>
|
||||||
|
<option warning="true" void_safety="none">
|
||||||
|
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||||
|
</option>
|
||||||
|
<setting name="console_application" value="true"/>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
|
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
|
||||||
|
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
|
||||||
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||||
|
<library name="layout" location="..\..\..\layout\layout.ecf"/>
|
||||||
|
<library name="model" location="..\..\..\model\cms_model.ecf"/>
|
||||||
|
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>
|
||||||
|
<library name="odbc" location="$ISE_LIBRARY\library\store\dbms\rdbms\odbc\odbc.ecf"/>
|
||||||
|
<library name="store" location="$ISE_LIBRARY\library\store\store.ecf" readonly="false"/>
|
||||||
|
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
|
||||||
|
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||||
|
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
||||||
|
<cluster name="common" location="..\common\" recursive="true"/>
|
||||||
|
<cluster name="interface" location="..\..\interface\" recursive="true"/>
|
||||||
|
<cluster name="persistence_sqlite" location=".\src\" recursive="true">
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/CVS$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
</cluster>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
-- Creator: MySQL Workbench 6.1.7/ExportSQLite plugin 2009.12.02
|
|
||||||
-- Author: javier
|
|
||||||
-- Caption: New Model
|
|
||||||
-- Project: Name of the project
|
|
||||||
-- Changed: 2014-09-16 23:12
|
|
||||||
-- Created: 2014-09-16 23:12
|
|
||||||
PRAGMA foreign_keys = OFF;
|
|
||||||
|
|
||||||
-- Schema: cms_dev
|
|
||||||
BEGIN;
|
|
||||||
CREATE TABLE "nodes"(
|
|
||||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
|
|
||||||
"publication_date" DATE NOT NULL,
|
|
||||||
"creation_date" DATE NOT NULL,
|
|
||||||
"modification_date" DATE NOT NULL,
|
|
||||||
"title" VARCHAR(255) NOT NULL,
|
|
||||||
"summary" TEXT NOT NULL,
|
|
||||||
"content" MEDIUMTEXT NOT NULL
|
|
||||||
);
|
|
||||||
CREATE TABLE "roles"(
|
|
||||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
|
|
||||||
"role" VARCHAR(100) NOT NULL,
|
|
||||||
CONSTRAINT "role"
|
|
||||||
UNIQUE("role")
|
|
||||||
);
|
|
||||||
CREATE TABLE "users"(
|
|
||||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
|
|
||||||
"username" VARCHAR(100) NOT NULL,
|
|
||||||
"password" VARCHAR(100) NOT NULL,
|
|
||||||
"salt" VARCHAR(100) NOT NULL,
|
|
||||||
"email" VARCHAR(250) NOT NULL,
|
|
||||||
CONSTRAINT "username"
|
|
||||||
UNIQUE("username")
|
|
||||||
);
|
|
||||||
CREATE TABLE "users_nodes"(
|
|
||||||
"users_id" INTEGER NOT NULL CHECK("users_id">=0),
|
|
||||||
"nodes_id" INTEGER NOT NULL CHECK("nodes_id">=0),
|
|
||||||
PRIMARY KEY("users_id","nodes_id"),
|
|
||||||
CONSTRAINT "fk_users_has_nodes_nodes1"
|
|
||||||
FOREIGN KEY("nodes_id")
|
|
||||||
REFERENCES "nodes"("id"),
|
|
||||||
CONSTRAINT "fk_users_has_nodes_users"
|
|
||||||
FOREIGN KEY("users_id")
|
|
||||||
REFERENCES "users"("id")
|
|
||||||
);
|
|
||||||
CREATE INDEX "users_nodes.fk_users_has_nodes_nodes1_idx" ON "users_nodes"("nodes_id");
|
|
||||||
CREATE INDEX "users_nodes.fk_users_has_nodes_users_idx" ON "users_nodes"("users_id");
|
|
||||||
CREATE TABLE "users_roles"(
|
|
||||||
"users_id" INTEGER NOT NULL CHECK("users_id">=0),
|
|
||||||
"roles_id" INTEGER NOT NULL CHECK("roles_id">=0),
|
|
||||||
PRIMARY KEY("users_id","roles_id"),
|
|
||||||
CONSTRAINT "fk_users_has_roles_roles1"
|
|
||||||
FOREIGN KEY("roles_id")
|
|
||||||
REFERENCES "roles"("id"),
|
|
||||||
CONSTRAINT "fk_users_has_roles_users1"
|
|
||||||
FOREIGN KEY("users_id")
|
|
||||||
REFERENCES "users"("id")
|
|
||||||
);
|
|
||||||
CREATE INDEX "users_roles.fk_users_has_roles_roles1_idx" ON "users_roles"("roles_id");
|
|
||||||
CREATE INDEX "users_roles.fk_users_has_roles_users1_idx" ON "users_roles"("users_id");
|
|
||||||
COMMIT;
|
|
||||||
36
library/persistence/implementation/sqlite/scripts/schema.sql
Normal file
36
library/persistence/implementation/sqlite/scripts/schema.sql
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
PRAGMA foreign_keys = OFF;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
CREATE TABLE "users"(
|
||||||
|
"uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0),
|
||||||
|
"name" VARCHAR(100) NOT NULL,
|
||||||
|
"password" VARCHAR(100) NOT NULL,
|
||||||
|
"salt" VARCHAR(100) NOT NULL,
|
||||||
|
"email" VARCHAR(250) NOT NULL,
|
||||||
|
"status" INTEGER,
|
||||||
|
"created" DATETIME NOT NULL,
|
||||||
|
"signed" DATETIME,
|
||||||
|
CONSTRAINT "name"
|
||||||
|
UNIQUE("name")
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "users_roles"(
|
||||||
|
"rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
|
||||||
|
"role" VARCHAR(100) NOT NULL,
|
||||||
|
CONSTRAINT "role"
|
||||||
|
UNIQUE("role")
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "nodes"(
|
||||||
|
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
|
||||||
|
"version" INTEGER,
|
||||||
|
"type" INTEGER,
|
||||||
|
"title" VARCHAR(255) NOT NULL,
|
||||||
|
"summary" TEXT NOT NULL,
|
||||||
|
"content" MEDIUMTEXT NOT NULL,
|
||||||
|
"author" INTEGER,
|
||||||
|
"publish" DATETIME,
|
||||||
|
"created" DATETIME NOT NULL,
|
||||||
|
"changed" DATETIME NOT NULL
|
||||||
|
);
|
||||||
|
COMMIT;
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
DROP TABLE IF EXISTS nodes;
|
|
||||||
|
|
||||||
CREATE TABLE nodes
|
|
||||||
(
|
|
||||||
id smallint unsigned NOT NULL auto_increment,
|
|
||||||
publication_date date NOT NULL, #When the article was published
|
|
||||||
creation_date date NOT NULL, #When the article was created
|
|
||||||
modification_date date NOT NULL, #When the article was updated
|
|
||||||
title varchar(255) NOT NULL, #Full title of the article
|
|
||||||
summary text NOT NULL, #A short summary of the articule
|
|
||||||
content mediumtext NOT NULL, #The HTML content of the article
|
|
||||||
|
|
||||||
PRIMARY KEY (ID)
|
|
||||||
);
|
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_NODE_STORAGE_SQLITE}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_NODE_STORAGE_SQLITE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_NODE_STORAGE_SQL
|
||||||
|
redefine
|
||||||
|
nodes, recent_nodes
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
db_handler: DATABASE_HANDLER
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
nodes: LIST [CMS_NODE]
|
||||||
|
-- List of nodes.
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||||
|
across nodes_iterator as ic loop
|
||||||
|
Result.force (ic.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
||||||
|
-- List of recent `a_count' nodes with an offset of `lower'.
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_count)
|
||||||
|
across recent_nodes_iterator (a_lower, a_count) as c loop
|
||||||
|
Result.force (c.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access: iterator
|
||||||
|
|
||||||
|
nodes_iterator: DATABASE_ITERATION_CURSOR [CMS_NODE]
|
||||||
|
-- List of nodes.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".nodes_iterator")
|
||||||
|
create l_parameters.make (0)
|
||||||
|
sql_query (select_nodes, l_parameters)
|
||||||
|
sql_post_execution
|
||||||
|
create Result.make (db_handler, agent fetch_node)
|
||||||
|
end
|
||||||
|
|
||||||
|
recent_nodes_iterator (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [CMS_NODE]
|
||||||
|
-- The most recent `a_rows'.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
l_query: STRING
|
||||||
|
do
|
||||||
|
-- FIXME: check implementation...
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".recent_nodes_iterator")
|
||||||
|
create l_parameters.make (2)
|
||||||
|
l_parameters.put (a_rows, "rows")
|
||||||
|
l_parameters.put (a_lower, "offset")
|
||||||
|
create l_query.make_from_string (select_recent_nodes)
|
||||||
|
sql_query (l_query, l_parameters)
|
||||||
|
create Result.make (db_handler, agent fetch_node)
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,272 +1,112 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_STORAGE_MYSQL}."
|
description: "Summary description for {CMS_STORAGE_MYSQL}."
|
||||||
date: "$Date$"
|
date: "$Date: 2014-11-13 12:23:47 -0300 (ju., 13 nov. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96085 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
CMS_STORAGE_SQLITE
|
CMS_STORAGE_SQLITE
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
CMS_STORAGE
|
CMS_STORAGE
|
||||||
|
|
||||||
|
CMS_STORAGE_STORE_SQL
|
||||||
|
|
||||||
|
CMS_USER_STORAGE_SQLITE
|
||||||
|
|
||||||
|
CMS_NODE_STORAGE_SQLITE
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
--feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (a_connection: DATABASE_CONNECTION)
|
-- make (a_connection: DATABASE_CONNECTION)
|
||||||
--
|
-- --
|
||||||
require
|
-- require
|
||||||
is_connected: a_connection.is_connected
|
-- is_connected: a_connection.is_connected
|
||||||
do
|
-- do
|
||||||
log.write_information (generator+".make_with_database is database connected? "+ a_connection.is_connected.out )
|
-- connection := a_connection
|
||||||
create node_provider.make (a_connection)
|
-- log.write_information (generator + ".make_with_database is database connected? "+ a_connection.is_connected.out )
|
||||||
create user_provider.make (a_connection)
|
|
||||||
post_node_provider_execution
|
|
||||||
post_user_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
-- create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
||||||
|
|
||||||
feature -- Access: user
|
-- create error_handler.make
|
||||||
|
---- error_handler.add_synchronization (db_handler.database_error_handler)
|
||||||
|
-- end
|
||||||
|
|
||||||
has_user: BOOLEAN
|
-- db_handler: DATABASE_HANDLER
|
||||||
-- Has any user?
|
|
||||||
do
|
|
||||||
Result := user_provider.has_user
|
|
||||||
post_user_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
-- connection: DATABASE_CONNECTION
|
||||||
|
-- -- Current database connection.
|
||||||
|
|
||||||
all_users: LIST [CMS_USER]
|
--feature -- Access: user
|
||||||
do
|
|
||||||
to_implement("Not implemented!!!")
|
|
||||||
create {ARRAYED_LIST[CMS_USER]} Result.make (0)
|
|
||||||
end
|
|
||||||
|
|
||||||
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
|
-- sql_post_execution
|
||||||
do
|
-- -- Post database execution.
|
||||||
Result := user_provider.user (a_id)
|
-- do
|
||||||
post_user_provider_execution
|
-- error_handler.append (db_handler.database_error_handler)
|
||||||
end
|
-- if error_handler.has_error then
|
||||||
|
-- log.write_critical (generator + ".post_execution " + error_handler.as_string_representation)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
|
-- sql_begin_transaction
|
||||||
do
|
-- do
|
||||||
Result := user_provider.user_by_name (a_name)
|
-- connection.begin_transaction
|
||||||
post_user_provider_execution
|
-- end
|
||||||
end
|
|
||||||
|
|
||||||
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
|
-- sql_commit_transaction
|
||||||
do
|
-- do
|
||||||
Result := user_provider.user_by_email (a_email)
|
-- connection.commit
|
||||||
post_user_provider_execution
|
-- end
|
||||||
end
|
|
||||||
|
|
||||||
is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN
|
-- sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
local
|
-- do
|
||||||
l_security: SECURITY_PROVIDER
|
-- check_sql_query_validity (a_sql_statement, a_params)
|
||||||
do
|
-- db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
|
||||||
if attached user_provider.user_salt (l_auth_login) as l_hash then
|
-- db_handler.execute_query
|
||||||
if attached user_provider.user_by_name (l_auth_login) as l_user then
|
-- end
|
||||||
create l_security
|
|
||||||
if
|
|
||||||
attached l_user.password as l_password and then
|
|
||||||
l_security.password_hash (l_auth_password, l_hash).is_case_insensitive_equal (l_password)
|
|
||||||
then
|
|
||||||
Result := True
|
|
||||||
else
|
|
||||||
log.write_information (generator + ".login_valid User: wrong username or password" )
|
|
||||||
end
|
|
||||||
else
|
|
||||||
log.write_information (generator + ".login_valid User:" + l_auth_login + "does not exist" )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
post_user_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Change: user
|
-- sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
|
-- do
|
||||||
|
-- check_sql_query_validity (a_sql_statement, a_params)
|
||||||
|
-- db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
|
||||||
|
-- db_handler.execute_change
|
||||||
|
-- end
|
||||||
|
|
||||||
save_user (a_user: CMS_USER)
|
-- sql_rows_count: INTEGER
|
||||||
-- Add a new user `a_user'.
|
-- -- Number of rows for last sql execution.
|
||||||
do
|
-- do
|
||||||
if
|
-- Result := db_handler.count
|
||||||
attached a_user.password as l_password and then
|
-- end
|
||||||
attached a_user.email as l_email
|
|
||||||
then
|
|
||||||
user_provider.new_user (a_user.name, l_password, l_email)
|
|
||||||
else
|
|
||||||
-- set error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- User Nodes
|
-- sql_start
|
||||||
|
-- -- Set the cursor on first element.
|
||||||
|
-- do
|
||||||
|
-- db_handler.start
|
||||||
|
-- end
|
||||||
|
|
||||||
user_collaborator_nodes (a_id: like {CMS_USER}.id): LIST[CMS_NODE]
|
-- sql_after: BOOLEAN
|
||||||
-- Possible list of nodes where the user identified by `a_id', is a collaborator.
|
-- -- Are there no more items to iterate over?
|
||||||
do
|
-- do
|
||||||
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
|
-- Result := db_handler.after
|
||||||
to_implement ("Not implemented")
|
-- end
|
||||||
end
|
|
||||||
|
|
||||||
user_author_nodes (a_id: like {CMS_USER}.id): LIST[CMS_NODE]
|
-- sql_forth
|
||||||
-- Possible list of nodes where the user identified by `a_id', is the author.
|
-- -- Fetch next row from last sql execution, if any.
|
||||||
do
|
-- do
|
||||||
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
|
-- db_handler.forth
|
||||||
to_implement ("Not implemented")
|
-- end
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Users roles and permissions
|
-- sql_item (a_index: INTEGER): detachable ANY
|
||||||
|
-- do
|
||||||
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
-- if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then
|
||||||
-- User role by id `a_id', if any.
|
-- Result := l_item.item (a_index)
|
||||||
do
|
-- else
|
||||||
to_implement ("Not implemented")
|
-- check has_item_at_index: False end
|
||||||
end
|
-- end
|
||||||
|
-- end
|
||||||
user_roles: LIST [CMS_USER_ROLE]
|
|
||||||
-- Possible list of user roles.
|
|
||||||
do
|
|
||||||
create {ARRAYED_LIST[CMS_USER_ROLE]} Result.make (0)
|
|
||||||
to_implement ("Not implemented")
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Change: roles and permissions
|
|
||||||
|
|
||||||
save_user_role (a_user_role: CMS_USER_ROLE)
|
|
||||||
-- Save user role `a_user_role'
|
|
||||||
do
|
|
||||||
to_implement ("Not implemented")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature -- Access: node
|
|
||||||
|
|
||||||
nodes: LIST[CMS_NODE]
|
|
||||||
-- List of nodes.
|
|
||||||
do
|
|
||||||
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
|
|
||||||
across node_provider.nodes as c loop
|
|
||||||
Result.force (c.item)
|
|
||||||
end
|
|
||||||
post_node_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
|
||||||
-- List of the `a_count' most recent nodes, starting from `a_lower'.
|
|
||||||
do
|
|
||||||
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
|
|
||||||
across node_provider.recent_nodes (a_lower,a_count) as c loop
|
|
||||||
Result.force (c.item)
|
|
||||||
end
|
|
||||||
post_node_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
node (a_id: INTEGER_64): detachable CMS_NODE
|
|
||||||
--
|
|
||||||
do
|
|
||||||
Result := node_provider.node (a_id)
|
|
||||||
post_node_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature -- Node
|
|
||||||
|
|
||||||
save_node (a_node: CMS_NODE)
|
|
||||||
-- Add a new node
|
|
||||||
do
|
|
||||||
node_provider.new_node (a_node)
|
|
||||||
post_node_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
delete_node (a_id: INTEGER_64)
|
|
||||||
do
|
|
||||||
node_provider.delete_node (a_id)
|
|
||||||
post_node_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node (a_id: like {CMS_USER}.id; a_node: CMS_NODE)
|
|
||||||
do
|
|
||||||
node_provider.update_node (a_node)
|
|
||||||
post_node_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_title (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
|
||||||
do
|
|
||||||
node_provider.update_node_title (a_id, a_title)
|
|
||||||
post_node_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_summary (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
|
||||||
do
|
|
||||||
node_provider.update_node_summary (a_id, a_summary)
|
|
||||||
post_node_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_content (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
|
||||||
do
|
|
||||||
node_provider.update_node_content (a_id, a_content)
|
|
||||||
post_node_provider_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
|
|
||||||
-- Node's author. if any.
|
|
||||||
do
|
|
||||||
to_implement ("Not implemented")
|
|
||||||
end
|
|
||||||
|
|
||||||
node_collaborators (a_id: like {CMS_NODE}.id): LIST [CMS_USER]
|
|
||||||
-- Possible list of node's collaborator.
|
|
||||||
do
|
|
||||||
create {ARRAYED_LIST[CMS_USER]} Result.make (0)
|
|
||||||
to_implement ("Not implemented")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature -- User
|
|
||||||
|
|
||||||
new_user (a_user: CMS_USER)
|
|
||||||
-- Add a new user `a_user'.
|
|
||||||
do
|
|
||||||
if
|
|
||||||
attached a_user.password as l_password and then
|
|
||||||
attached a_user.email as l_email
|
|
||||||
then
|
|
||||||
user_provider.new_user (a_user.name, l_password, l_email)
|
|
||||||
else
|
|
||||||
-- set error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Post process
|
|
||||||
|
|
||||||
post_node_provider_execution
|
|
||||||
do
|
|
||||||
if node_provider.successful then
|
|
||||||
set_successful
|
|
||||||
else
|
|
||||||
if attached node_provider.last_error then
|
|
||||||
set_last_error_from_handler (node_provider.last_error)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
post_user_provider_execution
|
|
||||||
do
|
|
||||||
if user_provider.successful then
|
|
||||||
set_successful
|
|
||||||
else
|
|
||||||
if attached user_provider.last_error then
|
|
||||||
set_last_error_from_handler (user_provider.last_error)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
node_provider: NODE_DATA_PROVIDER
|
|
||||||
-- Node Data provider.
|
|
||||||
|
|
||||||
user_provider: USER_DATA_PROVIDER
|
|
||||||
-- User Data provider.
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Objects that ...
|
||||||
|
]"
|
||||||
|
author: "$Author$"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_STORAGE_SQLITE_BUILDER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_STORAGE_BUILDER
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make
|
||||||
|
-- Initialize `Current'.
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Factory
|
||||||
|
|
||||||
|
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_SQLITE
|
||||||
|
local
|
||||||
|
s: STRING
|
||||||
|
do
|
||||||
|
if attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.layout.application_config_path) as l_database_config then
|
||||||
|
s := "Driver=SQLite3 ODBC Driver;Database="
|
||||||
|
if attached l_database_config.database_name as db_name then
|
||||||
|
s.append (db_name)
|
||||||
|
end
|
||||||
|
s.append (";LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
|
||||||
|
create Result.make (create {DATABASE_CONNECTION_ODBC}.login_with_connection_string (s))
|
||||||
|
--create Result.make (create {DATABASE_CONNECTION_ODBC}.login_with_connection_string (l_database_config.connection_string))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_USER_STORAGE_SQLITE}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_USER_STORAGE_SQLITE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_USER_STORAGE_SQL
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Object that handle a database connection for ODBC"
|
|
||||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
|
||||||
revision: "$Revision: 95678 $"
|
|
||||||
|
|
||||||
class
|
|
||||||
DATABASE_CONNECTION_MYSQL
|
|
||||||
|
|
||||||
inherit
|
|
||||||
|
|
||||||
DATABASE_CONNECTION
|
|
||||||
redefine
|
|
||||||
db_application
|
|
||||||
end
|
|
||||||
|
|
||||||
create
|
|
||||||
make, make_common, make_basic, login_with_connection_string, login_with_schema
|
|
||||||
|
|
||||||
feature -- Initialization
|
|
||||||
|
|
||||||
make_common
|
|
||||||
-- Create a database handler for MYSQL with common settings.
|
|
||||||
local
|
|
||||||
l_retried: BOOLEAN
|
|
||||||
do
|
|
||||||
create db_application.login (username, password)
|
|
||||||
|
|
||||||
if not l_retried then
|
|
||||||
db_application.set_hostname (hostname)
|
|
||||||
db_application.set_data_source (database_name)
|
|
||||||
db_application.set_base
|
|
||||||
create db_control.make
|
|
||||||
keep_connection := is_keep_connection
|
|
||||||
if keep_connection then
|
|
||||||
connect
|
|
||||||
end
|
|
||||||
set_successful
|
|
||||||
else
|
|
||||||
create db_control.make
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
create db_control.make
|
|
||||||
set_last_error_from_exception ("Connection execution")
|
|
||||||
log.write_critical (generator + ".make_common:" + last_error_message)
|
|
||||||
if is_connected then
|
|
||||||
disconnect
|
|
||||||
end
|
|
||||||
l_retried := True
|
|
||||||
retry
|
|
||||||
end
|
|
||||||
|
|
||||||
make_basic (a_database_name: STRING)
|
|
||||||
-- Create a database handler and
|
|
||||||
-- set database_name to `a_database_name'.
|
|
||||||
local
|
|
||||||
l_retried: BOOLEAN
|
|
||||||
do
|
|
||||||
create db_application.login (username, password)
|
|
||||||
|
|
||||||
if not l_retried then
|
|
||||||
db_application.set_hostname (hostname)
|
|
||||||
db_application.set_data_source (a_database_name)
|
|
||||||
db_application.set_base
|
|
||||||
create db_control.make
|
|
||||||
keep_connection := is_keep_connection
|
|
||||||
if keep_connection then
|
|
||||||
connect
|
|
||||||
end
|
|
||||||
set_successful
|
|
||||||
else
|
|
||||||
create db_control.make
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
create db_control.make
|
|
||||||
set_last_error_from_exception ("Connection execution")
|
|
||||||
log.write_critical (generator + ".make_common:" + last_error_message)
|
|
||||||
if is_connected then
|
|
||||||
disconnect
|
|
||||||
end
|
|
||||||
l_retried := True
|
|
||||||
retry
|
|
||||||
end
|
|
||||||
|
|
||||||
make (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN)
|
|
||||||
|
|
||||||
-- Create a database handler for ODBC and set `username' to `a_username',
|
|
||||||
-- `password' to `a_password'
|
|
||||||
-- `database_name' to `a_database_name'
|
|
||||||
-- `connection' to `a_connection'
|
|
||||||
do
|
|
||||||
create db_application.login (a_username, a_password)
|
|
||||||
db_application.set_hostname (a_hostname)
|
|
||||||
db_application.set_data_source (a_database_name)
|
|
||||||
db_application.set_base
|
|
||||||
create db_control.make
|
|
||||||
keep_connection := connection
|
|
||||||
if keep_connection then
|
|
||||||
connect
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
login_with_connection_string (a_string: STRING)
|
|
||||||
-- Login with `a_connection_string'and immediately connect to database.
|
|
||||||
local
|
|
||||||
l_string: LIST[STRING]
|
|
||||||
l_server: STRING
|
|
||||||
l_port: STRING
|
|
||||||
l_schema: STRING
|
|
||||||
l_user: STRING
|
|
||||||
l_password: STRING
|
|
||||||
do
|
|
||||||
l_string := a_string.split (';')
|
|
||||||
l_server := l_string.at (2).split ('=').at (2)
|
|
||||||
l_port := l_string.at (3).split ('=').at (2)
|
|
||||||
l_schema := l_string.at (4).split ('=').at (2)
|
|
||||||
l_user := l_string.at (5).split ('=').at (2)
|
|
||||||
l_password := l_string.at (6).split ('=').at (2)
|
|
||||||
|
|
||||||
create db_application
|
|
||||||
db_application.set_application (l_schema)
|
|
||||||
db_application.set_hostname (l_server + ":" + l_port)
|
|
||||||
db_application.login_and_connect (l_user, l_password)
|
|
||||||
db_application.set_base
|
|
||||||
create db_control.make
|
|
||||||
keep_connection := is_keep_connection
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
login_with_schema (a_schema: STRING; a_username: STRING; a_password: STRING)
|
|
||||||
-- Login with `a_connection_string'and immediately connect to database.
|
|
||||||
do
|
|
||||||
create db_application
|
|
||||||
db_application.set_application (a_schema)
|
|
||||||
db_application.login_and_connect (a_username, a_password)
|
|
||||||
db_application.set_base
|
|
||||||
create db_control.make
|
|
||||||
keep_connection := is_keep_connection
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Databse Connection
|
|
||||||
|
|
||||||
db_application: DATABASE_APPL [MYSQL]
|
|
||||||
-- Database application.
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,289 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Database access for node uses cases."
|
|
||||||
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
|
|
||||||
revision: "$Revision: 95678 $"
|
|
||||||
|
|
||||||
class
|
|
||||||
NODE_DATA_PROVIDER
|
|
||||||
|
|
||||||
inherit
|
|
||||||
|
|
||||||
PARAMETER_NAME_HELPER
|
|
||||||
|
|
||||||
SHARED_ERROR
|
|
||||||
|
|
||||||
REFACTORING_HELPER
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
feature -- Initialization
|
|
||||||
|
|
||||||
make (a_connection: DATABASE_CONNECTION)
|
|
||||||
-- Create a data provider.
|
|
||||||
do
|
|
||||||
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
db_handler: DATABASE_HANDLER
|
|
||||||
-- Db handler.
|
|
||||||
|
|
||||||
feature -- Status Report
|
|
||||||
|
|
||||||
is_successful: BOOLEAN
|
|
||||||
-- Is the last execution sucessful?
|
|
||||||
do
|
|
||||||
Result := db_handler.successful
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
nodes: DATABASE_ITERATION_CURSOR [CMS_NODE]
|
|
||||||
-- List of nodes.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".nodes")
|
|
||||||
create l_parameters.make (0)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (Select_nodes, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make (db_handler, agent fetch_node)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
recent_nodes (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [CMS_NODE]
|
|
||||||
-- The most recent `a_rows'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
l_query: STRING
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".recent_nodes")
|
|
||||||
create l_parameters.make (2)
|
|
||||||
l_parameters.put (a_rows, "rows")
|
|
||||||
create l_query.make_from_string (select_recent_nodes)
|
|
||||||
l_query.replace_substring_all ("$offset", a_lower.out)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (l_query, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
create Result.make (db_handler, agent fetch_node)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
node (a_id: INTEGER_64): detachable CMS_NODE
|
|
||||||
-- Node for the given id `a_id', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".node")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id,"id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_node_by_id, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := fetch_node
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
count: INTEGER
|
|
||||||
-- Number of items nodes.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".count")
|
|
||||||
create l_parameters.make (0)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_count, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := db_handler.read_integer_32 (1)
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Basic operations
|
|
||||||
|
|
||||||
new_node (a_node: CMS_NODE)
|
|
||||||
-- Create a new node.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".new_node")
|
|
||||||
create l_parameters.make (6)
|
|
||||||
l_parameters.put (a_node.title, "title")
|
|
||||||
l_parameters.put (a_node.summary, "summary")
|
|
||||||
l_parameters.put (a_node.content, "content")
|
|
||||||
l_parameters.put (a_node.publication_date, "publication_date")
|
|
||||||
l_parameters.put (a_node.creation_date, "creation_date")
|
|
||||||
l_parameters.put (a_node.modification_date, "modification_date")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_insert_node, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_title (a_id: INTEGER_64; a_title: READABLE_STRING_32)
|
|
||||||
-- Update node title for the corresponding the report with id `a_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".update_node_title")
|
|
||||||
create l_parameters.make (3)
|
|
||||||
l_parameters.put (a_title, "title")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
|
|
||||||
l_parameters.put (a_id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_update_node_title, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_summary (a_id: INTEGER_64; a_summary: READABLE_STRING_32)
|
|
||||||
-- Update node summary for the corresponding the report with id `a_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".update_node_summary")
|
|
||||||
create l_parameters.make (3)
|
|
||||||
l_parameters.put (a_summary, "summary")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
|
|
||||||
l_parameters.put (a_id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_update_node_summary, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_content (a_id: INTEGER_64; a_content: READABLE_STRING_32)
|
|
||||||
-- Update node content for the corresponding the report with id `a_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".update_node_content")
|
|
||||||
create l_parameters.make (3)
|
|
||||||
l_parameters.put (a_content, "content")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
|
|
||||||
l_parameters.put (a_id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_update_node_content, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node (a_node: CMS_NODE)
|
|
||||||
-- Update node.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".update_node")
|
|
||||||
create l_parameters.make (7)
|
|
||||||
l_parameters.put (a_node.title, "title")
|
|
||||||
l_parameters.put (a_node.summary, "summary")
|
|
||||||
l_parameters.put (a_node.content, "content")
|
|
||||||
l_parameters.put (a_node.publication_date, "publication_date")
|
|
||||||
l_parameters.put (a_node.creation_date, "creation_date")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "modification_date")
|
|
||||||
l_parameters.put (a_node.id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_update_node, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
delete_node (a_id: INTEGER_64;)
|
|
||||||
-- Delete node with id `a_id'.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".delete_node")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id, "id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_delete_node, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Connection
|
|
||||||
|
|
||||||
connect
|
|
||||||
-- Connect to the database.
|
|
||||||
do
|
|
||||||
if not db_handler.is_connected then
|
|
||||||
db_handler.connect
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
disconnect
|
|
||||||
-- Disconnect to the database.
|
|
||||||
do
|
|
||||||
if db_handler.is_connected then
|
|
||||||
db_handler.disconnect
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Queries
|
|
||||||
|
|
||||||
Select_count: STRING = "select count(*) from Nodes;"
|
|
||||||
|
|
||||||
Select_nodes: STRING = "select * from Nodes;"
|
|
||||||
-- SQL Query to retrieve all nodes.
|
|
||||||
|
|
||||||
Select_node_by_id: STRING = "select * from Nodes where id =:id order by id desc, publication_date desc;"
|
|
||||||
|
|
||||||
Select_recent_nodes: STRING = "select * from Nodes order by id desc, publication_date desc Limit $offset , :rows "
|
|
||||||
|
|
||||||
SQL_Insert_node: STRING = "insert into nodes (title, summary, content, publication_date, creation_date, modification_date) values (:title, :summary, :content, :publication_date, :creation_date, :modification_date);"
|
|
||||||
-- SQL Insert to add a new node.
|
|
||||||
|
|
||||||
SQL_Update_node_title: STRING ="update nodes SET title=:title, modification_date=:modification_date where id=:id;"
|
|
||||||
-- SQL update node title.
|
|
||||||
|
|
||||||
SQL_Update_node_summary: STRING ="update nodes SET summary=:summary, modification_date=:modification_date where id=:id;"
|
|
||||||
-- SQL update node summary.
|
|
||||||
|
|
||||||
SQL_Update_node_content: STRING ="update nodes SET content=:content, modification_date=:modification_date where id=:id;"
|
|
||||||
-- SQL node content.
|
|
||||||
|
|
||||||
SQL_Update_node : STRING = "update nodes SET title=:title, summary=:summary, content=:content, publication_date=:publication_date, creation_date=:creation_date, modification_date=:modification_date where id=:id;"
|
|
||||||
-- SQL node.
|
|
||||||
|
|
||||||
SQL_Delete_node: STRING = "delete from nodes where id=:id;"
|
|
||||||
|
|
||||||
|
|
||||||
feature -- New Object
|
|
||||||
|
|
||||||
fetch_node: CMS_NODE
|
|
||||||
do
|
|
||||||
create Result.make ("", "", "")
|
|
||||||
if attached db_handler.read_integer_32 (1) as l_id then
|
|
||||||
Result.set_id (l_id)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_date_time (2) as l_pd then
|
|
||||||
Result.set_publication_date (l_pd)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_date_time (3) as l_cd then
|
|
||||||
Result.set_creation_date (l_cd)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_date_time (4) as l_md then
|
|
||||||
Result.set_modification_date (l_md)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (5) as l_t then
|
|
||||||
Result.set_title (l_t)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (6) as l_s then
|
|
||||||
Result.set_summary (l_s)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (7) as l_c then
|
|
||||||
Result.set_content (l_c)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
post_execution
|
|
||||||
-- Post database execution.
|
|
||||||
do
|
|
||||||
if db_handler.successful then
|
|
||||||
set_successful
|
|
||||||
else
|
|
||||||
if attached db_handler.last_error then
|
|
||||||
set_last_error_from_handler (db_handler.last_error)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,206 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {USER_DATA_PROVIDER}."
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
USER_DATA_PROVIDER
|
|
||||||
|
|
||||||
inherit
|
|
||||||
|
|
||||||
PARAMETER_NAME_HELPER
|
|
||||||
|
|
||||||
SHARED_ERROR
|
|
||||||
|
|
||||||
REFACTORING_HELPER
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
feature -- Initialization
|
|
||||||
|
|
||||||
make (a_connection: DATABASE_CONNECTION)
|
|
||||||
-- Create a data provider.
|
|
||||||
do
|
|
||||||
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
db_handler: DATABASE_HANDLER
|
|
||||||
-- Db handler.
|
|
||||||
|
|
||||||
feature -- Status Report
|
|
||||||
|
|
||||||
is_successful: BOOLEAN
|
|
||||||
-- Is the last execution sucessful?
|
|
||||||
do
|
|
||||||
Result := db_handler.successful
|
|
||||||
end
|
|
||||||
|
|
||||||
has_user: BOOLEAN
|
|
||||||
-- Has any user?
|
|
||||||
do
|
|
||||||
Result := count > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Basic Operations
|
|
||||||
|
|
||||||
new_user (a_user_name: READABLE_STRING_32; a_password: READABLE_STRING_32; a_email: READABLE_STRING_32)
|
|
||||||
-- Create a new node.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
l_password_salt, l_password_hash: STRING
|
|
||||||
l_security: SECURITY_PROVIDER
|
|
||||||
do
|
|
||||||
create l_security
|
|
||||||
l_password_salt := l_security.salt
|
|
||||||
l_password_hash := l_security.password_hash (a_password, l_password_salt)
|
|
||||||
|
|
||||||
log.write_information (generator + ".new_user")
|
|
||||||
create l_parameters.make (4)
|
|
||||||
l_parameters.put (a_user_name,"username")
|
|
||||||
l_parameters.put (l_password_hash,"password")
|
|
||||||
l_parameters.put (l_password_salt,"salt")
|
|
||||||
l_parameters.put (a_email,"email")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (sql_insert_user, l_parameters))
|
|
||||||
db_handler.execute_change
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
user (a_id: INTEGER_64): detachable CMS_USER
|
|
||||||
-- User for the given id `a_id', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".user")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_id,"id")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_user_by_id, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := fetch_user
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
user_by_name (a_name: READABLE_STRING_32): detachable CMS_USER
|
|
||||||
-- User for the given name `a_name', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".user_by_name")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_name,"name")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_user_by_name, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := fetch_user
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
user_by_email (a_email: detachable READABLE_STRING_32): detachable CMS_USER
|
|
||||||
-- User for the given email `a_email', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".user_by_email")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_email,"email")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_user_by_email, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := fetch_user
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
user_salt (a_username: READABLE_STRING_32): detachable READABLE_STRING_32
|
|
||||||
-- User salt for the given user `a_username', if any.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".user_salt")
|
|
||||||
create l_parameters.make (1)
|
|
||||||
l_parameters.put (a_username,"name")
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_salt_by_username, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
if attached db_handler.read_string (1) as l_salt then
|
|
||||||
Result := l_salt.as_string_32
|
|
||||||
end
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
count: INTEGER
|
|
||||||
-- Number of items users.
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [ANY]
|
|
||||||
do
|
|
||||||
log.write_information (generator + ".count")
|
|
||||||
create l_parameters.make (0)
|
|
||||||
db_handler.set_query (create {DATABASE_QUERY}.data_reader (select_count, l_parameters))
|
|
||||||
db_handler.execute_query
|
|
||||||
if db_handler.count = 1 then
|
|
||||||
Result := db_handler.read_integer_32 (1)
|
|
||||||
end
|
|
||||||
post_execution
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- New Object
|
|
||||||
|
|
||||||
fetch_user: CMS_USER
|
|
||||||
do
|
|
||||||
create Result.make ("")
|
|
||||||
if attached db_handler.read_integer_32 (1) as l_id then
|
|
||||||
Result.set_id (l_id)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (2) as l_u then
|
|
||||||
Result.set_name (l_u)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (3) as l_p then
|
|
||||||
Result.set_password (l_p)
|
|
||||||
end
|
|
||||||
if attached db_handler.read_string (5) as l_e then
|
|
||||||
Result.set_email (l_e)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Sql Queries
|
|
||||||
|
|
||||||
Select_count: STRING = "select count(*) from Users;"
|
|
||||||
-- Number of users.
|
|
||||||
|
|
||||||
Select_user_by_id: STRING = "select * from Users where id =:id;"
|
|
||||||
-- Retrieve user by id if exists.
|
|
||||||
|
|
||||||
Select_user_by_name: STRING = "select * from Users where username =:name;"
|
|
||||||
-- Retrieve user by name if exists.
|
|
||||||
|
|
||||||
Select_user_by_email: STRING = "select * from Users where email =:email;"
|
|
||||||
-- Retrieve user by email if exists.
|
|
||||||
|
|
||||||
Select_salt_by_username: STRING = "select salt from Users where username =:name;"
|
|
||||||
-- Retrieve salt by username if exists.
|
|
||||||
|
|
||||||
SQL_Insert_user: STRING = "insert into users (username, password, salt, email) values (:username, :password, :salt, :email);"
|
|
||||||
-- SQL Insert to add a new node.
|
|
||||||
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
post_execution
|
|
||||||
-- Post database execution.
|
|
||||||
do
|
|
||||||
if db_handler.successful then
|
|
||||||
set_successful
|
|
||||||
else
|
|
||||||
if attached db_handler.last_error then
|
|
||||||
set_last_error_from_handler (db_handler.last_error)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -216,6 +216,7 @@ feature -- Test routines
|
|||||||
across 1 |..| 10 as c loop
|
across 1 |..| 10 as c loop
|
||||||
storage.save_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out))
|
storage.save_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out))
|
||||||
end
|
end
|
||||||
|
assert ("has nodes", storage.nodes.count > 5)
|
||||||
assert ("Node id: 10", attached storage.node (10) as l_node and then l_node.title ~ "Title_10" )
|
assert ("Node id: 10", attached storage.node (10) as l_node and then l_node.title ~ "Title_10" )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
</option>
|
</option>
|
||||||
<setting name="concurrency" value="thread"/>
|
<setting name="concurrency" value="thread"/>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
|
<library name="cms" location="..\..\..\..\..\cms-safe.ecf" readonly="false"/>
|
||||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
||||||
|
<library name="model" location="..\..\..\..\model\cms_model-safe.ecf"/>
|
||||||
<library name="persitence_sqlite" location="..\persistence_sqlite-safe.ecf" readonly="false"/>
|
<library name="persitence_sqlite" location="..\persistence_sqlite-safe.ecf" readonly="false"/>
|
||||||
<library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/>
|
<library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/>
|
||||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
|
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ feature -- Database connection
|
|||||||
connection: DATABASE_CONNECTION_ODBC
|
connection: DATABASE_CONNECTION_ODBC
|
||||||
-- odbc database connection
|
-- odbc database connection
|
||||||
once
|
once
|
||||||
-- create Result.login_with_connection_string ("Driver=SQLite3 ODBC Driver;Database=PATH/SQLITE.FILE;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
|
create Result.login_with_connection_string ("Driver=SQLite3 ODBC Driver;Database=cms_lite.db;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
|
||||||
create Result.make_basic ("cms_dev")
|
-- create Result.make_basic ("cms_lite.db")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,261 +0,0 @@
|
|||||||
|
|
||||||
note
|
|
||||||
description : "[
|
|
||||||
CMS interface to storage
|
|
||||||
]"
|
|
||||||
date : "$Date$"
|
|
||||||
revision : "$Revision$"
|
|
||||||
|
|
||||||
deferred class
|
|
||||||
CMS_STORAGE
|
|
||||||
|
|
||||||
inherit
|
|
||||||
|
|
||||||
SHARED_LOGGER
|
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
|
||||||
|
|
||||||
initialize
|
|
||||||
do
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Error Handling
|
|
||||||
|
|
||||||
error_handler: ERROR_HANDLER
|
|
||||||
-- Error handler.
|
|
||||||
|
|
||||||
feature -- Access: user
|
|
||||||
|
|
||||||
has_user: BOOLEAN
|
|
||||||
-- Has any user?
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
all_users: LIST [CMS_USER]
|
|
||||||
-- Possible list of users.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
|
|
||||||
-- User with id `a_id', if any.
|
|
||||||
require
|
|
||||||
a_id > 0
|
|
||||||
deferred
|
|
||||||
ensure
|
|
||||||
same_id: Result /= Void implies Result.id = a_id
|
|
||||||
password: Result /= Void implies Result.password /= Void
|
|
||||||
end
|
|
||||||
|
|
||||||
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
|
|
||||||
-- User with name `a_name', if any.
|
|
||||||
require
|
|
||||||
a_name /= Void and then not a_name.is_empty
|
|
||||||
deferred
|
|
||||||
ensure
|
|
||||||
same_name: Result /= Void implies a_name ~ Result.name
|
|
||||||
password: Result /= Void implies Result.password /= Void
|
|
||||||
end
|
|
||||||
|
|
||||||
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
|
|
||||||
-- User with name `a_email', if any.
|
|
||||||
deferred
|
|
||||||
ensure
|
|
||||||
same_email: Result /= Void implies a_email ~ Result.email
|
|
||||||
password: Result /= Void implies Result.password /= Void
|
|
||||||
end
|
|
||||||
|
|
||||||
is_valid_credential (a_u, a_p: READABLE_STRING_32): BOOLEAN
|
|
||||||
-- Does account with username `a_username' and password `a_password' exist?
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- User Nodes
|
|
||||||
|
|
||||||
user_collaborator_nodes (a_id: like {CMS_USER}.id): LIST[CMS_NODE]
|
|
||||||
-- Possible list of nodes where the user identified by `a_id', is a collaborator.
|
|
||||||
require
|
|
||||||
a_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
user_author_nodes (a_id: like {CMS_USER}.id): LIST[CMS_NODE]
|
|
||||||
-- Possible list of nodes where the user identified by `a_id', is the author.
|
|
||||||
require
|
|
||||||
a_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Change: user
|
|
||||||
|
|
||||||
save_user (a_user: CMS_USER)
|
|
||||||
-- Save user `a_user'.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access: roles and permissions
|
|
||||||
|
|
||||||
user_has_permission (u: detachable CMS_USER; s: detachable READABLE_STRING_8): BOOLEAN
|
|
||||||
-- Anonymous or user `u' has permission for `s' ?
|
|
||||||
--| `s' could be "create page",
|
|
||||||
do
|
|
||||||
-- if s = Void then
|
|
||||||
-- Result := True
|
|
||||||
-- elseif u = Void then
|
|
||||||
---- Result := user_role_has_permission (anonymous_user_role, s)
|
|
||||||
-- else
|
|
||||||
-- Result := user_role_has_permission (authenticated_user_role, s)
|
|
||||||
-- if not Result and attached u.roles as l_roles then
|
|
||||||
-- across
|
|
||||||
-- l_roles as r
|
|
||||||
-- until
|
|
||||||
-- Result
|
|
||||||
-- loop
|
|
||||||
-- if attached user_role_by_id (r.item) as ur then
|
|
||||||
-- Result := user_role_has_permission (ur, s)
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
end
|
|
||||||
|
|
||||||
user_role_has_permission (a_role: CMS_USER_ROLE; s: READABLE_STRING_8): BOOLEAN
|
|
||||||
do
|
|
||||||
Result := a_role.has_permission (s)
|
|
||||||
end
|
|
||||||
|
|
||||||
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
|
||||||
-- User role by id `a_id', if any.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
user_roles: LIST [CMS_USER_ROLE]
|
|
||||||
-- Possible list of user roles.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Change: roles and permissions
|
|
||||||
|
|
||||||
save_user_role (a_user_role: CMS_USER_ROLE)
|
|
||||||
-- Save user role `a_user_role'
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Email
|
|
||||||
|
|
||||||
-- save_email (a_email: NOTIFICATION_EMAIL)
|
|
||||||
-- deferred
|
|
||||||
-- end
|
|
||||||
|
|
||||||
--feature -- Log
|
|
||||||
|
|
||||||
-- recent_logs (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_LOG]
|
|
||||||
-- deferred
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- log (a_id: like {CMS_LOG}.id): detachable CMS_LOG
|
|
||||||
-- require
|
|
||||||
-- a_id > 0
|
|
||||||
-- deferred
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- save_log (a_log: CMS_LOG)
|
|
||||||
-- deferred
|
|
||||||
-- end
|
|
||||||
|
|
||||||
feature -- Access: Node
|
|
||||||
|
|
||||||
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
|
||||||
-- List of recent `a_count' nodes with an offset of `lower'.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
node (a_id: INTEGER_64): detachable CMS_NODE
|
|
||||||
-- Retrieve node by id `a_id', if any.
|
|
||||||
require
|
|
||||||
a_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
|
|
||||||
-- Node's author. if any.
|
|
||||||
require
|
|
||||||
valid_node: a_id >0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
node_collaborators (a_id: like {CMS_NODE}.id): LIST [CMS_USER]
|
|
||||||
-- Possible list of node's collaborator.
|
|
||||||
require
|
|
||||||
valid_node: a_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Change: Node
|
|
||||||
|
|
||||||
save_node (a_node: CMS_NODE)
|
|
||||||
-- Save node `a_node'.
|
|
||||||
require
|
|
||||||
valid_user: attached a_node.author as l_author and then l_author.id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
delete_node (a_id: INTEGER_64)
|
|
||||||
-- Remove node by id `a_id'.
|
|
||||||
require
|
|
||||||
valid_node_id: a_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node (a_id: like {CMS_USER}.id; a_node: CMS_NODE)
|
|
||||||
-- Update node content `a_node'.
|
|
||||||
-- The user `a_id' is an existing or new collaborator.
|
|
||||||
require
|
|
||||||
valid_node_id: a_node.id > 0
|
|
||||||
valid_user_id: a_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_title (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
|
||||||
-- Update node title to `a_title', node identified by id `a_node_id'.
|
|
||||||
-- The user `a_id' is an existing or new collaborator.
|
|
||||||
require
|
|
||||||
valid_node_id: a_node_id > 0
|
|
||||||
valid_user_id: a_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_summary (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
|
||||||
-- Update node summary to `a_summary', node identified by id `a_node_id'.
|
|
||||||
-- The user `a_id' is an existing or new collaborator.
|
|
||||||
require
|
|
||||||
valid_id: a_node_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_content (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
|
||||||
-- Update node content to `a_content', node identified by id `a_node_id'.
|
|
||||||
-- The user `a_id' is an existing or new collaborator.
|
|
||||||
require
|
|
||||||
valid_id: a_node_id > 0
|
|
||||||
valid_user_id: a_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
--feature -- Misc
|
|
||||||
|
|
||||||
-- set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: READABLE_STRING_8)
|
|
||||||
-- -- Save data `a_name:a_value' for type `a_type'
|
|
||||||
-- deferred
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- custom_value (a_name: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable TABLE_ITERABLE [READABLE_STRING_8, STRING_8]
|
|
||||||
-- -- Data for name `a_name' and type `a_type'.
|
|
||||||
-- deferred
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- custom_value_names_where (a_where_key, a_where_value: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable LIST [READABLE_STRING_8]
|
|
||||||
-- -- Names where custom value has item `a_where_key' same as `a_where_value' for type `a_type'.
|
|
||||||
-- deferred
|
|
||||||
-- end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,306 +0,0 @@
|
|||||||
note
|
|
||||||
description: "[
|
|
||||||
Configure the basic settings for a CMS application,
|
|
||||||
i.e: where to look for themes, name of the application, etc...
|
|
||||||
|
|
||||||
The settings can be configured by default:
|
|
||||||
- using the current working directory,
|
|
||||||
- using the commands provided by the class
|
|
||||||
- or by an external configuration file.
|
|
||||||
]"
|
|
||||||
|
|
||||||
class
|
|
||||||
CMS_CONFIGURATION
|
|
||||||
|
|
||||||
inherit
|
|
||||||
ANY
|
|
||||||
|
|
||||||
SHARED_EXECUTION_ENVIRONMENT
|
|
||||||
export
|
|
||||||
{NONE} all
|
|
||||||
end
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
|
||||||
|
|
||||||
make (a_layout: CMS_LAYOUT)
|
|
||||||
-- Initialize `Current' with layout `a_layout'.
|
|
||||||
do
|
|
||||||
layout := a_layout
|
|
||||||
create options.make_equal (10)
|
|
||||||
configuration_location := layout.cms_config_ini_path
|
|
||||||
import_from_path (layout.cms_config_ini_path)
|
|
||||||
analyze
|
|
||||||
end
|
|
||||||
|
|
||||||
analyze
|
|
||||||
do
|
|
||||||
get_root_location
|
|
||||||
get_var_location
|
|
||||||
get_themes_location
|
|
||||||
get_files_location
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
|
|
||||||
configuration_location: detachable PATH
|
|
||||||
-- Path to configuration location.
|
|
||||||
|
|
||||||
option (a_name: READABLE_STRING_GENERAL): detachable ANY
|
|
||||||
do
|
|
||||||
Result := options.item (a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
options: STRING_TABLE [STRING_32]
|
|
||||||
|
|
||||||
feature -- Conversion
|
|
||||||
|
|
||||||
append_to_string (s: STRING)
|
|
||||||
local
|
|
||||||
utf: UTF_CONVERTER
|
|
||||||
do
|
|
||||||
s.append ("Options:%N")
|
|
||||||
across
|
|
||||||
options as c
|
|
||||||
loop
|
|
||||||
s.append (c.key.to_string_8)
|
|
||||||
s.append_character ('=')
|
|
||||||
utf.string_32_into_utf_8_string_8 (c.item, s)
|
|
||||||
s.append_character ('%N')
|
|
||||||
end
|
|
||||||
|
|
||||||
s.append ("Specific:%N")
|
|
||||||
s.append ("root_location=" + root_location.utf_8_name + "%N")
|
|
||||||
s.append ("var_location=" + var_location.utf_8_name + "%N")
|
|
||||||
s.append ("files_location=" + files_location.utf_8_name + "%N")
|
|
||||||
s.append ("themes_location=" + themes_location.utf_8_name + "%N")
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Element change
|
|
||||||
|
|
||||||
set_option (a_name: READABLE_STRING_GENERAL; a_value: STRING_32)
|
|
||||||
do
|
|
||||||
options.force (a_value, a_name.as_string_8)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
var_location: PATH
|
|
||||||
|
|
||||||
root_location: PATH
|
|
||||||
|
|
||||||
files_location: PATH
|
|
||||||
|
|
||||||
themes_location: PATH
|
|
||||||
|
|
||||||
theme_name (dft: detachable like theme_name): READABLE_STRING_8
|
|
||||||
do
|
|
||||||
if attached options.item ("theme") as s then
|
|
||||||
Result := s
|
|
||||||
elseif dft /= Void then
|
|
||||||
Result := dft
|
|
||||||
else
|
|
||||||
Result := "default"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
site_id: READABLE_STRING_8
|
|
||||||
do
|
|
||||||
if attached options.item ("site.id") as s then
|
|
||||||
Result := s
|
|
||||||
else
|
|
||||||
Result := "_EWF_CMS_NO_ID_"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
site_name (dft: like site_name): READABLE_STRING_8
|
|
||||||
do
|
|
||||||
if attached options.item ("site.name") as s then
|
|
||||||
Result := s
|
|
||||||
else
|
|
||||||
Result := dft
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
site_url (dft: like site_url): detachable READABLE_STRING_8
|
|
||||||
do
|
|
||||||
if attached options.item ("site.url") as s then
|
|
||||||
Result := s
|
|
||||||
else
|
|
||||||
Result := dft
|
|
||||||
end
|
|
||||||
if Result /= Void then
|
|
||||||
if Result.is_empty then
|
|
||||||
-- ok
|
|
||||||
elseif not Result.ends_with ("/") then
|
|
||||||
Result := Result + "/"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
site_script_url (dft: like site_script_url): detachable READABLE_STRING_8
|
|
||||||
do
|
|
||||||
if attached options.item ("site.script_url") as s then
|
|
||||||
Result := s
|
|
||||||
else
|
|
||||||
Result := dft
|
|
||||||
end
|
|
||||||
if Result /= Void then
|
|
||||||
if Result.is_empty then
|
|
||||||
elseif not Result.ends_with ("/") then
|
|
||||||
Result := Result + "/"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
site_email (dft: like site_email): READABLE_STRING_8
|
|
||||||
do
|
|
||||||
if attached options.item ("site.email") as s then
|
|
||||||
Result := s
|
|
||||||
else
|
|
||||||
Result := dft
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Change
|
|
||||||
|
|
||||||
get_var_location
|
|
||||||
local
|
|
||||||
utf: UTF_CONVERTER
|
|
||||||
do
|
|
||||||
if attached options.item ("var-dir") as s then
|
|
||||||
create var_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
|
|
||||||
else
|
|
||||||
var_location := execution_environment.current_working_path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
get_root_location
|
|
||||||
do
|
|
||||||
root_location := layout.www_path
|
|
||||||
end
|
|
||||||
|
|
||||||
get_files_location
|
|
||||||
local
|
|
||||||
utf: UTF_CONVERTER
|
|
||||||
do
|
|
||||||
if attached options.item ("files-dir") as s then
|
|
||||||
create files_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
|
|
||||||
else
|
|
||||||
create files_location.make_from_string ("files")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
get_themes_location
|
|
||||||
local
|
|
||||||
utf: UTF_CONVERTER
|
|
||||||
do
|
|
||||||
if attached options.item ("themes-dir") as s then
|
|
||||||
create themes_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
|
|
||||||
else
|
|
||||||
themes_location := root_location.extended ("themes")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
import_from_file (fn: READABLE_STRING_GENERAL)
|
|
||||||
do
|
|
||||||
import_from_path (create {PATH}.make_from_string (fn))
|
|
||||||
end
|
|
||||||
|
|
||||||
import_from_path (a_filename: PATH)
|
|
||||||
-- Import ini file content
|
|
||||||
local
|
|
||||||
f: PLAIN_TEXT_FILE
|
|
||||||
l,v: STRING_8
|
|
||||||
p: INTEGER
|
|
||||||
do
|
|
||||||
create f.make_with_path (a_filename)
|
|
||||||
if f.exists and f.is_readable then
|
|
||||||
f.open_read
|
|
||||||
from
|
|
||||||
f.read_line
|
|
||||||
until
|
|
||||||
f.exhausted
|
|
||||||
loop
|
|
||||||
l := f.last_string
|
|
||||||
l.left_adjust
|
|
||||||
if not l.is_empty then
|
|
||||||
if l[1] = '#' then
|
|
||||||
-- commented line
|
|
||||||
else
|
|
||||||
p := l.index_of ('=', 1)
|
|
||||||
if p > 1 then
|
|
||||||
v := l.substring (p + 1, l.count)
|
|
||||||
l.keep_head (p - 1)
|
|
||||||
v.left_adjust
|
|
||||||
v.right_adjust
|
|
||||||
l.right_adjust
|
|
||||||
|
|
||||||
if l.is_case_insensitive_equal ("@include") then
|
|
||||||
import_from_file (resolved_string (v))
|
|
||||||
else
|
|
||||||
set_option (l.as_lower, resolved_string (v))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
f.read_line
|
|
||||||
end
|
|
||||||
f.close
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Environment
|
|
||||||
|
|
||||||
resolved_string (s: READABLE_STRING_8): STRING_32
|
|
||||||
-- Resolved `s' using `options' or else environment variables.
|
|
||||||
local
|
|
||||||
i,n,b,e: INTEGER
|
|
||||||
k: detachable READABLE_STRING_8
|
|
||||||
do
|
|
||||||
from
|
|
||||||
i := 1
|
|
||||||
n := s.count
|
|
||||||
create Result.make (s.count)
|
|
||||||
until
|
|
||||||
i > n
|
|
||||||
loop
|
|
||||||
if i + 1 < n and then s[i] = '$' and then s[i+1] = '{' then
|
|
||||||
b := i + 2
|
|
||||||
e := s.index_of ('}', b) - 1
|
|
||||||
if e > 0 then
|
|
||||||
k := s.substring (b, e)
|
|
||||||
if attached option (k) as v then
|
|
||||||
if attached {READABLE_STRING_32} v as s32 then
|
|
||||||
Result.append (s32)
|
|
||||||
else
|
|
||||||
Result.append (v.out)
|
|
||||||
end
|
|
||||||
i := e + 1
|
|
||||||
elseif attached execution_environment.item (k) as v then
|
|
||||||
Result.append (v)
|
|
||||||
i := e + 1
|
|
||||||
else
|
|
||||||
Result.extend (s[i])
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Result.extend (s[i])
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Result.extend (s[i])
|
|
||||||
end
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature -- Implementation
|
|
||||||
|
|
||||||
layout: CMS_LAYOUT
|
|
||||||
-- Cms layout
|
|
||||||
end
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {CMS_CUSTOM_SETUP}."
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
CMS_CUSTOM_SETUP
|
|
||||||
|
|
||||||
inherit
|
|
||||||
CMS_DEFAULT_SETUP
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_DEFAULT_SETUP}."
|
description: "[
|
||||||
date: "$Date$"
|
Default CMS_SETUP that can be reused easily, and/or redefined to match specific setup.
|
||||||
revision: "$Revision$"
|
]"
|
||||||
|
date: "$Date: 2015-01-14 16:13:47 +0100 (mer., 14 janv. 2015) $"
|
||||||
|
revision: "$Revision: 96454 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
CMS_DEFAULT_SETUP
|
CMS_DEFAULT_SETUP
|
||||||
@@ -10,6 +12,7 @@ inherit
|
|||||||
CMS_SETUP
|
CMS_SETUP
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
@@ -19,27 +22,50 @@ feature {NONE} -- Initialization
|
|||||||
-- Create a default setup with `a_layout'.
|
-- Create a default setup with `a_layout'.
|
||||||
do
|
do
|
||||||
layout := a_layout
|
layout := a_layout
|
||||||
create configuration.make (layout)
|
create {INI_CONFIG} configuration.make_from_file (layout.cms_config_ini_path)
|
||||||
initialize
|
initialize
|
||||||
end
|
end
|
||||||
|
|
||||||
initialize
|
initialize
|
||||||
-- Initialize varius cms components.
|
-- Initialize various cms components.
|
||||||
do
|
do
|
||||||
configure
|
configure
|
||||||
create modules.make (3)
|
create modules.make (3)
|
||||||
|
create storage_drivers.make (2)
|
||||||
|
|
||||||
build_mailer
|
build_mailer
|
||||||
|
initialize_storages
|
||||||
initialize_modules
|
initialize_modules
|
||||||
end
|
end
|
||||||
|
|
||||||
configure
|
configure
|
||||||
do
|
do
|
||||||
site_id := configuration.site_id
|
--| Site id, used to identified a site, this could be set to a uuid, or else
|
||||||
site_url := configuration.site_url (Void)
|
site_id := text_item_or_default ("site.id", "_EWF_CMS_NO_ID_")
|
||||||
site_name := configuration.site_name ("EWF::CMS")
|
|
||||||
site_email := configuration.site_email ("webmaster")
|
-- Site url: optional, but ending with a slash
|
||||||
themes_location := configuration.themes_location
|
site_url := string_8_item ("site_url")
|
||||||
theme_name := configuration.theme_name ("default")
|
if attached site_url as l_url and then not l_url.is_empty then
|
||||||
|
if l_url[l_url.count] /= '/' then
|
||||||
|
site_url := l_url + "/"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Site name
|
||||||
|
site_name := text_item_or_default ("site.name", "EWF::CMS")
|
||||||
|
|
||||||
|
-- Site email for any internal notification
|
||||||
|
-- Can be also used to precise the "From:" value for email.
|
||||||
|
site_email := text_item_or_default ("site.email", "webmaster")
|
||||||
|
|
||||||
|
-- Location for theme folders.
|
||||||
|
if attached text_item ("themes-dir") as s then
|
||||||
|
create themes_location.make_from_string (s)
|
||||||
|
else
|
||||||
|
themes_location := layout.www_path.extended ("themes")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Selected theme's name
|
||||||
|
theme_name := text_item_or_default ("theme", "default")
|
||||||
|
|
||||||
debug ("refactor_fixme")
|
debug ("refactor_fixme")
|
||||||
fixme ("Review export clause for configuration and layout")
|
fixme ("Review export clause for configuration and layout")
|
||||||
@@ -49,6 +75,12 @@ feature {NONE} -- Initialization
|
|||||||
compute_theme_assets_location
|
compute_theme_assets_location
|
||||||
end
|
end
|
||||||
|
|
||||||
|
initialize_storages
|
||||||
|
-- Initialize storages
|
||||||
|
do
|
||||||
|
storage_drivers.force (create {CMS_STORAGE_NULL_BUILDER}, "null")
|
||||||
|
end
|
||||||
|
|
||||||
initialize_modules
|
initialize_modules
|
||||||
-- Intialize core modules.
|
-- Intialize core modules.
|
||||||
local
|
local
|
||||||
@@ -57,34 +89,58 @@ feature {NONE} -- Initialization
|
|||||||
-- -- Core
|
-- -- Core
|
||||||
-- create {USER_MODULE} m.make (Current)
|
-- create {USER_MODULE} m.make (Current)
|
||||||
-- m.enable
|
-- m.enable
|
||||||
-- modules.extend (m)
|
-- register_module (m)
|
||||||
|
|
||||||
-- create {ADMIN_MODULE} m.make (Current)
|
-- create {ADMIN_MODULE} m.make (Current)
|
||||||
-- m.enable
|
-- m.enable
|
||||||
-- modules.extend (m)
|
-- register_module (m)
|
||||||
|
|
||||||
create {NODE_MODULE} m.make (Current)
|
create {NODE_MODULE} m.make (Current)
|
||||||
m.enable
|
m.enable
|
||||||
modules.extend (m)
|
register_module (m)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Configuration
|
||||||
|
|
||||||
|
configuration: CONFIG_READER
|
||||||
|
-- Association configuration file.
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
modules: CMS_MODULE_COLLECTION
|
modules: CMS_MODULE_COLLECTION
|
||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
|
|
||||||
|
text_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- Configuration value associated with `a_name', if any.
|
||||||
|
do
|
||||||
|
Result := configuration.resolved_text_item (a_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
string_8_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_8
|
||||||
|
-- String 8 configuration value associated with `a_name', if any.
|
||||||
|
local
|
||||||
|
utf: UTF_CONVERTER
|
||||||
|
do
|
||||||
|
if attached text_item (a_name) as s then
|
||||||
|
if s.is_valid_as_string_8 then
|
||||||
|
Result := s.as_string_8
|
||||||
|
else
|
||||||
|
Result := utf.escaped_utf_32_string_to_utf_8_string_8 (s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
is_html: BOOLEAN
|
is_html: BOOLEAN
|
||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
do
|
do
|
||||||
-- Enable change the mode
|
-- Enable change the mode
|
||||||
Result := (create {CMS_JSON_CONFIGURATION}).is_html_mode(layout.application_config_path)
|
Result := (create {CMS_JSON_CONFIGURATION}).is_html_mode (layout.application_config_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
is_web: BOOLEAN
|
is_web: BOOLEAN
|
||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
do
|
do
|
||||||
Result := (create {CMS_JSON_CONFIGURATION}).is_web_mode(layout.application_config_path)
|
Result := (create {CMS_JSON_CONFIGURATION}).is_web_mode (layout.application_config_path)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
build_auth_engine
|
build_auth_engine
|
||||||
@@ -97,6 +153,19 @@ feature -- Access
|
|||||||
to_implement ("Not implemented mailer")
|
to_implement ("Not implemented mailer")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Access: storage
|
||||||
|
|
||||||
|
storage_drivers: STRING_TABLE [CMS_STORAGE_BUILDER]
|
||||||
|
-- Precursor
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
register_module (m: CMS_MODULE)
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
modules.extend (m)
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Compute location
|
feature -- Compute location
|
||||||
|
|
||||||
compute_theme_location
|
compute_theme_location
|
||||||
@@ -111,7 +180,7 @@ feature -- Compute location
|
|||||||
debug ("refactor_fixme")
|
debug ("refactor_fixme")
|
||||||
fixme ("Check if we really need it")
|
fixme ("Check if we really need it")
|
||||||
end
|
end
|
||||||
-- Check how to get this path from the CMS_THEME information.
|
-- Check how to get this path from the CMS_THEME information.
|
||||||
theme_assets_location := theme_location.extended ("assets")
|
theme_assets_location := theme_location.extended ("assets")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_JSON_CONFIGURATION}."
|
description: "Summary description for {CMS_JSON_CONFIGURATION}."
|
||||||
date: "$Date$"
|
date: "$Date: 2015-01-14 16:13:47 +0100 (mer., 14 janv. 2015) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96454 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
CMS_JSON_CONFIGURATION
|
CMS_JSON_CONFIGURATION
|
||||||
|
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
JSON_CONFIGURATION
|
APPLICATION_JSON_CONFIGURATION_HELPER
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
is_html_mode (a_path: PATH): BOOLEAN
|
is_html_mode (a_path: PATH): BOOLEAN
|
||||||
@@ -19,29 +18,36 @@ feature -- Access
|
|||||||
l_parser: JSON_PARSER
|
l_parser: JSON_PARSER
|
||||||
do
|
do
|
||||||
if attached json_file_from (a_path) as json_file then
|
if attached json_file_from (a_path) as json_file then
|
||||||
l_parser := new_json_parser (json_file)
|
l_parser := new_json_parser (json_file)
|
||||||
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
|
l_parser.parse_content
|
||||||
attached {JSON_OBJECT} jv.item ("server") as l_server and then
|
if
|
||||||
attached {JSON_STRING} l_server.item ("mode") as l_mode then
|
l_parser.is_valid and then
|
||||||
Result := l_mode.item.is_case_insensitive_equal_general ("html")
|
attached l_parser.parsed_json_object as jo and then l_parser.is_parsed and then
|
||||||
end
|
attached {JSON_OBJECT} jo.item ("server") as l_server and then
|
||||||
|
attached {JSON_STRING} l_server.item ("mode") as l_mode
|
||||||
|
then
|
||||||
|
Result := l_mode.item.is_case_insensitive_equal_general ("html")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
is_web_mode (a_path: PATH): BOOLEAN
|
is_web_mode (a_path: PATH): BOOLEAN
|
||||||
-- Is the server running on web mode?
|
-- Is the server running on web mode?
|
||||||
local
|
local
|
||||||
l_parser: JSON_PARSER
|
l_parser: JSON_PARSER
|
||||||
do
|
do
|
||||||
if attached json_file_from (a_path) as json_file then
|
if attached json_file_from (a_path) as json_file then
|
||||||
l_parser := new_json_parser (json_file)
|
l_parser := new_json_parser (json_file)
|
||||||
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
|
l_parser.parse_content
|
||||||
attached {JSON_OBJECT} jv.item ("server") as l_server and then
|
if
|
||||||
attached {JSON_STRING} l_server.item ("mode") as l_mode then
|
l_parser.is_valid and then
|
||||||
Result := l_mode.item.is_case_insensitive_equal_general ("web")
|
attached l_parser.parsed_json_object as jo and then l_parser.is_parsed and then
|
||||||
end
|
attached {JSON_OBJECT} jo.item ("server") as l_server and then
|
||||||
|
attached {JSON_STRING} l_server.item ("mode") as l_mode
|
||||||
|
then
|
||||||
|
Result := l_mode.item.is_case_insensitive_equal_general ("web")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ note
|
|||||||
- documentation
|
- documentation
|
||||||
- themes
|
- themes
|
||||||
]"
|
]"
|
||||||
date: "$Date$"
|
date: "$Date: 2014-12-18 16:37:11 +0100 (jeu., 18 déc. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96383 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
CMS_LAYOUT
|
CMS_LAYOUT
|
||||||
@@ -38,7 +38,7 @@ feature -- Access
|
|||||||
end
|
end
|
||||||
|
|
||||||
cms_config_ini_path: PATH
|
cms_config_ini_path: PATH
|
||||||
-- Database Configuration file path.
|
-- CMS Configuration file path.
|
||||||
local
|
local
|
||||||
p: detachable PATH
|
p: detachable PATH
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
note
|
note
|
||||||
description: "Class that enable to set basic configuration, application layout, core modules and themes."
|
description: "Class that enable to set basic configuration, application layout, core modules and themes."
|
||||||
date: "$Date$"
|
date: "$Date: 2015-01-14 18:12:03 +0100 (mer., 14 janv. 2015) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96456 $"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
CMS_SETUP
|
CMS_SETUP
|
||||||
|
|
||||||
feature -- Access
|
inherit
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
configuration: CMS_CONFIGURATION
|
feature -- Access
|
||||||
-- cms configuration.
|
|
||||||
|
|
||||||
layout: CMS_LAYOUT
|
layout: CMS_LAYOUT
|
||||||
-- CMS layout.
|
-- CMS layout.
|
||||||
@@ -24,6 +24,26 @@ feature -- Access
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
enabled_modules: CMS_MODULE_COLLECTION
|
||||||
|
-- List of enabled modules.
|
||||||
|
local
|
||||||
|
l_module: CMS_MODULE
|
||||||
|
do
|
||||||
|
create Result.make (modules.count)
|
||||||
|
across
|
||||||
|
modules as ic
|
||||||
|
loop
|
||||||
|
l_module := ic.item
|
||||||
|
if l_module.is_enabled then
|
||||||
|
Result.extend (l_module)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
only_enabled_modules: across Result as ic all ic.item.is_enabled end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {CMS_MODULE} -- Restricted access
|
||||||
|
|
||||||
modules: CMS_MODULE_COLLECTION
|
modules: CMS_MODULE_COLLECTION
|
||||||
-- List of available modules.
|
-- List of available modules.
|
||||||
deferred
|
deferred
|
||||||
@@ -32,12 +52,15 @@ feature -- Access
|
|||||||
feature -- Access: Site
|
feature -- Access: Site
|
||||||
|
|
||||||
site_id: READABLE_STRING_8
|
site_id: READABLE_STRING_8
|
||||||
|
-- String identifying current CMS.
|
||||||
|
-- This could be used in webform, for cookie name, ...
|
||||||
|
|
||||||
site_name: READABLE_STRING_32
|
site_name: READABLE_STRING_32
|
||||||
-- Name of the site.
|
-- Name of the site.
|
||||||
|
|
||||||
site_email: READABLE_STRING_8
|
site_email: READABLE_STRING_8
|
||||||
-- Email for the site.
|
-- Admin email address for the site.
|
||||||
|
-- Mainly used for internal notification.
|
||||||
|
|
||||||
site_url: detachable READABLE_STRING_8
|
site_url: detachable READABLE_STRING_8
|
||||||
-- Optional base url of the site.
|
-- Optional base url of the site.
|
||||||
@@ -46,19 +69,41 @@ feature -- Access: Site
|
|||||||
-- Optional path defining the front page.
|
-- Optional path defining the front page.
|
||||||
-- By default "" or "/".
|
-- By default "" or "/".
|
||||||
|
|
||||||
|
feature -- Query
|
||||||
|
|
||||||
|
text_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- Configuration value associated with `a_name', if any.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
text_item_or_default (a_name: READABLE_STRING_GENERAL; a_default_value: READABLE_STRING_GENERAL): READABLE_STRING_32
|
||||||
|
-- `text_item' associated with `a_name' or if none, `a_default_value'.
|
||||||
|
do
|
||||||
|
if attached text_item (a_name) as v then
|
||||||
|
Result := v
|
||||||
|
else
|
||||||
|
Result := a_default_value.as_string_32
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
string_8_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_8
|
||||||
|
-- Configuration value associated with `a_name', if any.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access: Theme
|
feature -- Access: Theme
|
||||||
|
|
||||||
themes_location: PATH
|
themes_location: PATH
|
||||||
-- Path to themes.
|
-- Path to themes.
|
||||||
|
|
||||||
theme_location: PATH
|
theme_location: PATH
|
||||||
-- Path to a particular theme.
|
-- Path to a active theme.
|
||||||
|
|
||||||
theme_assets_location: PATH
|
theme_assets_location: PATH
|
||||||
-- Path to a particular theme assets folder.
|
-- Path to a active theme assets folder.
|
||||||
|
|
||||||
theme_information_location: PATH
|
theme_information_location: PATH
|
||||||
-- theme informations.
|
-- Active theme informations.
|
||||||
do
|
do
|
||||||
Result := theme_location.extended ("theme.info")
|
Result := theme_location.extended ("theme.info")
|
||||||
end
|
end
|
||||||
@@ -66,4 +111,61 @@ feature -- Access: Theme
|
|||||||
theme_name: READABLE_STRING_32
|
theme_name: READABLE_STRING_32
|
||||||
-- theme name.
|
-- theme name.
|
||||||
|
|
||||||
|
feature -- Access: storage
|
||||||
|
|
||||||
|
storage_drivers: STRING_TABLE [CMS_STORAGE_BUILDER]
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
storage (a_error_handler: ERROR_HANDLER): detachable CMS_STORAGE
|
||||||
|
local
|
||||||
|
retried: BOOLEAN
|
||||||
|
l_message: STRING
|
||||||
|
do
|
||||||
|
if not retried then
|
||||||
|
to_implement ("Refactor database setup")
|
||||||
|
if
|
||||||
|
attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (layout.application_config_path) as l_database_config and then
|
||||||
|
attached storage_drivers.item (l_database_config.driver) as l_builder
|
||||||
|
then
|
||||||
|
Result := l_builder.storage (Current)
|
||||||
|
else
|
||||||
|
create {CMS_STORAGE_NULL} Result
|
||||||
|
end
|
||||||
|
else
|
||||||
|
to_implement ("Workaround code, persistence layer does not implement yet this kind of error handling.")
|
||||||
|
-- error hanling.
|
||||||
|
create {CMS_STORAGE_NULL} Result
|
||||||
|
create l_message.make (1024)
|
||||||
|
if attached ((create {EXCEPTION_MANAGER}).last_exception) as l_exception then
|
||||||
|
if attached l_exception.description as l_description then
|
||||||
|
l_message.append (l_description.as_string_32)
|
||||||
|
l_message.append ("%N%N")
|
||||||
|
elseif attached l_exception.trace as l_trace then
|
||||||
|
l_message.append (l_trace)
|
||||||
|
l_message.append ("%N%N")
|
||||||
|
else
|
||||||
|
l_message.append (l_exception.out)
|
||||||
|
l_message.append ("%N%N")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
l_message.append ("The application crash without available information")
|
||||||
|
l_message.append ("%N%N")
|
||||||
|
end
|
||||||
|
a_error_handler.add_custom_error (0, " Database Connection ", l_message)
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
retried := True
|
||||||
|
retry
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
register_module (m: CMS_MODULE)
|
||||||
|
-- Add module `m' to `modules'
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
module_added: modules.has (m)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_HOOK_BLOCK}."
|
description: "[
|
||||||
|
Hook providing a way to alter a block.
|
||||||
|
]"
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
|||||||
29
library/src/hooks/cms_hook_block_helper.e
Normal file
29
library/src/hooks/cms_hook_block_helper.e
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_HOOK_BLOCK_HELPER}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date: 2015-01-14 16:13:47 +0100 (mer., 14 janv. 2015) $"
|
||||||
|
revision: "$Revision: 96454 $"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_HOOK_BLOCK_HELPER
|
||||||
|
|
||||||
|
feature -- Factory
|
||||||
|
|
||||||
|
template_block (a_module: CMS_MODULE; a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE): detachable CMS_SMARTY_TEMPLATE_BLOCK
|
||||||
|
-- Smarty content block for `a_block_id' in the context of `a_module' and `a_response'.
|
||||||
|
local
|
||||||
|
p: detachable PATH
|
||||||
|
do
|
||||||
|
create p.make_from_string ("templates")
|
||||||
|
p := p.extended ("block_").appended (a_block_id).appended_with_extension ("tpl")
|
||||||
|
p := a_response.module_resource_path (a_module, p)
|
||||||
|
if p /= Void then
|
||||||
|
if attached p.entry as e then
|
||||||
|
create Result.make (a_block_id, Void, p.parent, e)
|
||||||
|
else
|
||||||
|
create Result.make (a_block_id, Void, p.parent, p)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_BLOCK}."
|
description: "Describe content to be placed inside Regions."
|
||||||
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
|
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
@@ -8,20 +8,30 @@ deferred class
|
|||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
name: READABLE_STRING_8
|
name: READABLE_STRING_8
|
||||||
|
-- Name identifying Current block.
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
title: detachable READABLE_STRING_32
|
title: detachable READABLE_STRING_32
|
||||||
|
-- Optional title.
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- status report
|
feature -- status report
|
||||||
|
|
||||||
is_enabled: BOOLEAN
|
is_enabled: BOOLEAN
|
||||||
|
-- Is current block enabled?
|
||||||
|
|
||||||
|
is_raw: BOOLEAN
|
||||||
|
-- Is raw?
|
||||||
|
-- If True, do not get wrapped it with block specific div
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Conversion
|
feature -- Conversion
|
||||||
|
|
||||||
to_html (a_theme: CMS_THEME): STRING_8
|
to_html (a_theme: CMS_THEME): STRING_8
|
||||||
|
-- HTML representation of Current block.
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_CONTENT_BLOCK}."
|
description: "CMS_BLOCK implemented with a `content' associated with a specific `format'."
|
||||||
author: ""
|
date: "$Date$"
|
||||||
date: "$Date: 2014-10-30 12:55:33 -0300 (ju. 30 de oct. de 2014) $"
|
revision: "$Revision$"
|
||||||
revision: "$Revision: 96018 $"
|
|
||||||
|
|
||||||
class
|
class
|
||||||
CMS_CONTENT_BLOCK
|
CMS_CONTENT_BLOCK
|
||||||
@@ -17,6 +16,8 @@ create
|
|||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (a_name: like name; a_title: like title; a_content: like content; a_format: like format)
|
make (a_name: like name; a_title: like title; a_content: like content; a_format: like format)
|
||||||
|
require
|
||||||
|
a_name_not_blank: not a_name.is_whitespace
|
||||||
do
|
do
|
||||||
is_enabled := True
|
is_enabled := True
|
||||||
name := a_name
|
name := a_name
|
||||||
@@ -26,6 +27,8 @@ feature {NONE} -- Initialization
|
|||||||
end
|
end
|
||||||
|
|
||||||
make_raw (a_name: like name; a_title: like title; a_content: like content; a_format: like format)
|
make_raw (a_name: like name; a_title: like title; a_content: like content; a_format: like format)
|
||||||
|
require
|
||||||
|
a_name_not_blank: not a_name.is_whitespace
|
||||||
do
|
do
|
||||||
make (a_name, a_title, a_content, a_format)
|
make (a_name, a_title, a_content, a_format)
|
||||||
set_is_raw (True)
|
set_is_raw (True)
|
||||||
@@ -54,6 +57,20 @@ feature -- Element change
|
|||||||
is_raw := b
|
is_raw := b
|
||||||
end
|
end
|
||||||
|
|
||||||
|
set_name (n: like name)
|
||||||
|
-- Set `name' to `n'.
|
||||||
|
require
|
||||||
|
not n.is_whitespace
|
||||||
|
do
|
||||||
|
name := n
|
||||||
|
end
|
||||||
|
|
||||||
|
set_title (a_title: like title)
|
||||||
|
-- Set `title' to `a_title'.
|
||||||
|
do
|
||||||
|
title := a_title
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Conversion
|
feature -- Conversion
|
||||||
|
|
||||||
to_html (a_theme: CMS_THEME): STRING_8
|
to_html (a_theme: CMS_THEME): STRING_8
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_MENU_BLOCK}."
|
description: "Summary description for {CMS_MENU_BLOCK}."
|
||||||
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
|
date: "$Date: 2014-11-14 20:11:17 +0100 (ven., 14 nov. 2014) $"
|
||||||
|
|
||||||
class
|
class
|
||||||
CMS_MENU_BLOCK
|
CMS_MENU_BLOCK
|
||||||
@@ -29,8 +29,29 @@ feature -- Access
|
|||||||
|
|
||||||
title: detachable READABLE_STRING_32
|
title: detachable READABLE_STRING_32
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
is_horizontal: BOOLEAN
|
is_horizontal: BOOLEAN
|
||||||
|
|
||||||
|
is_raw: BOOLEAN = False
|
||||||
|
-- <Precursor>
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
set_name (n: like name)
|
||||||
|
-- Set `name' to `n'.
|
||||||
|
require
|
||||||
|
not n.is_whitespace
|
||||||
|
do
|
||||||
|
name := n
|
||||||
|
end
|
||||||
|
|
||||||
|
set_title (a_title: like title)
|
||||||
|
-- Set `title' to `a_title'.
|
||||||
|
do
|
||||||
|
title := a_title
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Conversion
|
feature -- Conversion
|
||||||
|
|
||||||
to_html (a_theme: CMS_THEME): STRING_8
|
to_html (a_theme: CMS_THEME): STRING_8
|
||||||
|
|||||||
195
library/src/kernel/content/cms_smarty_template_block.e
Normal file
195
library/src/kernel/content/cms_smarty_template_block.e
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
CMS block with smarty template file content.
|
||||||
|
]"
|
||||||
|
date: "$Date: 2014-12-05 22:39:27 +0100 (ven., 05 déc. 2014) $"
|
||||||
|
revision: "$Revision: 96260 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_SMARTY_TEMPLATE_BLOCK
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_BLOCK
|
||||||
|
redefine
|
||||||
|
out
|
||||||
|
select
|
||||||
|
out
|
||||||
|
end
|
||||||
|
SHARED_TEMPLATE_CONTEXT
|
||||||
|
rename
|
||||||
|
out as tpl_out
|
||||||
|
end
|
||||||
|
|
||||||
|
create
|
||||||
|
make,
|
||||||
|
make_raw
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_name: like name; a_title: like title; a_template_root_path: PATH; a_template_location: PATH)
|
||||||
|
-- Create Current with `a_name', `a_title', `a_template_location'
|
||||||
|
-- inside root directory `a_template_root_path' for the templates.
|
||||||
|
require
|
||||||
|
a_name_not_blank: not a_name.is_whitespace
|
||||||
|
do
|
||||||
|
is_enabled := True
|
||||||
|
name := a_name
|
||||||
|
title := a_title
|
||||||
|
location := a_template_location
|
||||||
|
template_root_path := a_template_root_path
|
||||||
|
create values.make (0)
|
||||||
|
end
|
||||||
|
|
||||||
|
make_raw (a_name: like name; a_title: like title; a_template_root_path: PATH; a_template_location: PATH)
|
||||||
|
-- Create Current with `a_name', `a_title', `a_template_location'
|
||||||
|
-- inside root directory `a_template_root_path' for the templates.
|
||||||
|
require
|
||||||
|
a_name_not_blank: not a_name.is_whitespace
|
||||||
|
do
|
||||||
|
make (a_name, a_title, a_template_root_path, a_template_location)
|
||||||
|
set_is_raw (True)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
name: READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
|
||||||
|
title: detachable READABLE_STRING_32
|
||||||
|
-- <Precursor>
|
||||||
|
|
||||||
|
location: PATH
|
||||||
|
-- Location of template file.
|
||||||
|
|
||||||
|
template_root_path: PATH
|
||||||
|
-- Root location for templates universe.
|
||||||
|
|
||||||
|
values: STRING_TABLE [detachable ANY]
|
||||||
|
-- Additional value used during template output processing.
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_raw: BOOLEAN
|
||||||
|
-- Is raw?
|
||||||
|
-- If True, do not get wrapped it with block specific div
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
set_is_raw (b: BOOLEAN)
|
||||||
|
do
|
||||||
|
is_raw := b
|
||||||
|
end
|
||||||
|
|
||||||
|
set_name (n: like name)
|
||||||
|
-- Set `name' to `n'.
|
||||||
|
require
|
||||||
|
not n.is_whitespace
|
||||||
|
do
|
||||||
|
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
|
||||||
|
values.force (v, k)
|
||||||
|
end
|
||||||
|
|
||||||
|
unset_value (k: READABLE_STRING_GENERAL)
|
||||||
|
-- Remove value indexed by key `k'.
|
||||||
|
do
|
||||||
|
values.remove (k)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Conversion
|
||||||
|
|
||||||
|
to_html (a_theme: CMS_THEME): STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
p: detachable PATH
|
||||||
|
tpl: detachable TEMPLATE_FILE
|
||||||
|
ut: FILE_UTILITIES
|
||||||
|
n: STRING_32
|
||||||
|
l_table_inspector: detachable STRING_TABLE_OF_STRING_INSPECTOR
|
||||||
|
do
|
||||||
|
-- Process html generation
|
||||||
|
p := location
|
||||||
|
if ut.file_path_exists (template_root_path.extended_path (p)) then
|
||||||
|
n := p.name
|
||||||
|
template_context.set_template_folder (template_root_path)
|
||||||
|
template_context.disable_verbose
|
||||||
|
debug ("cms")
|
||||||
|
template_context.enable_verbose
|
||||||
|
end
|
||||||
|
|
||||||
|
create tpl.make_from_file (n)
|
||||||
|
|
||||||
|
across
|
||||||
|
values as ic
|
||||||
|
loop
|
||||||
|
tpl.add_value (ic.item, ic.key)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
create l_table_inspector.register (({detachable STRING_TABLE [STRING_8]}).name)
|
||||||
|
create l_table_inspector.register (({detachable STRING_TABLE [STRING_32]}).name)
|
||||||
|
create l_table_inspector.register (({detachable STRING_TABLE [READABLE_STRING_8]}).name)
|
||||||
|
create l_table_inspector.register (({detachable STRING_TABLE [READABLE_STRING_32]}).name)
|
||||||
|
tpl.analyze
|
||||||
|
tpl.get_output
|
||||||
|
l_table_inspector.unregister
|
||||||
|
-- l_table32_inspector.unregister
|
||||||
|
|
||||||
|
if attached tpl.output as l_output then
|
||||||
|
Result := l_output
|
||||||
|
else
|
||||||
|
Result := ""
|
||||||
|
debug ("cms")
|
||||||
|
Result := "Template block #" + name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := ""
|
||||||
|
debug ("cms")
|
||||||
|
Result := "Template block #" + name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Debug
|
||||||
|
|
||||||
|
out: STRING
|
||||||
|
do
|
||||||
|
create Result.make_from_string (generator)
|
||||||
|
Result.append ("%Nname:")
|
||||||
|
Result.append (name)
|
||||||
|
if attached title as l_title then
|
||||||
|
Result.append ("%N%Ttitle:")
|
||||||
|
Result.append (l_title)
|
||||||
|
end
|
||||||
|
Result.append ("%Nlocation:")
|
||||||
|
Result.append (location.out)
|
||||||
|
Result.append ("%Ntemplate_root_path:")
|
||||||
|
Result.append (template_root_path.out)
|
||||||
|
Result.append ("%NValues: {")
|
||||||
|
from
|
||||||
|
values.start
|
||||||
|
until
|
||||||
|
values.after
|
||||||
|
loop
|
||||||
|
Result.append ("%NKey:")
|
||||||
|
Result.append (values.key_for_iteration.as_string_8)
|
||||||
|
Result.append (" - Value:")
|
||||||
|
if attached values.item_for_iteration as l_item then
|
||||||
|
Result.append (l_item.out)
|
||||||
|
end
|
||||||
|
values.forth
|
||||||
|
end
|
||||||
|
Result.append ("%N}")
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_DEBUG_MODULE}."
|
description: "Summary description for {CMS_DEBUG_MODULE}."
|
||||||
date: "$Date: 2014-08-28 13:21:49 +0200 (jeu., 28 août 2014) $"
|
date: "$Date: 2014-12-18 16:47:20 +0100 (jeu., 18 déc. 2014) $"
|
||||||
revision: "$Revision: 95708 $"
|
revision: "$Revision: 96384 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
CMS_DEBUG_MODULE
|
CMS_DEBUG_MODULE
|
||||||
@@ -82,7 +82,7 @@ feature -- Handler
|
|||||||
append_info_to ("Name", api.setup.site_name, r, s)
|
append_info_to ("Name", api.setup.site_name, r, s)
|
||||||
append_info_to ("Url", api.setup.site_url, r, s)
|
append_info_to ("Url", api.setup.site_url, r, s)
|
||||||
|
|
||||||
if attached api.setup.configuration.configuration_location as l_loc then
|
if attached api.setup.layout.cms_config_ini_path as l_loc then
|
||||||
s.append ("<hr/>")
|
s.append ("<hr/>")
|
||||||
append_info_to ("Configuration file", l_loc.name, r, s)
|
append_info_to ("Configuration file", l_loc.name, r, s)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {NEW_CONTENT_HANDLER}."
|
description: "Summary description for {NEW_CONTENT_HANDLER}."
|
||||||
date: "$Date$"
|
date: "$Date: 2014-12-19 14:17:32 +0100 (ven., 19 déc. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96402 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
NODE_CONTENT_HANDLER
|
NODE_CONTENT_HANDLER
|
||||||
@@ -78,7 +78,7 @@ feature -- HTTP Methods
|
|||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
@@ -96,14 +96,14 @@ feature -- HTTP Methods
|
|||||||
if l_method.is_case_insensitive_equal ("PUT") then
|
if l_method.is_case_insensitive_equal ("PUT") then
|
||||||
do_put (req, res)
|
do_put (req, res)
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
@@ -120,14 +120,14 @@ feature -- HTTP Methods
|
|||||||
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
|
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
|
||||||
u_node := extract_data_form (req)
|
u_node := extract_data_form (req)
|
||||||
u_node.set_id (l_id.integer_value)
|
u_node.set_id (l_id.value.to_integer_64)
|
||||||
api.update_node_content (l_user.id, u_node.id, u_node.content)
|
api.update_node_content (l_user.id, u_node.id, u_node.content)
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
||||||
else
|
else
|
||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {NODE_HANDLER}."
|
description: "Summary description for {NODE_HANDLER}."
|
||||||
date: "$Date$"
|
date: "$Date: 2014-12-19 14:17:32 +0100 (ven., 19 déc. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96402 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
NODE_HANDLER
|
NODE_HANDLER
|
||||||
@@ -68,7 +68,10 @@ feature -- HTTP Methods
|
|||||||
do
|
do
|
||||||
-- Existing node
|
-- Existing node
|
||||||
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
|
if
|
||||||
|
l_id.is_integer and then
|
||||||
|
attached api.node (l_id.value.to_integer_64) as l_node
|
||||||
|
then
|
||||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||||
l_page.add_variable (l_node, "node")
|
l_page.add_variable (l_node, "node")
|
||||||
l_page.execute
|
l_page.execute
|
||||||
@@ -89,14 +92,17 @@ feature -- HTTP Methods
|
|||||||
to_implement ("Check user permissions!!!")
|
to_implement ("Check user permissions!!!")
|
||||||
if attached current_user (req) as l_user then
|
if attached current_user (req) as l_user then
|
||||||
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
|
if
|
||||||
|
l_id.is_integer and then
|
||||||
|
attached {CMS_NODE} api.node (l_id.value.to_integer_64) as l_node
|
||||||
|
then
|
||||||
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
|
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
|
||||||
if l_method.is_case_insensitive_equal ("DELETE") then
|
if l_method.is_case_insensitive_equal ("DELETE") then
|
||||||
do_delete (req, res)
|
do_delete (req, res)
|
||||||
elseif l_method.is_case_insensitive_equal ("PUT") then
|
elseif l_method.is_case_insensitive_equal ("PUT") then
|
||||||
do_put (req, res)
|
do_put (req, res)
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -104,7 +110,8 @@ feature -- HTTP Methods
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- New node
|
-- New node
|
||||||
u_node := extract_data_form (req)
|
create u_node.make ("", "", "")
|
||||||
|
update_node_from_data_form (req, u_node)
|
||||||
u_node.set_author (l_user)
|
u_node.set_author (l_user)
|
||||||
api.new_node (u_node)
|
api.new_node (u_node)
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
||||||
@@ -116,27 +123,27 @@ feature -- HTTP Methods
|
|||||||
|
|
||||||
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
local
|
|
||||||
u_node: CMS_NODE
|
|
||||||
do
|
do
|
||||||
|
|
||||||
if attached current_user (req) as l_user then
|
if attached current_user (req) as l_user then
|
||||||
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
|
if
|
||||||
u_node := extract_data_form (req)
|
l_id.is_integer and then
|
||||||
u_node.set_id (l_id.integer_value)
|
attached api.node (l_id.value.to_integer_64) as l_node
|
||||||
api.update_node (l_user.id,u_node)
|
then
|
||||||
|
update_node_from_data_form (req, l_node)
|
||||||
|
l_node.set_author (l_user)
|
||||||
|
api.update_node (l_node)
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
||||||
else
|
else
|
||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
|
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
@@ -144,14 +151,17 @@ feature -- HTTP Methods
|
|||||||
do
|
do
|
||||||
if attached current_user_name (req) then
|
if attached current_user_name (req) then
|
||||||
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
|
if
|
||||||
|
l_id.is_integer and then
|
||||||
|
attached api.node (l_id.integer_value) as l_node
|
||||||
|
then
|
||||||
api.delete_node (l_id.integer_value)
|
api.delete_node (l_id.integer_value)
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
||||||
else
|
else
|
||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
@@ -198,19 +208,18 @@ feature {NONE} -- Node
|
|||||||
|
|
||||||
feature -- {NONE} Form data
|
feature -- {NONE} Form data
|
||||||
|
|
||||||
extract_data_form (req: WSF_REQUEST): CMS_NODE
|
update_node_from_data_form (req: WSF_REQUEST; a_node: CMS_NODE)
|
||||||
-- Extract request form data and build a object
|
-- Extract request form data and build a object
|
||||||
-- Node
|
-- Node
|
||||||
do
|
do
|
||||||
create Result.make ("", "", "")
|
|
||||||
if attached {WSF_STRING} req.form_parameter ("title") as l_title then
|
if attached {WSF_STRING} req.form_parameter ("title") as l_title then
|
||||||
Result.set_title (l_title.value)
|
a_node.set_title (l_title.value)
|
||||||
end
|
end
|
||||||
if attached {WSF_STRING} req.form_parameter ("summary") as l_summary then
|
if attached {WSF_STRING} req.form_parameter ("summary") as l_summary then
|
||||||
Result.set_summary (l_summary.value)
|
a_node.set_summary (l_summary.value)
|
||||||
end
|
end
|
||||||
if attached {WSF_STRING} req.form_parameter ("content") as l_content then
|
if attached {WSF_STRING} req.form_parameter ("content") as l_content then
|
||||||
Result.set_content (l_content.value)
|
a_node.set_content (l_content.value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {NODE_SUMMARY_HANDLER}."
|
description: "Summary description for {NODE_SUMMARY_HANDLER}."
|
||||||
date: "$Date$"
|
date: "$Date: 2014-12-19 14:17:32 +0100 (ven., 19 déc. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96402 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
NODE_SUMMARY_HANDLER
|
NODE_SUMMARY_HANDLER
|
||||||
@@ -77,7 +77,7 @@ feature -- HTTP Methods
|
|||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
@@ -95,14 +95,14 @@ feature -- HTTP Methods
|
|||||||
if l_method.is_case_insensitive_equal ("PUT") then
|
if l_method.is_case_insensitive_equal ("PUT") then
|
||||||
do_put (req, res)
|
do_put (req, res)
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
@@ -118,14 +118,14 @@ feature -- HTTP Methods
|
|||||||
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
|
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
|
||||||
u_node := extract_data_form (req)
|
u_node := extract_data_form (req)
|
||||||
u_node.set_id (l_id.integer_value)
|
u_node.set_id (l_id.value.to_integer_64)
|
||||||
api.update_node_summary (l_user.id,u_node.id, u_node.summary)
|
api.update_node_summary (l_user.id,u_node.id, u_node.summary)
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
||||||
else
|
else
|
||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {NODE_TITLE_HANDLER}."
|
description: "Summary description for {NODE_TITLE_HANDLER}."
|
||||||
date: "$Date$"
|
date: "$Date: 2014-12-19 14:17:32 +0100 (ven., 19 déc. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96402 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
NODE_TITLE_HANDLER
|
NODE_TITLE_HANDLER
|
||||||
@@ -77,7 +77,7 @@ feature -- HTTP Methods
|
|||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
@@ -94,14 +94,14 @@ feature -- HTTP Methods
|
|||||||
if l_method.is_case_insensitive_equal ("PUT") then
|
if l_method.is_case_insensitive_equal ("PUT") then
|
||||||
do_put (req, res)
|
do_put (req, res)
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
@@ -118,14 +118,14 @@ feature -- HTTP Methods
|
|||||||
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
|
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
|
||||||
u_node := extract_data_form (req)
|
u_node := extract_data_form (req)
|
||||||
u_node.set_id (l_id.integer_value)
|
u_node.set_id (l_id.value.to_integer_64)
|
||||||
api.update_node_title (l_user.id,u_node.id, u_node.title)
|
api.update_node_title (l_user.id,u_node.id, u_node.title)
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
||||||
else
|
else
|
||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ feature {NONE} -- Initialization
|
|||||||
config := a_setup
|
config := a_setup
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
config: CMS_SETUP
|
config: CMS_SETUP
|
||||||
-- Node configuration.
|
-- Node configuration.
|
||||||
|
|
||||||
@@ -159,10 +158,42 @@ feature -- Handler
|
|||||||
do_get_nodes (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API)
|
do_get_nodes (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API)
|
||||||
local
|
local
|
||||||
r: CMS_RESPONSE
|
r: CMS_RESPONSE
|
||||||
|
s: STRING
|
||||||
|
l_user: CMS_USER
|
||||||
|
l_node: CMS_NODE
|
||||||
do
|
do
|
||||||
create {NOT_IMPLEMENTED_ERROR_CMS_RESPONSE} r.make (req, res, a_api)
|
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_api)
|
||||||
r.set_main_content ("Sorry: listing the CMS nodes is not yet implemented.")
|
|
||||||
r.add_block (create {CMS_CONTENT_BLOCK}.make ("nodes_warning", Void, "/nodes/ is not yet implemented", Void), "highlighted")
|
if attached a_api.user_by_name ("foo") as u then
|
||||||
|
l_user := u
|
||||||
|
else
|
||||||
|
create l_user.make ("foo")
|
||||||
|
l_user.set_password ("foobar#")
|
||||||
|
l_user.set_email ("test@example.com")
|
||||||
|
a_api.new_user (l_user)
|
||||||
|
end
|
||||||
|
if a_api.nodes_count = 0 then
|
||||||
|
create l_node.make ({STRING_32} "This is a content", {STRING_32} "And a summary", {STRING_32} "Nice title")
|
||||||
|
l_node.set_author (l_user)
|
||||||
|
a_api.new_node (l_node)
|
||||||
|
end
|
||||||
|
|
||||||
|
create s.make_from_string ("<p>Nodes:</p>")
|
||||||
|
if attached a_api.nodes as lst then
|
||||||
|
across
|
||||||
|
lst as ic
|
||||||
|
loop
|
||||||
|
s.append ("<li>")
|
||||||
|
s.append (a_api.html_encoded (ic.item.title))
|
||||||
|
s.append (" (")
|
||||||
|
s.append (ic.item.id.out)
|
||||||
|
s.append (")")
|
||||||
|
s.append ("</li>%N")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
r.set_main_content (s)
|
||||||
|
r.add_block (create {CMS_CONTENT_BLOCK}.make ("nodes_warning", Void, "/nodes/ is not yet fully implemented<br/>", Void), "highlighted")
|
||||||
r.execute
|
r.execute
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
47
library/src/persistence/cms_storage.e
Normal file
47
library/src/persistence/cms_storage.e
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
note
|
||||||
|
description : "[
|
||||||
|
CMS interface to storage
|
||||||
|
]"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_STORAGE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_USER_STORAGE
|
||||||
|
|
||||||
|
CMS_NODE_STORAGE
|
||||||
|
|
||||||
|
SHARED_LOGGER
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
initialize
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Error Handling
|
||||||
|
|
||||||
|
error_handler: ERROR_HANDLER
|
||||||
|
-- Error handler.
|
||||||
|
|
||||||
|
feature -- Misc
|
||||||
|
|
||||||
|
-- set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: READABLE_STRING_8)
|
||||||
|
-- -- Save data `a_name:a_value' for type `a_type'
|
||||||
|
-- deferred
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- custom_value (a_name: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable TABLE_ITERABLE [READABLE_STRING_8, STRING_8]
|
||||||
|
-- -- Data for name `a_name' and type `a_type'.
|
||||||
|
-- deferred
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- custom_value_names_where (a_where_key, a_where_value: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable LIST [READABLE_STRING_8]
|
||||||
|
-- -- Names where custom value has item `a_where_key' same as `a_where_value' for type `a_type'.
|
||||||
|
-- deferred
|
||||||
|
-- end
|
||||||
|
|
||||||
|
end
|
||||||
18
library/src/persistence/cms_storage_builder.e
Normal file
18
library/src/persistence/cms_storage_builder.e
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Objects that ...
|
||||||
|
]"
|
||||||
|
author: "$Author$"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_STORAGE_BUILDER
|
||||||
|
|
||||||
|
feature -- Factory
|
||||||
|
|
||||||
|
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -7,13 +7,13 @@ class
|
|||||||
CMS_STORAGE_NULL
|
CMS_STORAGE_NULL
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
CMS_STORAGE
|
CMS_STORAGE
|
||||||
redefine
|
redefine
|
||||||
default_create
|
default_create
|
||||||
select
|
select
|
||||||
default_create
|
default_create
|
||||||
end
|
end
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
rename
|
rename
|
||||||
default_create as default_create_rh
|
default_create as default_create_rh
|
||||||
@@ -33,7 +33,7 @@ feature -- Access: user
|
|||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
all_users: LIST [CMS_USER]
|
users: LIST [CMS_USER]
|
||||||
do
|
do
|
||||||
create {ARRAYED_LIST[CMS_USER]} Result.make (0)
|
create {ARRAYED_LIST[CMS_USER]} Result.make (0)
|
||||||
end
|
end
|
||||||
@@ -70,11 +70,16 @@ feature -- User Nodes
|
|||||||
|
|
||||||
feature -- Change: user
|
feature -- Change: user
|
||||||
|
|
||||||
save_user (a_user: CMS_USER)
|
new_user (a_user: CMS_USER)
|
||||||
-- Add a new user `a_user'.
|
-- Add a new user `a_user'.
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
update_user (a_user: CMS_USER)
|
||||||
|
-- Update user `a_user'.
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access: roles and permissions
|
feature -- Access: roles and permissions
|
||||||
|
|
||||||
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
||||||
@@ -93,9 +98,13 @@ feature -- Change: roles and permissions
|
|||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
feature -- Access: node
|
feature -- Access: node
|
||||||
|
|
||||||
|
nodes_count: INTEGER_64
|
||||||
|
-- Count of nodes.
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
nodes: LIST[CMS_NODE]
|
nodes: LIST[CMS_NODE]
|
||||||
-- List of nodes.
|
-- List of nodes.
|
||||||
do
|
do
|
||||||
@@ -126,7 +135,7 @@ feature -- Access: node
|
|||||||
|
|
||||||
feature -- Node
|
feature -- Node
|
||||||
|
|
||||||
save_node (a_node: CMS_NODE)
|
new_node (a_node: CMS_NODE)
|
||||||
-- Add a new node
|
-- Add a new node
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
@@ -136,31 +145,24 @@ feature -- Node
|
|||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node (a_id: like {CMS_NODE}.id; a_node: CMS_NODE)
|
update_node (a_node: CMS_NODE)
|
||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node_title (a_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
update_node_title (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node_summary (a_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
update_node_summary (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node_content (a_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
update_node_content (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- User
|
|
||||||
|
|
||||||
new_user (a_user: CMS_USER)
|
|
||||||
-- Add a new user `a_user'.
|
|
||||||
do
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
22
library/src/persistence/cms_storage_null_builder.e
Normal file
22
library/src/persistence/cms_storage_null_builder.e
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Objects that ...
|
||||||
|
]"
|
||||||
|
author: "$Author$"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_STORAGE_NULL_BUILDER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_STORAGE_BUILDER
|
||||||
|
|
||||||
|
feature -- Factory
|
||||||
|
|
||||||
|
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_NULL
|
||||||
|
do
|
||||||
|
create Result
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
210
library/src/persistence/cms_storage_sql.e
Normal file
210
library/src/persistence/cms_storage_sql.e
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_STORAGE_SQL}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_STORAGE_SQL
|
||||||
|
|
||||||
|
feature -- Error handler
|
||||||
|
|
||||||
|
error_handler: ERROR_HANDLER
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Execution
|
||||||
|
|
||||||
|
sql_begin_transaction
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_commit_transaction
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_post_execution
|
||||||
|
-- Post database execution.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Operation
|
||||||
|
|
||||||
|
check_sql_query_validity (a_sql_statement: READABLE_STRING_8; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
|
local
|
||||||
|
l_sql_params: STRING_TABLE [READABLE_STRING_8]
|
||||||
|
i,j,n,m: INTEGER
|
||||||
|
s: STRING
|
||||||
|
do
|
||||||
|
create l_sql_params.make_caseless (0)
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := a_sql_statement.count
|
||||||
|
until
|
||||||
|
i > n
|
||||||
|
loop
|
||||||
|
i := a_sql_statement.index_of (':', i)
|
||||||
|
if i = 0 then
|
||||||
|
i := n -- exit
|
||||||
|
else
|
||||||
|
from
|
||||||
|
j := i + 1
|
||||||
|
until
|
||||||
|
j > n or not (a_sql_statement[j].is_alpha_numeric or a_sql_statement[j] = '_')
|
||||||
|
loop
|
||||||
|
j := j + 1
|
||||||
|
end
|
||||||
|
s := a_sql_statement.substring (i + 1, j - 1)
|
||||||
|
l_sql_params.force (s, s)
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
if a_params = Void then
|
||||||
|
if not l_sql_params.is_empty then
|
||||||
|
check False end
|
||||||
|
error_handler.add_custom_error (-1, "invalid query", "missing value for sql parameters")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
across
|
||||||
|
a_params as ic
|
||||||
|
loop
|
||||||
|
if l_sql_params.has (ic.key) then
|
||||||
|
l_sql_params.remove (ic.key)
|
||||||
|
else
|
||||||
|
error_handler.add_custom_error (-1, "useless value", "value for unexpected parameter [" + ic.key + "]")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
across
|
||||||
|
l_sql_params as ic
|
||||||
|
loop
|
||||||
|
error_handler.add_custom_error (-1, "invalid query", "missing value for sql parameter [" + ic.item + "]")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
sql_rows_count: INTEGER
|
||||||
|
-- Number of rows for last sql execution.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_start
|
||||||
|
-- Set the cursor on first element.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_after: BOOLEAN
|
||||||
|
-- Are there no more items to iterate over?
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_forth
|
||||||
|
-- Fetch next row from last sql execution, if any.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_item (a_index: INTEGER): detachable ANY
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_read_integer_64 (a_index: INTEGER): INTEGER_64
|
||||||
|
-- Retrieved value at `a_index' position in `item'.
|
||||||
|
local
|
||||||
|
l_item: like sql_item
|
||||||
|
do
|
||||||
|
l_item := sql_item (a_index)
|
||||||
|
if attached {INTEGER_64} l_item as i then
|
||||||
|
Result := i
|
||||||
|
elseif attached {INTEGER_64_REF} l_item as l_value then
|
||||||
|
Result := l_value.item
|
||||||
|
else
|
||||||
|
Result := sql_read_integer_32 (a_index).to_integer_64
|
||||||
|
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
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_read_string (a_index: INTEGER): detachable STRING
|
||||||
|
-- Retrieved value at `a_index' position in `item'.
|
||||||
|
local
|
||||||
|
l_item: like sql_item
|
||||||
|
do
|
||||||
|
l_item := sql_item (a_index)
|
||||||
|
if attached {READABLE_STRING_8} l_item as l_string then
|
||||||
|
Result := l_string
|
||||||
|
elseif attached {BOOLEAN} l_item as l_boolean then
|
||||||
|
Result := l_boolean.out
|
||||||
|
elseif attached {BOOLEAN_REF} l_item as l_boolean_ref then
|
||||||
|
Result := l_boolean_ref.item.out
|
||||||
|
else
|
||||||
|
-- check is_string: False end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_read_string_32 (a_index: INTEGER): detachable STRING_32
|
||||||
|
-- Retrieved value at `a_index' position in `item'.
|
||||||
|
local
|
||||||
|
l_item: like sql_item
|
||||||
|
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
|
||||||
|
else
|
||||||
|
if attached sql_read_string (a_index) as s8 then
|
||||||
|
Result := s8.to_string_32 -- FIXME
|
||||||
|
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
|
||||||
|
else
|
||||||
|
-- check is_date_time: False end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_read_boolean (a_index: INTEGER): detachable BOOLEAN
|
||||||
|
-- Retrieved value at `a_index' position in `item'.
|
||||||
|
local
|
||||||
|
l_item: like sql_item
|
||||||
|
do
|
||||||
|
l_item := sql_item (a_index)
|
||||||
|
if attached {BOOLEAN} l_item as l_boolean then
|
||||||
|
Result := l_boolean
|
||||||
|
elseif attached {BOOLEAN_REF} l_item as l_boolean_ref then
|
||||||
|
Result := l_boolean_ref.item
|
||||||
|
else
|
||||||
|
check is_boolean: False end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
103
library/src/persistence/node/cms_node_storage.e
Normal file
103
library/src/persistence/node/cms_node_storage.e
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_NODE_STORAGE}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_NODE_STORAGE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
SHARED_LOGGER
|
||||||
|
|
||||||
|
feature -- Error Handling
|
||||||
|
|
||||||
|
error_handler: ERROR_HANDLER
|
||||||
|
-- Error handler.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
nodes_count: INTEGER_64
|
||||||
|
-- Count of nodes.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
nodes: LIST [CMS_NODE]
|
||||||
|
-- List of nodes.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
||||||
|
-- List of recent `a_count' nodes with an offset of `lower'.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
node (a_id: INTEGER_64): detachable CMS_NODE
|
||||||
|
-- Retrieve node by id `a_id', if any.
|
||||||
|
require
|
||||||
|
a_id > 0
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
|
||||||
|
-- Node's author. if any.
|
||||||
|
require
|
||||||
|
valid_node: a_id >0
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Change: Node
|
||||||
|
|
||||||
|
new_node (a_node: CMS_NODE)
|
||||||
|
-- Save node `a_node'.
|
||||||
|
require
|
||||||
|
no_id: not a_node.has_id
|
||||||
|
valid_user: attached a_node.author as l_author and then l_author.id > 0
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
delete_node (a_id: INTEGER_64)
|
||||||
|
-- Remove node by id `a_id'.
|
||||||
|
require
|
||||||
|
valid_node_id: a_id > 0
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
update_node (a_node: CMS_NODE)
|
||||||
|
-- Update node content `a_node'.
|
||||||
|
-- The user `a_id' is an existing or new collaborator.
|
||||||
|
require
|
||||||
|
has_id: a_node.has_id
|
||||||
|
has_author: attached a_node.author as l_author and then l_author.has_id
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
update_node_title (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||||
|
-- Update node title to `a_title', node identified by id `a_node_id'.
|
||||||
|
-- The user `a_id' is an existing or new collaborator.
|
||||||
|
require
|
||||||
|
valid_node_id: a_node_id > 0
|
||||||
|
valid_user_id: a_id > 0
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
update_node_summary (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||||
|
-- Update node summary to `a_summary', node identified by id `a_node_id'.
|
||||||
|
-- The user `a_id' is an existing or new collaborator.
|
||||||
|
require
|
||||||
|
valid_id: a_node_id > 0
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
update_node_content (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||||
|
-- Update node content to `a_content', node identified by id `a_node_id'.
|
||||||
|
-- The user `a_id' is an existing or new collaborator.
|
||||||
|
require
|
||||||
|
valid_id: a_node_id > 0
|
||||||
|
valid_user_id: a_id > 0
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
342
library/src/persistence/node/cms_node_storage_sql.e
Normal file
342
library/src/persistence/node/cms_node_storage_sql.e
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_NODE_STORAGE_SQL}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_NODE_STORAGE_SQL
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_NODE_STORAGE
|
||||||
|
|
||||||
|
CMS_STORAGE_SQL
|
||||||
|
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
|
SHARED_LOGGER
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
nodes_count: INTEGER_64
|
||||||
|
-- Number of items nodes.
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".nodes_count")
|
||||||
|
sql_query (select_nodes_count, Void)
|
||||||
|
if sql_rows_count = 1 then
|
||||||
|
Result := sql_read_integer_64 (1)
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
nodes: LIST [CMS_NODE]
|
||||||
|
-- List of nodes.
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||||
|
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".nodes")
|
||||||
|
|
||||||
|
from
|
||||||
|
sql_query (select_nodes, Void)
|
||||||
|
sql_post_execution
|
||||||
|
sql_start
|
||||||
|
until
|
||||||
|
sql_after
|
||||||
|
loop
|
||||||
|
if attached fetch_node as l_node then
|
||||||
|
Result.force (l_node)
|
||||||
|
end
|
||||||
|
sql_forth
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
||||||
|
-- List of recent `a_count' nodes with an offset of `lower'.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||||
|
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".nodes")
|
||||||
|
|
||||||
|
from
|
||||||
|
create l_parameters.make (2)
|
||||||
|
l_parameters.put (a_count, "rows")
|
||||||
|
l_parameters.put (a_lower, "offset")
|
||||||
|
sql_query (select_recent_nodes, l_parameters)
|
||||||
|
sql_post_execution
|
||||||
|
sql_start
|
||||||
|
until
|
||||||
|
sql_after
|
||||||
|
loop
|
||||||
|
if attached fetch_node as l_node then
|
||||||
|
Result.force (l_node)
|
||||||
|
end
|
||||||
|
sql_forth
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
node (a_id: INTEGER_64): detachable CMS_NODE
|
||||||
|
-- Retrieve node by id `a_id', if any.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".node")
|
||||||
|
create l_parameters.make (1)
|
||||||
|
l_parameters.put (a_id,"id")
|
||||||
|
sql_query (select_node_by_id, l_parameters)
|
||||||
|
if sql_rows_count = 1 then
|
||||||
|
Result := fetch_node
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
|
||||||
|
-- Node's author for the given node id.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".node_author")
|
||||||
|
create l_parameters.make (1)
|
||||||
|
l_parameters.put (a_id, "node_id")
|
||||||
|
sql_query (select_node_author, l_parameters)
|
||||||
|
if sql_rows_count >= 1 then
|
||||||
|
Result := fetch_author
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
last_inserted_node_id: INTEGER_64
|
||||||
|
-- Last insert node id.
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".last_inserted_node_id")
|
||||||
|
sql_query (Sql_last_insert_node_id, Void)
|
||||||
|
if sql_rows_count = 1 then
|
||||||
|
Result := sql_read_integer_64 (1)
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Change: Node
|
||||||
|
|
||||||
|
new_node (a_node: CMS_NODE)
|
||||||
|
-- Save node `a_node'.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
-- New node
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".new_node")
|
||||||
|
create l_parameters.make (7)
|
||||||
|
l_parameters.put (a_node.title, "title")
|
||||||
|
l_parameters.put (a_node.summary, "summary")
|
||||||
|
l_parameters.put (a_node.content, "content")
|
||||||
|
l_parameters.put (a_node.publication_date, "publish")
|
||||||
|
l_parameters.put (a_node.creation_date, "created")
|
||||||
|
l_parameters.put (a_node.modification_date, "changed")
|
||||||
|
if
|
||||||
|
attached a_node.author as l_author and then
|
||||||
|
l_author.id > 0
|
||||||
|
then
|
||||||
|
l_parameters.put (l_author.id, "author")
|
||||||
|
else
|
||||||
|
l_parameters.put (0, "author")
|
||||||
|
end
|
||||||
|
sql_change (sql_insert_node, l_parameters)
|
||||||
|
sql_post_execution
|
||||||
|
if not error_handler.has_error then
|
||||||
|
a_node.set_id (last_inserted_node_id)
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
delete_node (a_id: INTEGER_64)
|
||||||
|
-- Remove node by id `a_id'.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
do
|
||||||
|
log.write_information (generator + ".delete_node")
|
||||||
|
|
||||||
|
error_handler.reset
|
||||||
|
create l_parameters.make (1)
|
||||||
|
l_parameters.put (a_id, "id")
|
||||||
|
sql_change (sql_delete_node, l_parameters)
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
update_node (a_node: CMS_NODE)
|
||||||
|
-- Update node content `a_node'.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
now: DATE_TIME
|
||||||
|
do
|
||||||
|
create now.make_now_utc
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".update_node")
|
||||||
|
create l_parameters.make (7)
|
||||||
|
l_parameters.put (a_node.title, "title")
|
||||||
|
l_parameters.put (a_node.summary, "summary")
|
||||||
|
l_parameters.put (a_node.content, "content")
|
||||||
|
l_parameters.put (a_node.publication_date, "publish")
|
||||||
|
l_parameters.put (now, "changed")
|
||||||
|
l_parameters.put (a_node.id, "id")
|
||||||
|
if attached a_node.author as l_author then
|
||||||
|
l_parameters.put (l_author.id, "author")
|
||||||
|
else
|
||||||
|
l_parameters.put (0, "author")
|
||||||
|
end
|
||||||
|
sql_change (sql_update_node, l_parameters)
|
||||||
|
sql_post_execution
|
||||||
|
if not error_handler.has_error then
|
||||||
|
a_node.set_modification_date (now)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||||
|
-- Update node title to `a_title', node identified by id `a_node_id'.
|
||||||
|
-- The user `a_user_id' is an existing or new collaborator.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
-- FIXME: unused a_user_id !
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".update_node_title")
|
||||||
|
create l_parameters.make (3)
|
||||||
|
l_parameters.put (a_title, "title")
|
||||||
|
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||||
|
l_parameters.put (a_node_id, "nid")
|
||||||
|
sql_change (sql_update_node_title, l_parameters)
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||||
|
-- Update node summary to `a_summary', node identified by id `a_node_id'.
|
||||||
|
-- The user `a_user_id' is an existing or new collaborator.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
-- FIXME: unused a_user_id !
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".update_node_summary")
|
||||||
|
create l_parameters.make (3)
|
||||||
|
l_parameters.put (a_summary, "summary")
|
||||||
|
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||||
|
l_parameters.put (a_node_id, "nid")
|
||||||
|
sql_change (sql_update_node_summary, l_parameters)
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||||
|
-- Update node content to `a_content', node identified by id `a_node_id'.
|
||||||
|
-- The user `a_user_id' is an existing or new collaborator.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
-- FIXME: unused a_user_id !
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".update_node_content")
|
||||||
|
create l_parameters.make (3)
|
||||||
|
l_parameters.put (a_content, "content")
|
||||||
|
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||||
|
l_parameters.put (a_node_id, "nid")
|
||||||
|
sql_change (sql_update_node_content, l_parameters)
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Queries
|
||||||
|
|
||||||
|
Select_nodes_count: STRING = "select count(*) from Nodes;"
|
||||||
|
|
||||||
|
Select_nodes: STRING = "select * from Nodes;"
|
||||||
|
-- SQL Query to retrieve all nodes.
|
||||||
|
|
||||||
|
Select_node_by_id: STRING = "select * from Nodes where nid =:nid order by nid desc, publish desc;"
|
||||||
|
|
||||||
|
Select_recent_nodes: STRING = "select * from Nodes order by nid desc, publish desc LIMIT :rows OFFSET :offset ;"
|
||||||
|
|
||||||
|
SQL_Insert_node: STRING = "insert into nodes (title, summary, content, publish, created, changed, author) values (:title, :summary, :content, :publish, :created, :changed, :author);"
|
||||||
|
-- SQL Insert to add a new node.
|
||||||
|
|
||||||
|
SQL_Update_node : STRING = "update nodes SET title=:title, summary=:summary, content=:content, publish=:publish, changed=:changed, version = version + 1, author=:author where nid=:nid;"
|
||||||
|
-- SQL node.
|
||||||
|
|
||||||
|
SQL_Delete_node: STRING = "delete from nodes where nid=:nid;"
|
||||||
|
|
||||||
|
Sql_update_node_author: STRING = "update nodes SET author=:author where nid=:nid;"
|
||||||
|
|
||||||
|
SQL_Update_node_title: STRING ="update nodes SET title=:title, changed=:changed, version = version + 1 where nid=:nid;"
|
||||||
|
-- SQL update node title.
|
||||||
|
|
||||||
|
SQL_Update_node_summary: STRING ="update nodes SET summary=:summary, changed=:changed, version = version + 1 where nid=:nid;"
|
||||||
|
-- SQL update node summary.
|
||||||
|
|
||||||
|
SQL_Update_node_content: STRING ="update nodes SET content=:content, changed=:changed, version = version + 1 where nid=:nid;"
|
||||||
|
-- SQL node content.
|
||||||
|
|
||||||
|
Sql_last_insert_node_id: STRING = "SELECT MAX(nid) from nodes;"
|
||||||
|
|
||||||
|
feature {NONE} -- Sql Queries: USER_ROLES collaborators, author
|
||||||
|
|
||||||
|
Select_user_author: STRING = "SELECT * FROM Nodes INNER JOIN users ON nodes.author=users.uid and users.uid = :uid;"
|
||||||
|
|
||||||
|
Select_node_author: STRING = "SELECT * FROM Users INNER JOIN nodes ON nodes.author=users.uid and nodes.nid =:nid;"
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
fetch_node: CMS_NODE
|
||||||
|
do
|
||||||
|
create Result.make ("", "", "")
|
||||||
|
if attached sql_read_integer_64 (1) as l_id then
|
||||||
|
Result.set_id (l_id)
|
||||||
|
end
|
||||||
|
if attached sql_read_string_32 (4) as l_title then
|
||||||
|
Result.set_title (l_title)
|
||||||
|
end
|
||||||
|
if attached sql_read_string_32 (5) as l_summary then
|
||||||
|
Result.set_summary (l_summary)
|
||||||
|
end
|
||||||
|
if attached sql_read_string (6) as l_content then
|
||||||
|
Result.set_content (l_content)
|
||||||
|
end
|
||||||
|
if attached sql_read_date_time (8) as l_publication_date then
|
||||||
|
Result.set_publication_date (l_publication_date)
|
||||||
|
end
|
||||||
|
if attached sql_read_date_time (9) as l_creation_date then
|
||||||
|
Result.set_creation_date (l_creation_date)
|
||||||
|
end
|
||||||
|
if attached sql_read_date_time (10) as l_modif_date then
|
||||||
|
Result.set_modification_date (l_modif_date)
|
||||||
|
end
|
||||||
|
if attached sql_read_integer_64 (7) as l_author_id then
|
||||||
|
-- access to API ...
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
fetch_author: detachable CMS_USER
|
||||||
|
do
|
||||||
|
if attached sql_read_string_32 (2) as l_name and then not l_name.is_whitespace then
|
||||||
|
create Result.make (l_name)
|
||||||
|
if attached sql_read_integer_32 (1) as l_id then
|
||||||
|
Result.set_id (l_id)
|
||||||
|
end
|
||||||
|
if attached sql_read_string (3) as l_password then
|
||||||
|
-- FIXME: should we return the password here ???
|
||||||
|
Result.set_hashed_password (l_password)
|
||||||
|
end
|
||||||
|
if attached sql_read_string (5) as l_email then
|
||||||
|
Result.set_email (l_email)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
check expected_valid_user: False end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
129
library/src/persistence/user/cms_user_storage.e
Normal file
129
library/src/persistence/user/cms_user_storage.e
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_USER_STORAGE}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_USER_STORAGE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
SHARED_LOGGER
|
||||||
|
|
||||||
|
feature -- Error Handling
|
||||||
|
|
||||||
|
error_handler: ERROR_HANDLER
|
||||||
|
-- Error handler.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
has_user: BOOLEAN
|
||||||
|
-- Has any user?
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
users: LIST [CMS_USER]
|
||||||
|
-- List of users.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
|
||||||
|
-- User with id `a_id', if any.
|
||||||
|
require
|
||||||
|
a_id > 0
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
same_id: Result /= Void implies Result.id = a_id
|
||||||
|
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
|
||||||
|
-- User with name `a_name', if any.
|
||||||
|
require
|
||||||
|
a_name /= Void and then not a_name.is_empty
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
same_name: Result /= Void implies a_name ~ Result.name
|
||||||
|
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
|
||||||
|
-- User with name `a_email', if any.
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
same_email: Result /= Void implies a_email ~ Result.email
|
||||||
|
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
is_valid_credential (a_u, a_p: READABLE_STRING_32): BOOLEAN
|
||||||
|
-- Does account with username `a_username' and password `a_password' exist?
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Change: user
|
||||||
|
|
||||||
|
new_user (a_user: CMS_USER)
|
||||||
|
-- New user `a_user'.
|
||||||
|
require
|
||||||
|
no_id: not a_user.has_id
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
update_user (a_user: CMS_USER)
|
||||||
|
-- Save user `a_user'.
|
||||||
|
require
|
||||||
|
has_id: a_user.has_id
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access: roles and permissions
|
||||||
|
|
||||||
|
user_has_permission (u: detachable CMS_USER; s: detachable READABLE_STRING_8): BOOLEAN
|
||||||
|
-- Anonymous or user `u' has permission for `s' ?
|
||||||
|
--| `s' could be "create page",
|
||||||
|
do
|
||||||
|
-- if s = Void then
|
||||||
|
-- Result := True
|
||||||
|
-- elseif u = Void then
|
||||||
|
---- Result := user_role_has_permission (anonymous_user_role, s)
|
||||||
|
-- else
|
||||||
|
-- Result := user_role_has_permission (authenticated_user_role, s)
|
||||||
|
-- if not Result and attached u.roles as l_roles then
|
||||||
|
-- across
|
||||||
|
-- l_roles as r
|
||||||
|
-- until
|
||||||
|
-- Result
|
||||||
|
-- loop
|
||||||
|
-- if attached user_role_by_id (r.item) as ur then
|
||||||
|
-- Result := user_role_has_permission (ur, s)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
end
|
||||||
|
|
||||||
|
user_role_has_permission (a_role: CMS_USER_ROLE; s: READABLE_STRING_8): BOOLEAN
|
||||||
|
do
|
||||||
|
Result := a_role.has_permission (s)
|
||||||
|
end
|
||||||
|
|
||||||
|
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
||||||
|
-- User role by id `a_id', if any.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
user_roles: LIST [CMS_USER_ROLE]
|
||||||
|
-- Possible list of user roles.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Change: roles and permissions
|
||||||
|
|
||||||
|
save_user_role (a_user_role: CMS_USER_ROLE)
|
||||||
|
-- Save user role `a_user_role'
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
332
library/src/persistence/user/cms_user_storage_sql.e
Normal file
332
library/src/persistence/user/cms_user_storage_sql.e
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_USER_STORAGE_SQL}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_USER_STORAGE_SQL
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_USER_STORAGE
|
||||||
|
|
||||||
|
CMS_STORAGE_SQL
|
||||||
|
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
|
SHARED_LOGGER
|
||||||
|
|
||||||
|
feature -- Access: user
|
||||||
|
|
||||||
|
has_user: BOOLEAN
|
||||||
|
-- Has any user?
|
||||||
|
do
|
||||||
|
Result := user_count > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
user_count: INTEGER
|
||||||
|
-- Number of items users.
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".user_count")
|
||||||
|
|
||||||
|
sql_query (select_users_count, Void)
|
||||||
|
if sql_rows_count = 1 then
|
||||||
|
Result := sql_read_integer_32 (1)
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
users: LIST [CMS_USER]
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_USER]} Result.make (0)
|
||||||
|
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".all_users")
|
||||||
|
|
||||||
|
from
|
||||||
|
sql_query (select_users, Void)
|
||||||
|
sql_post_execution
|
||||||
|
sql_start
|
||||||
|
until
|
||||||
|
sql_after
|
||||||
|
loop
|
||||||
|
if attached fetch_user as l_user then
|
||||||
|
Result.force (l_user)
|
||||||
|
end
|
||||||
|
sql_forth
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
|
||||||
|
-- User for the given id `a_id', if any.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".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
|
||||||
|
Result := fetch_user
|
||||||
|
else
|
||||||
|
check no_more_than_one: sql_rows_count = 0 end
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
|
||||||
|
-- User for the given name `a_name', if any.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".user_by_name")
|
||||||
|
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
|
||||||
|
Result := fetch_user
|
||||||
|
else
|
||||||
|
check no_more_than_one: sql_rows_count = 0 end
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
|
||||||
|
-- User for the given email `a_email', if any.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".user_by_email")
|
||||||
|
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
|
||||||
|
Result := fetch_user
|
||||||
|
else
|
||||||
|
check no_more_than_one: sql_rows_count = 0 end
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN
|
||||||
|
local
|
||||||
|
l_security: SECURITY_PROVIDER
|
||||||
|
do
|
||||||
|
if attached user_salt (l_auth_login) as l_hash then
|
||||||
|
if attached user_by_name (l_auth_login) as l_user then
|
||||||
|
create l_security
|
||||||
|
if
|
||||||
|
attached l_user.hashed_password as l_hashed_password and then
|
||||||
|
l_security.password_hash (l_auth_password, l_hash).is_case_insensitive_equal (l_hashed_password)
|
||||||
|
then
|
||||||
|
Result := True
|
||||||
|
else
|
||||||
|
log.write_information (generator + ".is_valid_credential User: wrong username or password" )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
log.write_information (generator + ".is_valid_credential User:" + l_auth_login + "does not exist" )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Change: user
|
||||||
|
|
||||||
|
new_user (a_user: CMS_USER)
|
||||||
|
-- Add a new user `a_user'.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
l_password_salt, l_password_hash: STRING
|
||||||
|
l_security: SECURITY_PROVIDER
|
||||||
|
do
|
||||||
|
if
|
||||||
|
attached a_user.password as l_password and then
|
||||||
|
attached a_user.email as l_email
|
||||||
|
then
|
||||||
|
sql_begin_transaction
|
||||||
|
error_handler.reset
|
||||||
|
create l_security
|
||||||
|
l_password_salt := l_security.salt
|
||||||
|
l_password_hash := l_security.password_hash (l_password, l_password_salt)
|
||||||
|
|
||||||
|
log.write_information (generator + ".new_user")
|
||||||
|
create l_parameters.make (4)
|
||||||
|
l_parameters.put (a_user.name, "name")
|
||||||
|
l_parameters.put (l_password_hash, "password")
|
||||||
|
l_parameters.put (l_password_salt, "salt")
|
||||||
|
l_parameters.put (l_email, "email")
|
||||||
|
l_parameters.put (create {DATE_TIME}.make_now_utc, "created")
|
||||||
|
|
||||||
|
sql_change (sql_insert_user, l_parameters)
|
||||||
|
sql_post_execution
|
||||||
|
if not error_handler.has_error then
|
||||||
|
a_user.set_id (last_inserted_user_id)
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
sql_commit_transaction
|
||||||
|
else
|
||||||
|
-- set error
|
||||||
|
error_handler.add_custom_error (-1, "bad request" , "Missing password or email")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
update_user (a_user: CMS_USER)
|
||||||
|
-- Save user `a_user'.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
l_password_salt, l_password_hash: detachable READABLE_STRING_8
|
||||||
|
l_security: SECURITY_PROVIDER
|
||||||
|
do
|
||||||
|
if attached a_user.password as l_password then
|
||||||
|
-- New password!
|
||||||
|
create l_security
|
||||||
|
l_password_salt := l_security.salt
|
||||||
|
l_password_hash := l_security.password_hash (l_password, l_password_salt)
|
||||||
|
else
|
||||||
|
-- Existing hashed password
|
||||||
|
l_password_hash := a_user.hashed_password
|
||||||
|
l_password_salt := user_salt (a_user.name)
|
||||||
|
end
|
||||||
|
if
|
||||||
|
l_password_hash /= Void and l_password_salt /= Void and
|
||||||
|
attached a_user.email as l_email
|
||||||
|
then
|
||||||
|
error_handler.reset
|
||||||
|
|
||||||
|
log.write_information (generator + ".update_user")
|
||||||
|
create l_parameters.make (6)
|
||||||
|
l_parameters.put (a_user.id, "uid")
|
||||||
|
l_parameters.put (a_user.name, "name")
|
||||||
|
l_parameters.put (l_password_hash, "password")
|
||||||
|
l_parameters.put (l_password_salt, "salt")
|
||||||
|
l_parameters.put (l_email, "email")
|
||||||
|
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||||
|
|
||||||
|
sql_change (sql_update_user, l_parameters)
|
||||||
|
sql_post_execution
|
||||||
|
else
|
||||||
|
-- set error
|
||||||
|
error_handler.add_custom_error (-1, "bad request" , "Missing password or email")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access: roles and permissions
|
||||||
|
|
||||||
|
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
||||||
|
do
|
||||||
|
to_implement (generator + ".user_role_by_id")
|
||||||
|
end
|
||||||
|
|
||||||
|
user_roles: LIST [CMS_USER_ROLE]
|
||||||
|
do
|
||||||
|
to_implement (generator + ".user_roles")
|
||||||
|
create {ARRAYED_LIST[CMS_USER_ROLE]} Result.make (0)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Change: roles and permissions
|
||||||
|
|
||||||
|
save_user_role (a_user_role: CMS_USER_ROLE)
|
||||||
|
do
|
||||||
|
to_implement (generator + ".save_user_role")
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
user_salt (a_username: READABLE_STRING_32): detachable READABLE_STRING_8
|
||||||
|
-- User salt for the given user `a_username', if any.
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".user_salt")
|
||||||
|
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 attached sql_read_string (1) as l_salt then
|
||||||
|
Result := l_salt
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
fetch_user: detachable CMS_USER
|
||||||
|
local
|
||||||
|
l_id: INTEGER_64
|
||||||
|
l_name: detachable READABLE_STRING_32
|
||||||
|
do
|
||||||
|
if attached sql_read_integer_32 (1) as i then
|
||||||
|
l_id := i
|
||||||
|
end
|
||||||
|
if attached sql_read_string_32 (2) as s and then not s.is_whitespace then
|
||||||
|
l_name := s
|
||||||
|
end
|
||||||
|
|
||||||
|
if l_name /= Void then
|
||||||
|
create Result.make (l_name)
|
||||||
|
if l_id > 0 then
|
||||||
|
Result.set_id (l_id)
|
||||||
|
end
|
||||||
|
elseif l_id > 0 then
|
||||||
|
create Result.make_with_id (l_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
if Result /= Void then
|
||||||
|
if attached sql_read_string (3) as l_password then
|
||||||
|
-- FIXME: should we return the password here ???
|
||||||
|
Result.set_hashed_password (l_password)
|
||||||
|
end
|
||||||
|
if attached sql_read_string (5) as l_email then
|
||||||
|
Result.set_email (l_email)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
check expected_valid_user: False end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
last_inserted_user_id: INTEGER_64
|
||||||
|
-- Last insert user id.
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
log.write_information (generator + ".last_inserted_user_id")
|
||||||
|
sql_query (Sql_last_insert_user_id, Void)
|
||||||
|
if sql_rows_count = 1 then
|
||||||
|
Result := sql_read_integer_64 (1)
|
||||||
|
end
|
||||||
|
sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Sql Queries: USER
|
||||||
|
|
||||||
|
Select_users_count: STRING = "select count(*) from Users;"
|
||||||
|
-- Number of users.
|
||||||
|
|
||||||
|
Sql_last_insert_user_id: STRING = "SELECT MAX(uid) from Users;"
|
||||||
|
|
||||||
|
Select_users: STRING = "select * from Users;"
|
||||||
|
-- List of users.
|
||||||
|
|
||||||
|
Select_user_by_id: STRING = "select * from Users where uid =:uid;"
|
||||||
|
-- Retrieve user by id if exists.
|
||||||
|
|
||||||
|
Select_user_by_name: STRING = "select * from Users where name =:name;"
|
||||||
|
-- Retrieve user by name if exists.
|
||||||
|
|
||||||
|
Select_user_by_email: STRING = "select * from Users where email =:email;"
|
||||||
|
-- Retrieve user by email if exists.
|
||||||
|
|
||||||
|
Select_salt_by_username: STRING = "select salt from Users where name =:name;"
|
||||||
|
-- Retrieve salt by username if exists.
|
||||||
|
|
||||||
|
Sql_Insert_user: STRING = "insert into users (name, password, salt, email, created) values (:name, :password, :salt, :email, :created);"
|
||||||
|
-- SQL Insert to add a new node.
|
||||||
|
|
||||||
|
sql_update_user: STRING = "update users SET name=:name, password=:password, salt=:salt, email=:email WHERE uid=:uid;"
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -34,10 +34,16 @@ feature -- Access
|
|||||||
Result.keep_head (Result.count - 2)
|
Result.keep_head (Result.count - 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
password_hash (a_password, a_salt: STRING): STRING
|
password_hash (a_password: READABLE_STRING_GENERAL; a_salt: STRING): STRING
|
||||||
-- Password hash based on password `a_password' and salt value `a_salt'.
|
-- Password hash based on password `a_password' and salt value `a_salt'.
|
||||||
|
local
|
||||||
|
utf: UTF_CONVERTER
|
||||||
|
s: STRING
|
||||||
do
|
do
|
||||||
Result := sha1_string (a_password + a_salt )
|
create s.make (a_password.count + a_salt.count)
|
||||||
|
utf.utf_32_string_into_utf_8_string_8 (a_password, s)
|
||||||
|
s.append (a_salt)
|
||||||
|
Result := sha1_string (s)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
@@ -1,17 +1,26 @@
|
|||||||
note
|
note
|
||||||
description: "API for a CMS"
|
description: "API for a CMS"
|
||||||
date: "$Date$"
|
date: "$Date: 2015-01-14 16:13:47 +0100 (mer., 14 janv. 2015) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96454 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
CMS_API
|
CMS_API
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
ANY
|
||||||
SHARED_ERROR
|
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
|
|
||||||
|
SHARED_HTML_ENCODER
|
||||||
|
export
|
||||||
|
{NONE} all
|
||||||
|
end
|
||||||
|
|
||||||
|
SHARED_WSF_PERCENT_ENCODER
|
||||||
|
export
|
||||||
|
{NONE} all
|
||||||
|
end
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
@@ -23,7 +32,6 @@ feature -- Initialize
|
|||||||
setup := a_setup
|
setup := a_setup
|
||||||
create error_handler.make
|
create error_handler.make
|
||||||
initialize
|
initialize
|
||||||
set_successful
|
|
||||||
ensure
|
ensure
|
||||||
setup_set: setup = a_setup
|
setup_set: setup = a_setup
|
||||||
error_handler_set: not error_handler.has_error
|
error_handler_set: not error_handler.has_error
|
||||||
@@ -34,49 +42,38 @@ feature -- Initialize
|
|||||||
|
|
||||||
initialize
|
initialize
|
||||||
-- Initialize the persitent layer.
|
-- Initialize the persitent layer.
|
||||||
local
|
|
||||||
l_database: DATABASE_CONNECTION
|
|
||||||
retried: BOOLEAN
|
|
||||||
l_message: STRING
|
|
||||||
do
|
do
|
||||||
if not retried then
|
to_implement ("Refactor database setup")
|
||||||
to_implement ("Refactor database setup")
|
if attached setup.storage (error_handler) as l_storage then
|
||||||
if attached (create {JSON_CONFIGURATION}).new_database_configuration (setup.layout.application_config_path) as l_database_config then
|
storage := l_storage
|
||||||
create {DATABASE_CONNECTION_MYSQL} l_database.login_with_connection_string (l_database_config.connection_string)
|
|
||||||
create {CMS_STORAGE_MYSQL} storage.make (l_database)
|
|
||||||
else
|
|
||||||
create {DATABASE_CONNECTION_NULL} l_database.make_common
|
|
||||||
create {CMS_STORAGE_NULL} storage
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
to_implement ("Workaround code, persistence layer does not implement yet this kind of error handling.")
|
|
||||||
-- error hanling.
|
|
||||||
create {DATABASE_CONNECTION_NULL} l_database.make_common
|
|
||||||
create {CMS_STORAGE_NULL} storage
|
create {CMS_STORAGE_NULL} storage
|
||||||
create l_message.make (1024)
|
|
||||||
if attached ((create {EXCEPTION_MANAGER}).last_exception) as l_exception then
|
|
||||||
if attached l_exception.description as l_description then
|
|
||||||
l_message.append (l_description.as_string_32)
|
|
||||||
l_message.append ("%N%N")
|
|
||||||
elseif attached l_exception.trace as l_trace then
|
|
||||||
l_message.append (l_trace)
|
|
||||||
l_message.append ("%N%N")
|
|
||||||
else
|
|
||||||
l_message.append (l_exception.out)
|
|
||||||
l_message.append ("%N%N")
|
|
||||||
end
|
|
||||||
else
|
|
||||||
l_message.append ("The application crash without available information")
|
|
||||||
l_message.append ("%N%N")
|
|
||||||
end
|
|
||||||
error_handler.add_custom_error (0, " Database Connection ", l_message)
|
|
||||||
end
|
end
|
||||||
rescue
|
|
||||||
retried := True
|
|
||||||
retry
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access: Error
|
||||||
|
|
||||||
|
has_error: BOOLEAN
|
||||||
|
-- Has error?
|
||||||
|
do
|
||||||
|
Result := error_handler.has_error
|
||||||
|
end
|
||||||
|
|
||||||
|
as_string_representation: STRING_32
|
||||||
|
-- String representation of all error(s).
|
||||||
|
do
|
||||||
|
Result := error_handler.as_string_representation
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Element Change: Error
|
||||||
|
|
||||||
|
reset
|
||||||
|
-- Reset error handler.
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE}-- Error handler implemenations
|
||||||
|
|
||||||
error_handler: ERROR_HANDLER
|
error_handler: ERROR_HANDLER
|
||||||
-- Error handler.
|
-- Error handler.
|
||||||
@@ -91,16 +88,18 @@ feature -- Status Report
|
|||||||
|
|
||||||
feature -- Access: Node
|
feature -- Access: Node
|
||||||
|
|
||||||
nodes: LIST[CMS_NODE]
|
nodes_count: INTEGER_64
|
||||||
-- List of nodes.
|
|
||||||
do
|
do
|
||||||
debug ("refactor_fixme")
|
Result := storage.nodes_count
|
||||||
fixme ("Implementation")
|
|
||||||
end
|
|
||||||
Result := storage.recent_nodes (0, 10)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
recent_nodes (a_offset, a_rows: INTEGER): LIST[CMS_NODE]
|
nodes: LIST [CMS_NODE]
|
||||||
|
-- List of nodes.
|
||||||
|
do
|
||||||
|
Result := storage.nodes
|
||||||
|
end
|
||||||
|
|
||||||
|
recent_nodes (a_offset, a_rows: INTEGER): LIST [CMS_NODE]
|
||||||
-- List of the `a_rows' most recent nodes starting from `a_offset'.
|
-- List of the `a_rows' most recent nodes starting from `a_offset'.
|
||||||
do
|
do
|
||||||
Result := storage.recent_nodes (a_offset, a_rows)
|
Result := storage.recent_nodes (a_offset, a_rows)
|
||||||
@@ -119,8 +118,10 @@ feature -- Change: Node
|
|||||||
|
|
||||||
new_node (a_node: CMS_NODE)
|
new_node (a_node: CMS_NODE)
|
||||||
-- Add a new node `a_node'
|
-- Add a new node `a_node'
|
||||||
|
require
|
||||||
|
no_id: not a_node.has_id
|
||||||
do
|
do
|
||||||
storage.save_node (a_node)
|
storage.new_node (a_node)
|
||||||
end
|
end
|
||||||
|
|
||||||
delete_node (a_id: INTEGER_64)
|
delete_node (a_id: INTEGER_64)
|
||||||
@@ -129,37 +130,37 @@ feature -- Change: Node
|
|||||||
storage.delete_node (a_id)
|
storage.delete_node (a_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node (a_id: like {CMS_USER}.id; a_node: CMS_NODE)
|
update_node (a_node: CMS_NODE)
|
||||||
-- Update node by id `a_id' with `a_node' data.
|
-- Update node `a_node' data.
|
||||||
do
|
do
|
||||||
storage.update_node (a_id,a_node)
|
storage.update_node (a_node)
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node_title (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||||
-- Update node title, with user identified by `a_id', with node id `a_node_id' and a new title `a_title'.
|
-- Update node title, with user identified by `a_id', with node id `a_node_id' and a new title `a_title'.
|
||||||
do
|
do
|
||||||
debug ("refactor_fixme")
|
debug ("refactor_fixme")
|
||||||
fixme ("Check preconditions")
|
fixme ("Check preconditions")
|
||||||
end
|
end
|
||||||
storage.update_node_title (a_id,a_node_id,a_title)
|
storage.update_node_title (a_user_id, a_node_id, a_title)
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node_summary (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||||
-- Update node summary, with user identified by `a_id', with node id `a_node_id' and a new summary `a_summary'.
|
-- Update node summary, with user identified by `a_user_id', with node id `a_node_id' and a new summary `a_summary'.
|
||||||
do
|
do
|
||||||
debug ("refactor_fixme")
|
debug ("refactor_fixme")
|
||||||
fixme ("Check preconditions")
|
fixme ("Check preconditions")
|
||||||
end
|
end
|
||||||
storage.update_node_summary (a_id,a_node_id, a_summary)
|
storage.update_node_summary (a_user_id, a_node_id, a_summary)
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node_content (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||||
-- Update node content, with user identified by `a_id', with node id `a_node_id' and a new content `a_content'.
|
-- Update node content, with user identified by `a_user_id', with node id `a_node_id' and a new content `a_content'.
|
||||||
do
|
do
|
||||||
debug ("refactor_fixme")
|
debug ("refactor_fixme")
|
||||||
fixme ("Check preconditions")
|
fixme ("Check preconditions")
|
||||||
end
|
end
|
||||||
storage.update_node_content (a_id,a_node_id, a_content)
|
storage.update_node_content (a_user_id, a_node_id, a_content)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -175,12 +176,15 @@ feature -- Change User
|
|||||||
|
|
||||||
new_user (a_user: CMS_USER)
|
new_user (a_user: CMS_USER)
|
||||||
-- Add a new user `a_user'.
|
-- Add a new user `a_user'.
|
||||||
|
require
|
||||||
|
no_id: not a_user.has_id
|
||||||
|
no_hashed_password: a_user.hashed_password = Void
|
||||||
do
|
do
|
||||||
if
|
if
|
||||||
attached a_user.password as l_password and then
|
attached a_user.password as l_password and then
|
||||||
attached a_user.email as l_email
|
attached a_user.email as l_email
|
||||||
then
|
then
|
||||||
storage.save_user (a_user)
|
storage.new_user (a_user)
|
||||||
else
|
else
|
||||||
debug ("refactor_fixme")
|
debug ("refactor_fixme")
|
||||||
fixme ("Add error")
|
fixme ("Add error")
|
||||||
@@ -188,12 +192,65 @@ feature -- Change User
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
update_user (a_user: CMS_USER)
|
||||||
|
-- Update user `a_user'.
|
||||||
|
require
|
||||||
|
has_id: a_user.has_id
|
||||||
|
do
|
||||||
|
storage.update_user (a_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Helpers
|
||||||
|
|
||||||
|
html_encoded (a_string: READABLE_STRING_GENERAL): STRING_8
|
||||||
|
-- `a_string' encoded for html output.
|
||||||
|
do
|
||||||
|
Result := html_encoder.general_encoded_string (a_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
percent_encoded (a_string: READABLE_STRING_GENERAL): STRING_8
|
||||||
|
-- `a_string' encoded with percent encoding, mainly used for url.
|
||||||
|
do
|
||||||
|
Result := percent_encoder.percent_encoded_string (a_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Layout
|
||||||
|
|
||||||
|
module_configuration (a_module_name: READABLE_STRING_GENERAL; a_name: detachable READABLE_STRING_GENERAL): detachable CONFIG_READER
|
||||||
|
-- Configuration reader for `a_module', and if `a_name' is set, using name `a_name'.
|
||||||
|
local
|
||||||
|
p, l_path: PATH
|
||||||
|
ut: FILE_UTILITIES
|
||||||
|
do
|
||||||
|
p := setup.layout.config_path.extended ("modules").extended (a_module_name)
|
||||||
|
if a_name = Void then
|
||||||
|
p := p.extended (a_module_name)
|
||||||
|
else
|
||||||
|
p := p.extended (a_name)
|
||||||
|
end
|
||||||
|
l_path := p.appended_with_extension ("json")
|
||||||
|
if ut.file_path_exists (l_path) then
|
||||||
|
create {JSON_CONFIG} Result.make_from_file (l_path)
|
||||||
|
else
|
||||||
|
l_path := p.appended_with_extension ("ini")
|
||||||
|
if ut.file_path_exists (l_path) then
|
||||||
|
create {INI_CONFIG} Result.make_from_file (l_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if Result = Void and a_name /= Void then
|
||||||
|
-- Use sub config from default?
|
||||||
|
if attached {CONFIG_READER} module_configuration (a_module_name, Void) as cfg then
|
||||||
|
Result := cfg.sub_config (a_name)
|
||||||
|
else
|
||||||
|
-- Maybe try to use the global cms.ini ?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implemenataion
|
feature {NONE} -- Implemenataion
|
||||||
|
|
||||||
|
|
||||||
storage: CMS_STORAGE
|
storage: CMS_STORAGE
|
||||||
-- Persistence storage.
|
-- Persistence storage.
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ feature {NONE} -- Initialization
|
|||||||
-- Build a CMS service with `a_api'
|
-- Build a CMS service with `a_api'
|
||||||
do
|
do
|
||||||
api := a_api
|
api := a_api
|
||||||
configuration := a_api.setup.configuration
|
|
||||||
initialize
|
initialize
|
||||||
ensure
|
ensure
|
||||||
api_set: api = a_api
|
api_set: api = a_api
|
||||||
@@ -58,27 +57,17 @@ feature {NONE} -- Initialization
|
|||||||
initialize_users
|
initialize_users
|
||||||
initialize_auth_engine
|
initialize_auth_engine
|
||||||
initialize_mailer
|
initialize_mailer
|
||||||
|
-- initialize_router
|
||||||
|
-- initialize_filter: expanded here, for void-safety concern.
|
||||||
|
create_filter
|
||||||
initialize_router
|
initialize_router
|
||||||
initialize_filter
|
setup_filter
|
||||||
end
|
end
|
||||||
|
|
||||||
initialize_modules
|
initialize_modules
|
||||||
-- Intialize modules and keep only enabled modules.
|
-- Intialize modules and keep only enabled modules.
|
||||||
local
|
|
||||||
l_module: CMS_MODULE
|
|
||||||
l_available_modules: CMS_MODULE_COLLECTION
|
|
||||||
do
|
do
|
||||||
log.write_debug (generator + ".initialize_modules")
|
modules := setup.enabled_modules
|
||||||
l_available_modules := setup.modules
|
|
||||||
create modules.make (l_available_modules.count)
|
|
||||||
across
|
|
||||||
l_available_modules as ic
|
|
||||||
loop
|
|
||||||
l_module := ic.item
|
|
||||||
if l_module.is_enabled then
|
|
||||||
modules.extend (l_module)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ensure
|
ensure
|
||||||
only_enabled_modules: across modules as ic all ic.item.is_enabled end
|
only_enabled_modules: across modules as ic all ic.item.is_enabled end
|
||||||
end
|
end
|
||||||
@@ -169,6 +158,7 @@ feature -- Execute Filter
|
|||||||
-- Execute the filter.
|
-- Execute the filter.
|
||||||
do
|
do
|
||||||
res.put_header_line ("Date: " + (create {HTTP_DATE}.make_now_utc).string)
|
res.put_header_line ("Date: " + (create {HTTP_DATE}.make_now_utc).string)
|
||||||
|
res.put_header_line ("X-EWF-Server: CMS_v1.0")
|
||||||
execute_service (req, res)
|
execute_service (req, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -243,10 +233,6 @@ feature -- Access
|
|||||||
Result := api.setup
|
Result := api.setup
|
||||||
end
|
end
|
||||||
|
|
||||||
configuration: CMS_CONFIGURATION
|
|
||||||
-- CMS configuration.
|
|
||||||
--| Maybe we can compute it (using `setup') instead of using memory.
|
|
||||||
|
|
||||||
modules: CMS_MODULE_COLLECTION
|
modules: CMS_MODULE_COLLECTION
|
||||||
-- Configurator of possible modules.
|
-- Configurator of possible modules.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_ERROR_FILTER}."
|
description: "Summary description for {CMS_ERROR_FILTER}."
|
||||||
date: "$Date$"
|
date: "$Date: 2014-12-19 14:17:32 +0100 (ven., 19 déc. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96402 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
CMS_ERROR_FILTER
|
CMS_ERROR_FILTER
|
||||||
@@ -20,13 +20,20 @@ feature -- Basic operations
|
|||||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
-- Execute the filter
|
-- Execute the filter
|
||||||
do
|
do
|
||||||
if not api.error_handler.has_error then
|
fixme ("Check if it's ok to add new fetures CMS_API.has_error:BOOLEAN and CMS_API.error_description.")
|
||||||
log.write_information (generator + ".execute")
|
if not api.has_error then
|
||||||
|
log.write_information (generator + ".execute with req: " + req.debug_output)
|
||||||
|
if attached req.raw_header_data as l_header_data then
|
||||||
|
log.write_debug (generator + ".execute with req header: " + l_header_data)
|
||||||
|
end
|
||||||
|
if attached req.raw_input_data as l_input_data then
|
||||||
|
log.write_debug (generator + ".execute with req input: " + l_input_data)
|
||||||
|
end
|
||||||
execute_next (req, res)
|
execute_next (req, res)
|
||||||
else
|
else
|
||||||
log.write_critical (generator + ".execute" + api.error_handler.as_string_representation )
|
log.write_critical (generator + ".execute" + api.as_string_representation )
|
||||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
api.error_handler.reset
|
api.reset
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {BAD_REQUEST_ERROR_CMS_RESPONSE}."
|
||||||
|
date: "$Date: 2014-12-19 14:17:32 +0100 (ven., 19 déc. 2014) $"
|
||||||
|
revision: "$Revision: 96402 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
BAD_REQUEST_ERROR_CMS_RESPONSE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
|
||||||
|
CMS_RESPONSE
|
||||||
|
redefine
|
||||||
|
custom_prepare
|
||||||
|
end
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature -- Generation
|
||||||
|
|
||||||
|
custom_prepare (page: CMS_HTML_PAGE)
|
||||||
|
do
|
||||||
|
page.register_variable (request.absolute_script_url (request.path_info), "request")
|
||||||
|
page.set_status_code ({HTTP_STATUS_CODE}.bad_request)
|
||||||
|
page.register_variable (page.status_code.out, "code")
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Execution
|
||||||
|
|
||||||
|
process
|
||||||
|
-- Computed response message.
|
||||||
|
do
|
||||||
|
set_title ("Bad request")
|
||||||
|
set_page_title ("Bad request")
|
||||||
|
set_main_content ("<em>Bad request.</em>")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Generic CMS Response.It builds the content to get process to render the output"
|
description: "Generic CMS Response.It builds the content to get process to render the output"
|
||||||
date: "$Date$"
|
date: "$Date: 2014-12-15 21:43:38 +0100 (lun., 15 déc. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96346 $"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
CMS_RESPONSE
|
CMS_RESPONSE
|
||||||
@@ -36,19 +36,17 @@ feature {NONE} -- Initialization
|
|||||||
register_hooks
|
register_hooks
|
||||||
local
|
local
|
||||||
l_module: CMS_MODULE
|
l_module: CMS_MODULE
|
||||||
l_available_modules: CMS_MODULE_COLLECTION
|
l_enabled_modules: CMS_MODULE_COLLECTION
|
||||||
do
|
do
|
||||||
l_available_modules := setup.modules
|
l_enabled_modules := setup.enabled_modules
|
||||||
across
|
across
|
||||||
l_available_modules as ic
|
l_enabled_modules as ic
|
||||||
loop
|
loop
|
||||||
l_module := ic.item
|
l_module := ic.item
|
||||||
if l_module.is_enabled then
|
if attached {CMS_HOOK_AUTO_REGISTER} l_module as l_auto then
|
||||||
if attached {CMS_HOOK_AUTO_REGISTER} l_module as l_auto then
|
l_auto.auto_subscribe_to_hooks (Current)
|
||||||
l_auto.auto_subscribe_to_hooks (Current)
|
|
||||||
end
|
|
||||||
l_module.register_hooks (Current)
|
|
||||||
end
|
end
|
||||||
|
l_module.register_hooks (Current)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -81,6 +79,37 @@ feature -- Access
|
|||||||
additional_page_head_lines: detachable LIST [READABLE_STRING_8]
|
additional_page_head_lines: detachable LIST [READABLE_STRING_8]
|
||||||
-- HTML>head>...extra lines
|
-- HTML>head>...extra lines
|
||||||
|
|
||||||
|
feature -- Module
|
||||||
|
|
||||||
|
module_resource_path (a_module: CMS_MODULE; a_resource: PATH): detachable PATH
|
||||||
|
-- Resource path of `a_resource' for module `a_module', if resource exists.
|
||||||
|
local
|
||||||
|
rp: PATH
|
||||||
|
ut: FILE_UTILITIES
|
||||||
|
do
|
||||||
|
rp := module_assets_theme_location (a_module)
|
||||||
|
Result := rp.extended_path (a_resource)
|
||||||
|
if not ut.file_path_exists (Result) then
|
||||||
|
rp := module_assets_location (a_module)
|
||||||
|
Result := rp.extended_path (a_resource)
|
||||||
|
if not ut.file_path_exists (Result) then
|
||||||
|
Result := Void
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module_assets_location (a_module: CMS_MODULE): PATH
|
||||||
|
-- Location for the assets associated with `a_module'.
|
||||||
|
do
|
||||||
|
Result := setup.layout.path.extended ("modules").extended (a_module.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
module_assets_theme_location (a_module: CMS_MODULE): PATH
|
||||||
|
-- Location for the assets associated with `a_module'.
|
||||||
|
do
|
||||||
|
Result := setup.theme_location.extended ("modules").extended (a_module.name)
|
||||||
|
end
|
||||||
|
|
||||||
feature -- URL utilities
|
feature -- URL utilities
|
||||||
|
|
||||||
is_front: BOOLEAN
|
is_front: BOOLEAN
|
||||||
@@ -350,12 +379,6 @@ feature -- Blocks
|
|||||||
add_block (header_block, "header")
|
add_block (header_block, "header")
|
||||||
if attached message_block as m then
|
if attached message_block as m then
|
||||||
add_block (m, "content")
|
add_block (m, "content")
|
||||||
end
|
|
||||||
-- FIXME: avoid hardcoded html! should be only in theme.
|
|
||||||
add_block (create {CMS_CONTENT_BLOCK}.make_raw ("top_content_anchor", Void, "<a id=%"main-content%"></a>%N", formats.full_html), "content")
|
|
||||||
if attached page_title as l_page_title then
|
|
||||||
-- FIXME: avoid hardcoded html! should be only in theme.
|
|
||||||
add_block (create {CMS_CONTENT_BLOCK}.make_raw ("page_title", Void, "<h1 id=%"page-title%" class=%"title%">"+ l_page_title +"</h1>%N", formats.full_html), "content")
|
|
||||||
end
|
end
|
||||||
if attached primary_tabs_block as m then
|
if attached primary_tabs_block as m then
|
||||||
add_block (m, "content")
|
add_block (m, "content")
|
||||||
@@ -372,11 +395,10 @@ feature -- Blocks
|
|||||||
add_block (l_block, "first_sidebar")
|
add_block (l_block, "first_sidebar")
|
||||||
end
|
end
|
||||||
|
|
||||||
if attached footer_block as l_block then
|
|
||||||
add_block (l_block, "footer")
|
|
||||||
end
|
|
||||||
|
|
||||||
invoke_block
|
invoke_block
|
||||||
|
debug ("cms")
|
||||||
|
add_block (create {CMS_CONTENT_BLOCK}.make ("made_with", Void, "Made with <a href=%"http://www.eiffel.com/%">EWF</a>", Void), "footer")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
primary_menu_block: detachable CMS_MENU_BLOCK
|
primary_menu_block: detachable CMS_MENU_BLOCK
|
||||||
@@ -419,7 +441,7 @@ feature -- Blocks
|
|||||||
s: STRING
|
s: STRING
|
||||||
do
|
do
|
||||||
create s.make_empty
|
create s.make_empty
|
||||||
create Result.make ("page_top", Void, s, formats.full_html)
|
create Result.make ("page_top", Void, s, Void)
|
||||||
Result.set_is_raw (True)
|
Result.set_is_raw (True)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -430,7 +452,7 @@ feature -- Blocks
|
|||||||
do
|
do
|
||||||
create s.make_from_string (theme.menu_html (primary_menu, True))
|
create s.make_from_string (theme.menu_html (primary_menu, True))
|
||||||
create l_hb.make_empty
|
create l_hb.make_empty
|
||||||
create Result.make ("header", Void, l_hb, formats.full_html)
|
create Result.make ("header", Void, l_hb, Void)
|
||||||
Result.set_is_raw (True)
|
Result.set_is_raw (True)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -452,7 +474,7 @@ feature -- Blocks
|
|||||||
message_block: detachable CMS_CONTENT_BLOCK
|
message_block: detachable CMS_CONTENT_BLOCK
|
||||||
do
|
do
|
||||||
if attached message as m and then not m.is_empty then
|
if attached message as m and then not m.is_empty then
|
||||||
create Result.make ("message", Void, "<div id=%"message%">" + m + "</div>", formats.full_html)
|
create Result.make ("message", Void, "<div id=%"message%">" + m + "</div>", Void)
|
||||||
Result.set_is_raw (True)
|
Result.set_is_raw (True)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -469,22 +491,10 @@ feature -- Blocks
|
|||||||
s := "No Content"
|
s := "No Content"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
create Result.make ("content", Void, s, formats.full_html)
|
create Result.make ("content", Void, s, Void)
|
||||||
Result.set_is_raw (True)
|
Result.set_is_raw (True)
|
||||||
end
|
end
|
||||||
|
|
||||||
made_with_html: STRING
|
|
||||||
do
|
|
||||||
create Result.make_empty
|
|
||||||
Result.append ("Made with <a href=%"http://www.eiffel.com/%">EWF</a>")
|
|
||||||
end
|
|
||||||
|
|
||||||
footer_block: CMS_CONTENT_BLOCK
|
|
||||||
do
|
|
||||||
create Result.make ("made_with", Void, made_with_html, Void)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature -- Hooks
|
feature -- Hooks
|
||||||
|
|
||||||
hook_subscribers: HASH_TABLE [LIST [CMS_HOOK], TYPE [CMS_HOOK]]
|
hook_subscribers: HASH_TABLE [LIST [CMS_HOOK], TYPE [CMS_HOOK]]
|
||||||
@@ -722,7 +732,9 @@ feature -- Theme
|
|||||||
if l_info.engine.is_case_insensitive_equal_general ("smarty") then
|
if l_info.engine.is_case_insensitive_equal_general ("smarty") then
|
||||||
create {SMARTY_CMS_THEME} theme.make (setup, l_info)
|
create {SMARTY_CMS_THEME} theme.make (setup, l_info)
|
||||||
else
|
else
|
||||||
create {DEFAULT_CMS_THEME} theme.make (setup, l_info)
|
create {MISSING_CMS_THEME} theme.make (setup)
|
||||||
|
status_code := {HTTP_STATUS_CODE}.service_unavailable
|
||||||
|
to_implement ("Check how to add the Retry-after, http://tools.ietf.org/html/rfc7231#section-6.6.4 and http://tools.ietf.org/html/rfc7231#section-7.1.3")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -786,6 +798,13 @@ feature -- Generation
|
|||||||
across
|
across
|
||||||
reg_ic.item.blocks as ic
|
reg_ic.item.blocks as ic
|
||||||
loop
|
loop
|
||||||
|
-- if attached {CMS_SMARTY_CONTENT_BLOCK} ic.item as l_tpl_block then
|
||||||
|
-- across
|
||||||
|
-- page.variables as var_ic
|
||||||
|
-- loop
|
||||||
|
-- l_tpl_block.set_value (var_ic.item, var_ic.key)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
page.add_to_region (theme.block_html (ic.item), reg_ic.item.name)
|
page.add_to_region (theme.block_html (ic.item), reg_ic.item.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -837,6 +856,11 @@ feature -- Generation
|
|||||||
|
|
||||||
-- Menu...
|
-- Menu...
|
||||||
page.register_variable (horizontal_primary_menu_html, "primary_nav")
|
page.register_variable (horizontal_primary_menu_html, "primary_nav")
|
||||||
|
|
||||||
|
-- Page related
|
||||||
|
if attached page_title as l_page_title then
|
||||||
|
page.register_variable (l_page_title, "page_title")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
custom_prepare (page: CMS_HTML_PAGE)
|
custom_prepare (page: CMS_HTML_PAGE)
|
||||||
@@ -886,7 +910,11 @@ feature -- Generation
|
|||||||
-- Update the active status recursively on `a_comp'.
|
-- Update the active status recursively on `a_comp'.
|
||||||
local
|
local
|
||||||
ln: CMS_LINK
|
ln: CMS_LINK
|
||||||
|
l_comp_link: detachable CMS_LOCAL_LINK
|
||||||
do
|
do
|
||||||
|
if attached {CMS_LOCAL_LINK} a_comp as lnk then
|
||||||
|
l_comp_link := lnk
|
||||||
|
end
|
||||||
if attached a_comp.items as l_items then
|
if attached a_comp.items as l_items then
|
||||||
across
|
across
|
||||||
l_items as ic
|
l_items as ic
|
||||||
@@ -898,8 +926,16 @@ feature -- Generation
|
|||||||
if (ln.is_expanded or ln.is_collapsed) and then attached {CMS_LINK_COMPOSITE} ln as l_comp then
|
if (ln.is_expanded or ln.is_collapsed) and then attached {CMS_LINK_COMPOSITE} ln as l_comp then
|
||||||
recursive_get_active (l_comp, req)
|
recursive_get_active (l_comp, req)
|
||||||
end
|
end
|
||||||
|
if l_comp_link /= Void then
|
||||||
|
if ln.is_expanded or (not ln.is_expandable and ln.is_active) then
|
||||||
|
l_comp_link.set_expanded (True)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if l_comp_link /= Void and then l_comp_link.is_active then
|
||||||
|
l_comp_link.set_expanded (True)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
get_local_link_active_status (a_lnk: CMS_LOCAL_LINK)
|
get_local_link_active_status (a_lnk: CMS_LOCAL_LINK)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {HOME_CMS_RESPONSE}."
|
description: "Summary description for {HOME_CMS_RESPONSE}."
|
||||||
date: "$Date$"
|
date: "$Date: 2014-12-17 13:14:43 +0100 (mer., 17 déc. 2014) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 96367 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
HOME_CMS_RESPONSE
|
HOME_CMS_RESPONSE
|
||||||
@@ -21,7 +21,7 @@ feature -- Generation
|
|||||||
custom_prepare (page: CMS_HTML_PAGE)
|
custom_prepare (page: CMS_HTML_PAGE)
|
||||||
do
|
do
|
||||||
Precursor (page)
|
Precursor (page)
|
||||||
page.register_variable (api.recent_nodes (0, 5), "nodes")
|
-- page.register_variable (api.recent_nodes (0, 5), "nodes")
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user