Commit d47df833 authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

use fulltext search in title and description.

* to quickly setup catalog_full_text table, you can use the following SQL.

  REPLACE INTO catalog_full_text SELECT uid, title, description FROM catalog;

* non fulltext queries like '=abc', '>abc', '%abc%' are supported.

* now erp5_full_text_mroonga_catalog is used for unit tests thus I recommend using it instead of erp5_full_text_myisam_catalog.

* to migrate existing MyISAM full_text table into Mroonga, you can use the following SQL.

  ALTER TABLE full_text DROP KEY SearchableText,
    ENGINE = mroonga,
    ADD FULLTEXT KEY SearchableText (`SearchableText`) COMMENT 'parser "TokenBigramSplitSymbolAlpha"';

* fulltext search score is no longer provided as (column_name) but now provided as (column_name)__score__.

* (category)_title, like source_title, related keys are automatically generated. (category)_description keys as well.
parent 315d57fb
<key_list>
<key>accounting_transaction_line_node_uid | stock/node_uid/z_related_accounting_transaction_stock_line</key>
<key>accounting_transaction_line_total_price | stock/total_price/z_related_accounting_transaction_stock_line</key>
<key>accounting_transaction_mirror_section_title | catalog/title/z_related_accounting_transaction_mirror_section</key>
<key>accounting_transaction_payment_title | catalog/title/z_related_accounting_transaction_payment</key>
<key>accounting_transaction_project_title | catalog/title/z_related_accounting_transaction_project</key>
<key>accounting_transaction_section_title | catalog/title/z_related_accounting_transaction_section</key>
<key>accounting_transaction_mirror_section_title | catalog_full_text/title/z_related_accounting_transaction_mirror_section</key>
<key>accounting_transaction_payment_title | catalog_full_text/title/z_related_accounting_transaction_payment</key>
<key>accounting_transaction_project_title | catalog_full_text/title/z_related_accounting_transaction_project</key>
<key>accounting_transaction_section_title | catalog_full_text/title/z_related_accounting_transaction_section</key>
<key>preferred_gap_id | category,catalog/id/z_related_preferred_gap</key>
<key>preferred_gap_strict_membership_id | category,catalog/id/z_related_strict_membership_preferred_gap</key>
</key_list>
\ No newline at end of file
preferred_gap_id | category,catalog/id/z_related_preferred_gap
preferred_gap_strict_membership_id | category,catalog/id/z_related_strict_membership_preferred_gap
accounting_transaction_mirror_section_title | catalog/title/z_related_accounting_transaction_mirror_section
accounting_transaction_section_title | catalog/title/z_related_accounting_transaction_section
accounting_transaction_project_title | catalog/title/z_related_accounting_transaction_project
accounting_transaction_payment_title | catalog/title/z_related_accounting_transaction_payment
accounting_transaction_mirror_section_title | catalog_full_text/title/z_related_accounting_transaction_mirror_section
accounting_transaction_section_title | catalog_full_text/title/z_related_accounting_transaction_section
accounting_transaction_project_title | catalog_full_text/title/z_related_accounting_transaction_project
accounting_transaction_payment_title | catalog_full_text/title/z_related_accounting_transaction_payment
accounting_transaction_line_node_uid | stock/node_uid/z_related_accounting_transaction_stock_line
accounting_transaction_line_total_price | stock/total_price/z_related_accounting_transaction_stock_line
\ No newline at end of file
......@@ -53,6 +53,7 @@
<value> <string encoding="cdata"><![CDATA[
from DateTime import DateTime\n
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery\n
\n
# params\n
section_title = \'My Organisation\'\n
......@@ -90,7 +91,7 @@ if 1:\n
def getAccountByTitle(title):\n
account_list = [x.getObject().getRelativeUrl() for x in\n
portal.portal_catalog(portal_type=\'Account\',\n
title=title)]\n
title=SimpleQuery(title=title, comparison_operator=\'=\'))]\n
assert len(account_list) == 1, \\\n
\'%d account with title "%s"\' % (len(account_list), title)\n
return account_list[0]\n
......@@ -98,7 +99,7 @@ def getAccountByTitle(title):\n
def getOrganisationByTitle(title):\n
document_list = [x.getObject().getRelativeUrl() for x in\n
portal.portal_catalog(portal_type=\'Organisation\',\n
title=title)]\n
title=SimpleQuery(title=title, comparison_operator=\'=\'))]\n
assert len(document_list) == 1, \\\n
\'%d organisation with title "%s"\' % (len(document_list), title)\n
return document_list[0]\n
......@@ -109,14 +110,14 @@ euro_resource = \'currency_module/euro\'\n
def getBankAccountByTitle(title):\n
document_list = [x.getObject().getRelativeUrl() for x in\n
portal.portal_catalog(portal_type=\'Bank Account\',\n
title=title)]\n
title=SimpleQuery(title=title, comparison_operator=\'=\'))]\n
assert len(document_list) == 1, \\\n
\'%d Bank Account with title "%s"\' % (len(document_list), title)\n
return document_list[0]\n
\n
product_list = [o.getObject() for o in portal.portal_catalog(\n
portal_type=\'Product\',\n
title=\'Dummy Product for testing\')]\n
title=SimpleQuery(title=\'Dummy Product for testing\', comparison_operator=\'=\'))]\n
if product_list:\n
product = product_list[0]\n
else:\n
......
......@@ -53,6 +53,7 @@
<value> <string encoding="cdata"><![CDATA[
from DateTime import DateTime\n
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery\n
\n
# params\n
section_title = \'My Organisation\'\n
......@@ -80,7 +81,7 @@ if 1:\n
def getAccountByTitle(title):\n
account_list = [x.getObject().getRelativeUrl() for x in\n
portal.portal_catalog(portal_type=\'Account\',\n
title=title)]\n
title=SimpleQuery(title=title, comparison_operator=\'=\'))]\n
assert len(account_list) == 1, \\\n
\'%d account with title "%s"\' % (len(account_list), title)\n
return account_list[0]\n
......@@ -88,7 +89,7 @@ def getAccountByTitle(title):\n
def getOrganisationByTitle(title):\n
document_list = [x.getObject().getRelativeUrl() for x in\n
portal.portal_catalog(portal_type=\'Organisation\',\n
title=title)]\n
title=SimpleQuery(title=title, comparison_operator=\'=\'))]\n
assert len(document_list) == 1, \\\n
\'%d organisation with title "%s"\' % (len(document_list), title)\n
return document_list[0]\n
......@@ -106,7 +107,7 @@ euro_resource = getCurrencyByReference(\'EUR\')\n
def getBankAccountByTitle(title):\n
document_list = [x.getObject().getRelativeUrl() for x in\n
portal.portal_catalog(portal_type=\'Bank Account\',\n
title=title)]\n
title=SimpleQuery(title=title, comparison_operator=\'=\'))]\n
assert len(document_list) == 1, \\\n
\'%d Bank Account with title "%s"\' % (len(document_list), title)\n
return document_list[0]\n
......
......@@ -58,6 +58,7 @@ business_process = \'business_process_module/erp5_default_business_process\'\n
portal = context.getPortalObject()\n
accounting_module = portal.accounting_module\n
from DateTime import DateTime\n
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery\n
year = 2005\n
\n
# if the previous test didn\'t change input data, no need to recreate content\n
......@@ -82,7 +83,7 @@ if 1:\n
def getAccountByTitle(title):\n
account_list = [x.getObject().getRelativeUrl() for x in\n
portal.portal_catalog(portal_type=\'Account\',\n
title=title)]\n
title=SimpleQuery(title=title, comparison_operator=\'=\'))]\n
assert len(account_list) == 1, \\\n
\'%d account with title "%s"\' % (len(account_list), title)\n
return account_list[0]\n
......@@ -90,7 +91,7 @@ def getAccountByTitle(title):\n
def getOrganisationByTitle(title):\n
document_list = [x.getObject().getRelativeUrl() for x in\n
portal.portal_catalog(portal_type=\'Organisation\',\n
title=title)]\n
title=SimpleQuery(title=title, comparison_operator=\'=\'))]\n
assert len(document_list) == 1, \\\n
\'%d organisation with title "%s"\' % (len(document_list), title)\n
return document_list[0]\n
......@@ -99,7 +100,7 @@ section = getOrganisationByTitle(section_title)\n
def getPersonByTitle(title):\n
document_list = [x.getObject().getRelativeUrl() for x in\n
portal.portal_catalog(portal_type=\'Person\',\n
title=title)]\n
title=SimpleQuery(title=title, comparison_operator=\'=\'))]\n
assert len(document_list) == 1, \\\n
\'%d person with title "%s"\' % (len(document_list), title)\n
return document_list[0]\n
......@@ -116,7 +117,7 @@ euro_resource = getCurrencyByReference(\'EUR\')\n
def getBankAccountByTitle(title):\n
document_list = [x.getObject().getRelativeUrl() for x in\n
portal.portal_catalog(portal_type=\'Bank Account\',\n
title=title)]\n
title=SimpleQuery(title=title, comparison_operator=\'=\'))]\n
assert len(document_list) == 1, \\\n
\'%d Bank Account with title "%s"\' % (len(document_list), title)\n
return document_list[0]\n
......
......@@ -51,6 +51,7 @@
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery\n
\n
# validate rules\n
for rule in portal.portal_rules.objectValues():\n
......@@ -129,7 +130,7 @@ stool.setSelectionColumns(\'account_module_selection\',\n
\n
# delete the "dummy account" we create in test_account_gap_parallel_list_field\n
dummy_account_list = portal.account_module.searchFolder(\n
title=\'Dummy Account for UI Test\')\n
title=SimpleQuery(title=\'Dummy Account for UI Test\', comparison_operator=\'=\'))\n
if dummy_account_list:\n
portal.account_module.manage_delObjects([dummy_account_list[0].getId()])\n
\n
......
......@@ -2,8 +2,8 @@
<key>child_address_SearchableText | catalog,full_text/SearchableText/z_related_child_address</key>
<key>child_telephone_SearchableText | catalog,full_text/SearchableText/z_related_child_telephone</key>
<key>default_email_text | catalog,email/url_string/z_related_default_email</key>
<key>destination_person_title | category,catalog/title/z_related_destination_person</key>
<key>destination_person_title | category,catalog_full_text/title/z_related_destination_person</key>
<key>related_resource_use_uid | category,category,catalog,catalog/uid/z_related_resource_use</key>
<key>source_organisation_title | category,catalog/title/z_related_source_organisation</key>
<key>source_person_title | category,catalog/title/z_related_source_person</key>
<key>source_organisation_title | category,catalog_full_text/title/z_related_source_organisation</key>
<key>source_person_title | category,catalog_full_text/title/z_related_source_person</key>
</key_list>
\ No newline at end of file
source_organisation_title | category,catalog/title/z_related_source_organisation
source_person_title | category,catalog/title/z_related_source_person
destination_person_title | category,catalog/title/z_related_destination_person
source_organisation_title | category,catalog_full_text/title/z_related_source_organisation
source_person_title | category,catalog_full_text/title/z_related_source_person
destination_person_title | category,catalog_full_text/title/z_related_destination_person
default_email_text | catalog,email/url_string/z_related_default_email
related_resource_use_uid | category,category,catalog,catalog/uid/z_related_resource_use
child_address_SearchableText | catalog,full_text/SearchableText/z_related_child_address
......
erp5_full_text_myisam_catalog
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
erp5_full_text_myisam_catalog
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
erp5_core_proxy_field_legacy
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
erp5_workflow
\ No newline at end of file
erp5_core_proxy_field_legacy
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
erp5_workflow
\ No newline at end of file
erp5_full_text_myisam_catalog
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
erp5_core_proxy_field_legacy
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
erp5_workflow
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from Products.ZSQLCatalog.SQLCatalog import Query, SimpleQuery, AndQuery\n
\n
########### CONFIGURATION ######################################\n
# This is a query for search translated properties of Person #\n
# documents. If you want to get other results. Customise this. # \n
################################################################\n
\n
query = AndQuery(SimpleQuery(**{\'content_translation.translated_text\': value, \'comparison_operator\': \'match\'}),\n
Query(**{\'content_translation.property_name\': \'title\'})\n
)\n
\n
################################################################\n
# Above query must make SQL condition like this. #\n
################################################################\n
# MATCH(content_translation.translated_text) AGAINST({value})\n
# AND content_translation.property_name = \'title\'\n
\n
return query\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>value</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SQLCatalog_makeContentTranslationSearchQuery</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<key_list>
<key>content_translation_title | SQLCatalog_makeContentTranslationSearchQuery</key>
<key>content_translation_title | SQLCatalog_makeTranslatedTitleQuery</key>
</key_list>
\ No newline at end of file
content_translation_title | SQLCatalog_makeContentTranslationSearchQuery
\ No newline at end of file
content_translation_title | SQLCatalog_makeTranslatedTitleQuery
\ No newline at end of file
......@@ -6,5 +6,5 @@
<key>related_source_or_source_decision_or_destination_or_destination_decision | category,catalog,catalog/uid/z_related_source_or_source_decision_or_destination_or_destination_decision</key>
<key>related_source_or_source_section_or_destination_or_destination_section | category,catalog,catalog/uid/z_related_source_or_source_section_or_destination_or_destination_section</key>
<key>related_source_section_or_destination_section | category,catalog,catalog/uid/z_related_source_section_or_destination_section</key>
<key>source_organisation_title | category,catalog/title/z_related_source_organisation</key>
<key>source_organisation_title | category,catalog_full_text/title/z_related_source_organisation</key>
</key_list>
\ No newline at end of file
source_organisation_title | category,catalog/title/z_related_source_organisation
source_organisation_title | category,catalog_full_text/title/z_related_source_organisation
event_causality_ticket_uid | category,catalog,category,catalog/uid/z_related_event_causality_ticket
related_source_or_destination | category,catalog,catalog/uid/z_related_source_or_destination
related_source_section_or_destination_section | category,catalog,catalog/uid/z_related_source_section_or_destination_section
......
......@@ -51,7 +51,7 @@
<item>
<key> <string>_body</string> </key>
<value> <string>return (\'erp5_core_proxy_field_legacy\',\n
\'erp5_full_text_myisam_catalog\',\n
\'erp5_full_text_mroonga_catalog\',\n
\'erp5_base\',\n
\'erp5_workflow\',\n
\'erp5_configurator\',\n
......
......@@ -51,7 +51,7 @@
<item>
<key> <string>_body</string> </key>
<value> <string>return (\'erp5_core_proxy_field_legacy\',\n
\'erp5_full_text_myisam_catalog\',\n
\'erp5_full_text_mroonga_catalog\',\n
\'erp5_base\',\n
\'erp5_simulation\',\n
\'erp5_dhtml_style\',\n
......
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
erp5_web
erp5_ingestion_mysql_innodb_catalog
......
<key_list>
<key>SearchableText</key>
<key>full_text.SearchableText</key>
</key_list>
\ No newline at end of file
......@@ -68,8 +68,9 @@ for path in path_list:\n
try:\n
tmp_dict = {}\n
for property in property_list:\n
if property == \'SearchableText\':\n
value = obj.SearchableText()\n
getter = getattr(obj, property, None)\n
if getter is not None and callable(getter):\n
value = getter()\n
else:\n
value = getattr(obj, \'get%s\' % UpperCase(property))()\n
tmp_dict[property] = value\n
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_col</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z0_drop_catalog_fulltext</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string>DROP TABLE IF EXISTS catalog_full_text</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<catalog_method>
<item key="sql_uncatalog_object" type="int">
<value>1</value>
</item>
</catalog_method>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>uid</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_deferred_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z0_uncatalog_catalog_fulltext</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
DELETE FROM catalog_full_text WHERE <dtml-sqltest uid op=eq type=int>
]]></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<catalog_method>
<item key="sql_catalog_object_list" type="int">
<value>1</value>
</item>
</catalog_method>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>uid\r\n
getTitle\r\n
getDescription</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_deferred_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_catalog_catalog_fulltext_list</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
REPLACE INTO\n
catalog_full_text (`uid`, `title`, `description`)\n
VALUES\n
<dtml-in prefix="loop" expr="_.range(_.len(uid))">\n
(\n
<dtml-sqlvar expr="uid[loop_item]" type="int">, \n
<dtml-sqlvar expr="getTitle[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getDescription[loop_item]" type="string" optional>\n
)<dtml-unless sequence-end>,</dtml-unless>\n
</dtml-in>\n
]]></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -55,21 +55,16 @@ SearchableText</string> </value>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
DELETE FROM\n
full_text\n
WHERE\n
<dtml-in uid>\n
uid=<dtml-sqlvar sequence-item type="int"><dtml-if sequence-end><dtml-else> OR </dtml-if>\n
</dtml-in>\n
;\n
<dtml-var "\'\\0\'"><dtml-let document_list="[]">\n
<dtml-let document_list="[]" delete_list="[]">\n
<dtml-in prefix="loop" expr="_.range(_.len(uid))">\n
<dtml-if "SearchableText[loop_item]">\n
<dtml-call expr="document_list.append(loop_item)">\n
<dtml-else>\n
<dtml-call expr="delete_list.append(loop_item)">\n
</dtml-if>\n
</dtml-in>\n
<dtml-if expr="_.len(document_list) > 0">\n
INSERT INTO\n
REPLACE INTO\n
full_text\n
VALUES\n
<dtml-in prefix="loop" expr="document_list">\n
......@@ -79,7 +74,19 @@ VALUES\n
)<dtml-unless sequence-end>,</dtml-unless>\n
</dtml-in>\n
</dtml-if>\n
</dtml-let>
<dtml-if expr="_.len(delete_list) > 0">\n
<dtml-var sql_delimiter>\n
DELETE FROM\n
full_text\n
WHERE uid IN\n
( \n
<dtml-in prefix="loop" expr="delete_list">\n
<dtml-sqlvar expr="uid[loop_item]" type="int"><dtml-unless sequence-end>,</dtml-unless>\n
</dtml-in>\n
)\n
</dtml-if>\n
</dtml-let>\n
]]></string> </value>
</item>
......
<catalog_method>
<item key="sql_clear_catalog" type="int">
<value>1</value>
</item>
</catalog_method>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_col</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_create_catalog_fulltext</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string># Host:\n
# Database: test\n
# Table: \'catalog_full_text\'\n
#\n
CREATE TABLE `catalog_full_text` (\n
`uid` BIGINT UNSIGNED NOT NULL,\n
`title` varchar(255) default \'\',\n
`description` text,\n
PRIMARY KEY (`uid`),\n
FULLTEXT `title` (`title`) COMMENT \'parser "TokenBigramSplitSymbolAlpha"\',\n
FULLTEXT `description` (`description`) COMMENT \'parser "TokenBigramSplitSymbolAlpha"\'\n
) ENGINE=mroonga;\n
</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -64,7 +64,7 @@
`content_language` VARBINARY(100),\n
`translated_text` TEXT,\n
PRIMARY KEY (`uid`, `property_name`, `content_language`),\n
FULLTEXT KEY (`translated_text`)\n
FULLTEXT KEY (`translated_text`) COMMENT \'parser "TokenBigramSplitSymbolAlpha"\'\n
) ENGINE=mroonga;\n
</string> </value>
</item>
......
......@@ -66,7 +66,7 @@ CREATE TABLE `full_text` (\n
`uid` BIGINT UNSIGNED NOT NULL,\n
`SearchableText` MEDIUMTEXT,\n
PRIMARY KEY (`uid`),\n
FULLTEXT `SearchableText` (`SearchableText`)\n
FULLTEXT `SearchableText` (`SearchableText`) COMMENT \'parser "TokenBigramSplitSymbolAlpha"\'\n
) ENGINE=mroonga;\n
</string> </value>
</item>
......
<key_list>
<key>career_skill_title | category,catalog,catalog_full_text/title/z_related_career_skill</key>
<key>description | catalog_full_text/description/z_related_uid</key>
<key>parent_description | catalog_full_text/description/z_related_parent</key>
<key>parent_title | catalog_full_text/title/z_related_parent</key>
<key>stock_explanation_title | catalog_full_text/title/z_related_explanation_from_stock</key>
<key>stock_mirror_section_title | catalog_full_text/title/z_related_mirror_section_uid_from_stock</key>
<key>stock_node_title | catalog_full_text/title/z_related_node_uid_from_stock</key>
<key>title | catalog_full_text/title/z_related_uid</key>
</key_list>
\ No newline at end of file
<key_list>
<key>catalog_full_text</key>
<key>full_text</key>
</key_list>
\ No newline at end of file
<key_list>
<key>SearchableText | MroongaBooleanFullTextKey</key>
<key>catalog_full_text.description | MroongaBooleanFullTextKey</key>
<key>catalog_full_text.title | MroongaBooleanFullTextKey</key>
<key>description | MroongaBooleanFullTextKey</key>
<key>full_text.SearchableText | MroongaBooleanFullTextKey</key>
<key>title | MroongaBooleanFullTextKey</key>
</key_list>
\ No newline at end of file
SearchableText
full_text.SearchableText
\ No newline at end of file
erp5_mysql_innodb/SQLCatalog_deferFullTextIndex
erp5_mysql_innodb/SQLCatalog_deferFullTextIndexActivity
erp5_mysql_innodb/SQLCatalog_makeFullTextQuery
erp5_mysql_innodb/z0_drop_catalog_fulltext
erp5_mysql_innodb/z0_drop_content_translation
erp5_mysql_innodb/z0_drop_fulltext
erp5_mysql_innodb/z0_uncatalog_catalog_fulltext
erp5_mysql_innodb/z0_uncatalog_fulltext
erp5_mysql_innodb/z_catalog_catalog_fulltext_list
erp5_mysql_innodb/z_catalog_fulltext_list
erp5_mysql_innodb/z_create_catalog_fulltext
erp5_mysql_innodb/z_create_content_translation
erp5_mysql_innodb/z_create_fulltext
\ No newline at end of file
career_skill_title | category,catalog,catalog_full_text/title/z_related_career_skill
description | catalog_full_text/description/z_related_uid
parent_description | catalog_full_text/description/z_related_parent
parent_title | catalog_full_text/title/z_related_parent
stock_explanation_title | catalog_full_text/title/z_related_explanation_from_stock
stock_mirror_section_title | catalog_full_text/title/z_related_mirror_section_uid_from_stock
stock_node_title | catalog_full_text/title/z_related_node_uid_from_stock
title | catalog_full_text/title/z_related_uid
\ No newline at end of file
SearchableText | MroongaBooleanFullTextKey
catalog_full_text.description | MroongaBooleanFullTextKey
catalog_full_text.title | MroongaBooleanFullTextKey
description | MroongaBooleanFullTextKey
full_text.SearchableText | MroongaBooleanFullTextKey
title | MroongaBooleanFullTextKey
\ No newline at end of file
<key_list>
<key>SearchableText</key>
<key>full_text.SearchableText</key>
<key>catalog_full_text.description</key>
<key>catalog_full_text.title</key> |
<key>description</key> |
<key>full_text.SearchableText</key> |
<key>title</key> |
</key_list>
\ No newline at end of file
......@@ -68,8 +68,9 @@ for path in path_list:\n
try:\n
tmp_dict = {}\n
for property in property_list:\n
if property == \'SearchableText\':\n
value = obj.SearchableText()\n
getter = getattr(obj, property, None)\n
if getter is not None and callable(getter):\n
value = getter()\n
else:\n
value = getattr(obj, \'get%s\' % UpperCase(property))()\n
tmp_dict[property] = value\n
......
<catalog_method>
<item key="sql_clear_catalog" type="int">
<value>1</value>
</item>
</catalog_method>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_col</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z0_drop_catalog_fulltext</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string>DROP TABLE IF EXISTS catalog_full_text</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<catalog_method>
<item key="sql_uncatalog_object" type="int">
<value>1</value>
</item>
</catalog_method>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>uid</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_deferred_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z0_uncatalog_catalog_fulltext</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
DELETE FROM catalog_full_text WHERE <dtml-sqltest uid op=eq type=int>
]]></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<catalog_method>
<item key="sql_catalog_object_list" type="int">
<value>1</value>
</item>
</catalog_method>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>uid\r\n
getTitle\r\n
getDescription</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_deferred_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_catalog_catalog_fulltext_list</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
REPLACE INTO\n
catalog_full_text (`uid`, `title`, `description`)\n
VALUES\n
<dtml-in prefix="loop" expr="_.range(_.len(uid))">\n
(\n
<dtml-sqlvar expr="uid[loop_item]" type="int">, \n
<dtml-sqlvar expr="getTitle[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getDescription[loop_item]" type="string" optional>\n
)<dtml-unless sequence-end>,</dtml-unless>\n
</dtml-in>\n
]]></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -55,21 +55,16 @@ SearchableText</string> </value>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
DELETE FROM\n
full_text\n
WHERE\n
<dtml-in uid>\n
uid=<dtml-sqlvar sequence-item type="int"><dtml-if sequence-end><dtml-else> OR </dtml-if>\n
</dtml-in>\n
;\n
<dtml-var "\'\\0\'"><dtml-let document_list="[]">\n
<dtml-let document_list="[]" delete_list="[]">\n
<dtml-in prefix="loop" expr="_.range(_.len(uid))">\n
<dtml-if "SearchableText[loop_item]">\n
<dtml-call expr="document_list.append(loop_item)">\n
<dtml-else>\n
<dtml-call expr="delete_list.append(loop_item)">\n
</dtml-if>\n
</dtml-in>\n
<dtml-if expr="_.len(document_list) > 0">\n
INSERT INTO\n
REPLACE INTO\n
full_text\n
VALUES\n
<dtml-in prefix="loop" expr="document_list">\n
......@@ -79,7 +74,19 @@ VALUES\n
)<dtml-unless sequence-end>,</dtml-unless>\n
</dtml-in>\n
</dtml-if>\n
</dtml-let>
<dtml-if expr="_.len(delete_list) > 0">\n
<dtml-var sql_delimiter>\n
DELETE FROM\n
full_text\n
WHERE uid IN\n
( \n
<dtml-in prefix="loop" expr="delete_list">\n
<dtml-sqlvar expr="uid[loop_item]" type="int"><dtml-unless sequence-end>,</dtml-unless>\n
</dtml-in>\n
)\n
</dtml-if>\n
</dtml-let>\n
]]></string> </value>
</item>
......
<catalog_method>
<item key="sql_clear_catalog" type="int">
<value>1</value>
</item>
</catalog_method>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_col</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_create_catalog_fulltext</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string># Host:\n
# Database: test\n
# Table: \'catalog_full_text\'\n
#\n
CREATE TABLE `catalog_full_text` (\n
`uid` BIGINT UNSIGNED NOT NULL,\n
`title` varchar(255) default \'\',\n
`description` text,\n
PRIMARY KEY (`uid`),\n
FULLTEXT `title` (`title`),\n
FULLTEXT `description` (`description`)\n
) ENGINE=MyISAM;\n
</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<key_list>
<key>career_skill_title | category,catalog,catalog_full_text/title/z_related_career_skill</key>
<key>description | catalog_full_text/description/z_related_uid</key>
<key>parent_description | catalog_full_text/description/z_related_parent</key>
<key>parent_title | catalog_full_text/title/z_related_parent</key>
<key>stock_explanation_title | catalog_full_text/title/z_related_explanation_from_stock</key>
<key>stock_mirror_section_title | catalog_full_text/title/z_related_mirror_section_uid_from_stock</key>
<key>stock_node_title | catalog_full_text/title/z_related_node_uid_from_stock</key>
<key>title | catalog_full_text/title/z_related_uid</key>
</key_list>
\ No newline at end of file
<key_list>
<key>catalog_full_text</key>
<key>full_text</key>
</key_list>
\ No newline at end of file
SearchableText
full_text.SearchableText
\ No newline at end of file
catalog_full_text.description
catalog_full_text.title
description
full_text.SearchableText
title
\ No newline at end of file
erp5_mysql_innodb/SQLCatalog_deferFullTextIndex
erp5_mysql_innodb/SQLCatalog_deferFullTextIndexActivity
erp5_mysql_innodb/SQLCatalog_makeFullTextQuery
erp5_mysql_innodb/z0_drop_catalog_fulltext
erp5_mysql_innodb/z0_drop_content_translation
erp5_mysql_innodb/z0_drop_fulltext
erp5_mysql_innodb/z0_uncatalog_catalog_fulltext
erp5_mysql_innodb/z0_uncatalog_fulltext
erp5_mysql_innodb/z_catalog_catalog_fulltext_list
erp5_mysql_innodb/z_catalog_fulltext_list
erp5_mysql_innodb/z_create_catalog_fulltext
erp5_mysql_innodb/z_create_content_translation
erp5_mysql_innodb/z_create_fulltext
\ No newline at end of file
career_skill_title | category,catalog,catalog_full_text/title/z_related_career_skill
description | catalog_full_text/description/z_related_uid
parent_description | catalog_full_text/description/z_related_parent
parent_title | catalog_full_text/title/z_related_parent
stock_explanation_title | catalog_full_text/title/z_related_explanation_from_stock
stock_mirror_section_title | catalog_full_text/title/z_related_mirror_section_uid_from_stock
stock_node_title | catalog_full_text/title/z_related_node_uid_from_stock
title | catalog_full_text/title/z_related_uid
\ No newline at end of file
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_ingestion_mysql_innodb_catalog
erp5_web
erp5_crm
......
<key_list>
<key>item_catalog_portal_type | catalog/portal_type/z_related_item_catalog</key>
<key>item_catalog_reference | catalog/reference/z_related_item_catalog</key>
<key>item_catalog_title | catalog/title/z_related_item_catalog</key>
<key>item_catalog_title | catalog_full_text/title/z_related_item_catalog</key>
<key>item_catalog_validation_state | catalog/validation_state/z_related_item_catalog</key>
</key_list>
\ No newline at end of file
item_catalog_title | catalog/title/z_related_item_catalog
item_catalog_title | catalog_full_text/title/z_related_item_catalog
item_catalog_portal_type | catalog/portal_type/z_related_item_catalog
item_catalog_reference | catalog/reference/z_related_item_catalog
item_catalog_validation_state | catalog/validation_state/z_related_item_catalog
\ No newline at end of file
......@@ -96,7 +96,7 @@
<tr>\n
<td>type</td>\n
<td>search_text</td>\n
<td>Pouet_NO_EXISTS</td>\n
<td>Poueet</td>\n
</tr>\n
<tr>\n
<td>clickAndWait</td>\n
......@@ -111,7 +111,7 @@
<tr>\n
<td>verifyValue</td>\n
<td>search_text</td>\n
<td>Pouet_NO_EXISTS</td>\n
<td>Poueet</td>\n
</tr>\n
<tr>\n
<td>type</td>\n
......
erp5_full_text_myisam_catalog
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
erp5_full_text_myisam_catalog
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
erp5_web
erp5_ingestion
......
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_simulation
erp5_configurator_standard_trade_template
erp5_simulation_test
......
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_ingestion_mysql_innodb_catalog
erp5_ingestion
\ No newline at end of file
erp5_full_text_myisam_catalog
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
erp5_full_text_myisam_catalog
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
......@@ -26,6 +26,7 @@
##############################################################################
from Products.ERP5.Document.ERP5ProjectUnitTestDistributor import ERP5ProjectUnitTestDistributor
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery
from zLOG import LOG,ERROR
from AccessControl import ClassSecurityInfo
......@@ -110,7 +111,10 @@ class ERP5ScalabilityDistributor(ERP5ProjectUnitTestDistributor):
tag = "%s_%s" % (self.getRelativeUrl(), title)
if portal.portal_activities.countMessageWithTag(tag) == 0:
test_node_list = test_node_module.searchFolder(portal_type="Test Node",title=title)
test_node_list = test_node_module.searchFolder(
portal_type="Test Node",
title=SimpleQuery(comparison_operator='=', title=title),
)
assert len(test_node_list) in (0, 1), "Unable to find testnode : %s" % title
test_node = None
if len(test_node_list) == 1:
......@@ -129,7 +133,8 @@ class ERP5ScalabilityDistributor(ERP5ProjectUnitTestDistributor):
isMasterTestnode : return True if the node given in parameter exists and is a validated master
"""
test_node_module = self._getTestNodeModule()
test_node_master = [ node for node in test_node_module.searchFolder(portal_type="Test Node", title=title,
test_node_master = [ node for node in test_node_module.searchFolder(portal_type="Test Node",
title=SimpleQuery(comparison_operator='=', title=title),
specialise_uid=self.getUid(),
validation_state="validated") if node.getMaster() == 1 ]
if len(test_node_master) == 1:
......
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
\ No newline at end of file
......@@ -41,7 +41,7 @@ class TestOxatisSynchronization(ERP5TypeTestCase):
""" Return the list of BT required by unit tests. """
return (
'erp5_core_proxy_field_legacy',
'erp5_full_text_myisam_catalog',
'erp5_full_text_mroonga_catalog',
'erp5_base',
'erp5_pdm',
'erp5_simulation',
......
......@@ -102,7 +102,7 @@
<tr>\n
<td>assertValue</td>\n
<td>listbox_title</td>\n
<td>"%1%" OR "%2%"</td>\n
<td>("%1%" OR "%2%")</td>\n
</tr>\n
<tr>\n
<td>clickAndWait</td>\n
......@@ -119,7 +119,7 @@
<tr>\n
<td>assertValue</td>\n
<td>listbox_title</td>\n
<td>"%1%" OR "%2%"</td>\n
<td>("%1%" OR "%2%")</td>\n
</tr>\n
\n
<tr>\n
......@@ -137,7 +137,7 @@
<tr>\n
<td>assertValue</td>\n
<td>listbox_title</td>\n
<td>"%1%" OR "%2%"</td>\n
<td>("%1%" OR "%2%")</td>\n
</tr>\n
\n
<tr>\n
......@@ -181,7 +181,7 @@
<tr>\n
<td>assertValue</td>\n
<td>listbox_title</td>\n
<td>"%1%" OR "%2%"</td>\n
<td>("%1%" OR "%2%")</td>\n
</tr>\n
\n
<tal:block tal:condition="python: context.TestTool_getSkinName()!=\'Mobile\'">\n
......@@ -213,7 +213,7 @@
<tr>\n
<td>assertValue</td>\n
<td>listbox_title</td>\n
<td>"%1%" OR "%2%"</td>\n
<td>("%1%" OR "%2%")</td>\n
</tr>\n
\n
<tr>\n
......
......@@ -78,7 +78,7 @@
<tr>\n
<td>type</td>\n
<td>field_my_foo_category_title</td>\n
<td>b</td>\n
<td>=b</td>\n
</tr>\n
<tr>\n
<td>type</td>\n
......
......@@ -126,7 +126,7 @@ metal:use-macro="here/RelationFieldZuite_CommonTemplate/macros/init"\n
<tr>\n
<td>type</td>\n
<td>listbox_title</td>\n
<td>a</td>\n
<td>=a</td>\n
</tr>\n
<tr>\n
<td>clickAndWait</td>\n
......@@ -135,7 +135,7 @@ metal:use-macro="here/RelationFieldZuite_CommonTemplate/macros/init"\n
</tr>\n
<tr>\n
<td>click</td>\n
<td>//*[@class=\'listbox-data-line-0 DataA\']//input[@type="checkbox"]</td>\n
<td>//tr//a[.="a"]/parent::td/preceding-sibling::td/input[@type="checkbox"]</td>\n
<td></td>\n
</tr>\n
<tr>\n
......
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
erp5_upgrader_test
\ No newline at end of file
......@@ -52,7 +52,7 @@
<key> <string>_body</string> </key>
<value> <string>template_tool = context\n
\n
return template_tool.upgradeSite((\'erp5_full_text_myisam_catalog\',),\n
return template_tool.upgradeSite((\'erp5_full_text_mroonga_catalog\',),\n
dry_run=(not fixit))\n
</string> </value>
</item>
......
erp5_full_text_myisam_catalog
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
erp5_jquery
erp5_ingestion_mysql_innodb_catalog
......
erp5_full_text_myisam_catalog
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
erp5_web
erp5_ingestion_mysql_innodb_catalog
......
erp5_ingestion_mysql_innodb_catalog
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
erp5_jquery
erp5_web
......
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_pdm
erp5_data_set
\ No newline at end of file
erp5_full_text_myisam_catalog
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
......@@ -37,7 +37,7 @@ import string
from zLOG import LOG,INFO,ERROR
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from Products.ZSQLCatalog.SQLCatalog import Query
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery
TEST_SUITE_MAX = 4
# Depending on the test suite priority, we will affect
# more or less cores
......@@ -210,7 +210,10 @@ class ERP5ProjectUnitTestDistributor(XMLObject):
tag = "%s_%s" % (self.getRelativeUrl(), title)
if portal.portal_activities.countMessageWithTag(tag) == 0:
test_node_list = test_node_module.searchFolder(portal_type="Test Node",title=title)
test_node_list = test_node_module.searchFolder(
portal_type="Test Node",
title=SimpleQuery(comparison_operator='=', title=title),
)
assert len(test_node_list) in (0, 1), "Unable to find testnode : %s" % title
test_node = None
if len(test_node_list) == 1:
......@@ -244,9 +247,11 @@ class ERP5ProjectUnitTestDistributor(XMLObject):
from_date = now - 30
def getTestSuiteSortKey(test_suite):
test_result = portal.portal_catalog(portal_type="Test Result",
title='="%s"' % test_suite.getTitle(),
modification_date=Query(**{"creation_date": from_date,
"range": "min"}),
title=SimpleQuery(title=test_suite.getTitle()),
creation_date=SimpleQuery(
creation_date=from_date,
comparison_operator='>=',
),
sort_on=[("modification_date", "descending")],
limit=1)
if len(test_result):
......@@ -304,7 +309,10 @@ class ERP5ProjectUnitTestDistributor(XMLObject):
config_list = []
tag = "%s_%s" % (self.getRelativeUrl(), title)
if portal.portal_activities.countMessageWithTag(tag) == 0:
test_node_list = test_node_module.searchFolder(portal_type="Test Node",title=title)
test_node_list = test_node_module.searchFolder(
portal_type="Test Node",
title=SimpleQuery(comparison_operator='=', title=title),
)
assert len(test_node_list) in (0, 1), "Unable to find testnode : %s" % title
test_node = None
if len(test_node_list) == 1:
......@@ -365,7 +373,9 @@ class ERP5ProjectUnitTestDistributor(XMLObject):
def _getTestNodeFromTitle(self, node_title):
test_node_list = self._getTestNodeModule().searchFolder(
portal_type='Test Node', title="='%s'" % node_title)
portal_type="Test Node",
title=SimpleQuery(comparison_operator='=', title=node_title),
)
assert len(test_node_list) == 1, "We found %i test nodes for %s" % (
len(test_node_list), node_title)
test_node = test_node_list[0].getObject()
......@@ -373,7 +383,9 @@ class ERP5ProjectUnitTestDistributor(XMLObject):
def _getTestSuiteFromTitle(self, suite_title):
test_suite_list = self._getTestSuiteModule().searchFolder(
portal_type='Test Suite', title="='%s'" % suit_tile, validation_state="validated")
portal_type='Test Suite',
title=SimpleQuery(comparison_operator='=', title=suite_title),
validation_state='validated')
assert len(test_suite_list) == 1, "We found %i test suite for %s" % (
len(test_suite_list), name)
test_suite = test_suite_list[0].getObject()
......
......@@ -30,6 +30,7 @@ import random
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint, interfaces
from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery
from zLOG import LOG
from xmlrpclib import Binary
......@@ -91,7 +92,7 @@ class TaskDistributionTool(BaseTool):
def createTestResultLineList(test_result, test_name_list):
duration_list = []
previous_test_result_list = portal.test_result_module.searchFolder(
title='="%s"' % test_result.getTitle(),
title=SimpleQuery(comparison_operator='=', title=test_result.getTitle()),
sort_on=[('creation_date','descending')],
simulation_state=('stopped', 'public_stopped'),
limit=1)
......@@ -126,7 +127,7 @@ class TaskDistributionTool(BaseTool):
int_index, reference = revision
result_list = portal.test_result_module.searchFolder(
portal_type="Test Result",
title='="%s"' % test_title,
title=SimpleQuery(comparison_operator='=', title=test_title),
sort_on=(("creation_date","descending"),),
limit=1)
if result_list:
......@@ -162,7 +163,7 @@ class TaskDistributionTool(BaseTool):
test_result._setIntIndex(int_index)
if project_title is not None:
project_list = portal.portal_catalog(portal_type='Project',
title='="%s"' % project_title)
title=SimpleQuery(comparison_operator='=', title=project_title))
if len(project_list) != 1:
raise ValueError('found this list of project : %r for title %r' % \
([x.path for x in project_list], project_title))
......
erp5_full_text_myisam_catalog
erp5_full_text_mroonga_catalog
erp5_base
\ No newline at end of file
......@@ -56,8 +56,12 @@ portal = context.getPortalObject()\n
# This scriptable key supports content_translation if the table is present\n
catalog = portal.portal_catalog.getSQLCatalog()\n
if \'content_translation\' in catalog.getProperty(\'sql_search_tables\'):\n
return AndQuery(SimpleQuery(**{\'content_translation.translated_text\': value, \'comparison_operator\': \'match\'}),\n
Query(**{\'content_translation.property_name\': \'title\'}))\n
if [x for x in catalog.getProperty(\'sql_catalog_search_keys\', []) if \'Mroonga\' in x]:\n
return AndQuery(SimpleQuery(**{\'content_translation.translated_text\': value, \'comparison_operator\': \'mroonga_boolean\'}),\n
Query(**{\'content_translation.property_name\': \'title\'}))\n
else:\n
return AndQuery(SimpleQuery(**{\'content_translation.translated_text\': value, \'comparison_operator\': \'match_boolean\'}),\n
Query(**{\'content_translation.property_name\': \'title\'}))\n
\n
# Otherwise it simply use title\n
return Query(title=value)\n
......
......@@ -82,7 +82,7 @@ class TestCRM(BaseTestCRM):
return "CRM"
def getBusinessTemplateList(self):
return ('erp5_full_text_myisam_catalog',
return ('erp5_full_text_mroonga_catalog',
'erp5_core_proxy_field_legacy',
'erp5_base',
'erp5_ingestion',
......@@ -571,7 +571,7 @@ class TestCRMMailIngestion(BaseTestCRM):
def getBusinessTemplateList(self):
# Mail Ingestion must work with CRM alone.
return ('erp5_core_proxy_field_legacy',
'erp5_full_text_myisam_catalog',
'erp5_full_text_mroonga_catalog',
'erp5_base',
'erp5_ingestion',
'erp5_ingestion_mysql_innodb_catalog',
......
......@@ -48,7 +48,7 @@ class TestERP5Coordinate(ERP5TypeTestCase):
Return the list of required business templates.
"""
return ('erp5_core_proxy_field_legacy',
'erp5_full_text_myisam_catalog',
'erp5_full_text_mroonga_catalog',
'erp5_base',)
def beforeTearDown(self):
......
......@@ -55,7 +55,7 @@ class TestERP5Credential(ERP5TypeTestCase):
def getBusinessTemplateList(self):
return (
'erp5_full_text_myisam_catalog',
'erp5_full_text_mroonga_catalog',
'erp5_core_proxy_field_legacy',
'erp5_base',
'erp5_jquery',
......
......@@ -63,7 +63,7 @@ class TestEgov(ERP5TypeTestCase):
def getBusinessTemplateList(self):
"""return list of business templates to be installed. """
bt_list = ['erp5_core_proxy_field_legacy',
'erp5_full_text_myisam_catalog',
'erp5_full_text_mroonga_catalog',
'erp5_base',
'erp5_web',
'erp5_ingestion_mysql_innodb_catalog',
......
......@@ -56,7 +56,7 @@ class TestZeleniumRunMyDocSample(ERP5TypeFunctionalTestCase):
"""
Return the list of business templates.
"""
return ('erp5_core_proxy_field_legacy', 'erp5_full_text_myisam_catalog',
return ('erp5_core_proxy_field_legacy', 'erp5_full_text_mroonga_catalog',
'erp5_base', 'erp5_ui_test_core','erp5_web', 'erp5_ingestion',
'erp5_accounting',
'erp5_jquery', 'erp5_dms', 'erp5_jquery_ui', 'erp5_web',
......
......@@ -43,21 +43,42 @@ class TestI18NSearch(ERP5TypeTestCase):
portal_type='Person',
first_name='Gabriel',
last_name='Fauré',
description='Quick brown fox jumps over the lazy dog.',
)
person2 = person_module.newContent(
portal_type='Person',
first_name='武者小路',
last_name='実篤'
last_name='実篤',
description='Slow white fox jumps over the diligent dog.',
)
self.tic()
# check if 'é' == 'e' collation works
result = person_module.searchFolder(SearchableText='Faure')
self.assertEqual(len(result), 1)
self.assertEqual(result[0].getPath(), person1.getPath())
result = person_module.searchFolder(title='Faure')
self.assertEqual(len(result), 1)
self.assertEqual(result[0].getPath(), person1.getPath())
# check if a partial string of CJK string matches
result = person_module.searchFolder(SearchableText='武者')
self.assertEqual(len(result), 1)
self.assertEqual(result[0].getPath(), person2.getPath())
result = person_module.searchFolder(title='武者')
self.assertEqual(len(result), 1)
self.assertEqual(result[0].getPath(), person2.getPath())
# check boolean language mode search
result = person_module.searchFolder(SearchableText='+quick +fox +dog')
self.assertEqual(len(result), 1)
self.assertEqual(result[0].getPath(), person1.getPath())
result = person_module.searchFolder(description='+quick +fox +dog')
self.assertEqual(len(result), 1)
self.assertEqual(result[0].getPath(), person1.getPath())
# check fulltext search for automatically generated related keys.
self.assertTrue('MATCH' in self.portal.portal_catalog(destination_title='Faure', src__=1))
def test_suite():
suite = unittest.TestSuite()
......
......@@ -50,7 +50,7 @@ class TestKMMixIn(TestDocumentMixin):
manager_password = ''
website_id = 'km_test'
business_template_list = ['erp5_core_proxy_field_legacy',
'erp5_full_text_myisam_catalog','erp5_base',
'erp5_full_text_mroonga_catalog','erp5_base',
'erp5_jquery', 'erp5_jquery_ui', 'erp5_knowledge_pad',
'erp5_ingestion_mysql_innodb_catalog', 'erp5_ingestion',
'erp5_web', 'erp5_dms',
......
......@@ -68,7 +68,7 @@ class TestSpellChecking(ERP5TypeTestCase):
return "Spell Checking Test"
def getBusinessTemplateList(self):
return ('erp5_full_text_myisam_catalog',
return ('erp5_full_text_mroonga_catalog',
'erp5_base',
'erp5_simulation',
'erp5_accounting',
......
......@@ -52,7 +52,7 @@ class TestTemplateTool(ERP5TypeTestCase):
def getBusinessTemplateList(self):
return ('erp5_core_proxy_field_legacy',
'erp5_full_text_myisam_catalog',
'erp5_full_text_mroonga_catalog',
'erp5_base',
'erp5_stock_cache',
'erp5_csv_style')
......@@ -650,7 +650,7 @@ class TestTemplateTool(ERP5TypeTestCase):
'erp5_core_proxy_field_legacy': first_group,
'erp5_mysql_innodb_catalog': first_group,
'erp5_core': first_group,
'erp5_full_text_myisam_catalog': first_group,
'erp5_full_text_mroonga_catalog': first_group,
'erp5_xhtml_style': first_group,
'erp5_ingestion_mysql_innodb_catalog': second_group,
'erp5_base': second_group,
......
......@@ -881,9 +881,10 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
by looking at the category tree.
For exemple it will generate:
destination_title | category,catalog/title/z_related_destination
default_destination_title | category,catalog/title/z_related_destination
strict_destination_title | category,catalog/title/z_related_strict_destination
destination_reference | category,catalog/reference/z_related_destination
default_destination_reference | category,catalog/reference/z_related_destination
strict_destination_reference | category,catalog/reference/z_related_strict_destination
destination_title | category,catalog_full_text/title/z_related_destination
strict_ related keys only returns documents which are strictly member of
the category.
......@@ -917,9 +918,18 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
if related:
end_key = end_key[len(related_string):]
# XXX: joining with non-catalog tables is not trivial and requires
# ZSQLCatalog's ColumnMapper cooperation, so only allow catalog
# columns.
if 'catalog' in column_map.get(end_key, ()):
# ZSQLCatalog's ColumnMapper cooperation, so only allow columns in
# catalog or catalog_full_text tables.
if end_key != 'uid' and 'catalog_full_text' in column_map.get(end_key, ()):
related_key_list.append(
prefix + key + ' | category,catalog_full_text/' +
end_key +
'/z_related_' +
('strict_' if strict else '') +
expected_base_cat_id +
('_related' if related else '')
)
elif 'catalog' in column_map.get(end_key, ()):
is_uid = end_key == 'uid'
if is_uid:
end_key = 'uid' if related else 'category_uid'
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment