Commit 03466c6e authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

support cataloging multiple subjects.

* calculate unique subject_set_uid in ZSQLCatalog.SQLCatalog.
* move subject related tables from erp5_ingestion_mysql_innodb_catalog BT to erp5_mysql_innodb_catalog BT.
* add subject_uid column in versioning table.
* now TestDocument.test_DocumentIndexation (testDms) should pass.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@40057 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent fae4cb4d
<catalog_method>
<item key="sql_uncatalog_object" type="int">
<value>1</value>
</item>
<item key="_is_filtered_archive" type="int">
<value>1</value>
</item>
<item key="_filter_expression_archive" type="str">
<value>python: context.isDocument()</value>
</item>
<item key="_filter_expression_cache_key_archive" type="tuple">
<value>portal_type</value>
</item>
</catalog_method>
<key_list>
<key>email</key>
<key>subject</key>
</key_list>
\ No newline at end of file
2010-11-08 Kazuhiko
* subject related tables are moved to erp5_mysql_innodb_catalog.
2009-04-18 Kazuhiko
* Version 5.4.1
......
24
\ No newline at end of file
25
\ No newline at end of file
erp5_mysql_innodb/z0_drop_email
erp5_mysql_innodb/z0_drop_subject
erp5_mysql_innodb/z0_uncatalog_email
erp5_mysql_innodb/z0_uncatalog_subject
erp5_mysql_innodb/z_catalog_email_list
erp5_mysql_innodb/z_catalog_subject_list
erp5_mysql_innodb/z_create_email
erp5_mysql_innodb/z_create_subject
\ No newline at end of file
erp5_mysql_innodb/z_create_email
\ No newline at end of file
email
subject
\ No newline at end of file
email
\ No newline at end of file
......@@ -2,10 +2,7 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
<tuple/>
</tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
......
......@@ -6,7 +6,7 @@
<value>1</value>
</item>
<item key="_filter_expression_archive" type="str">
<value>python: context.isDocument()</value>
<value>python: getattr(context, 'getVersion', None) is not None</value>
</item>
<item key="_filter_expression_cache_key_archive" type="tuple">
<value>portal_type</value>
......
......@@ -2,10 +2,7 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
<tuple/>
</tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
......@@ -24,19 +21,13 @@
<value>
<dictionary>
<item>
<key> <string>getSubjectList</string> </key>
<key> <string>optimised_subject_list</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>isDocument</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>uid</string> </key>
<key> <string>subject_set_uid</string> </key>
<value>
<dictionary/>
</value>
......@@ -48,9 +39,8 @@
<key> <string>_keys</string> </key>
<value>
<list>
<string>getSubjectList</string>
<string>isDocument</string>
<string>uid</string>
<string>subject_set_uid</string>
<string>optimised_subject_list</string>
</list>
</value>
</item>
......@@ -67,9 +57,8 @@
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>getSubjectList\r\n
isDocument\r\n
uid</string> </value>
<value> <string>subject_set_uid\r\n
optimised_subject_list</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
......@@ -109,20 +98,25 @@ uid</string> </value>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
REPLACE INTO subject VALUES \n
<dtml-in prefix="loop" expr="_.range(_.len(uid))">\n
<dtml-if sequence-start><dtml-else>,</dtml-if>\n
<dtml-let subject="getSubjectList[loop_item]">\n
<dtml-if subject>\n
<dtml-in prefix="word" expr="subject">\n
<dtml-if sequence-start><dtml-else>,</dtml-if>\n
(<dtml-sqlvar "uid[loop_item]" type="int">, <dtml-sqlvar word_item type="string">)\n
<dtml-let row_list="[]">\n
<dtml-in prefix="loop" expr="_.range(_.len(subject_set_uid))">\n
<dtml-if expr="optimised_subject_list[loop_item]">\n
<dtml-in prefix="role" expr="optimised_subject_list[loop_item]">\n
<dtml-call expr="row_list.append([subject_set_uid[loop_item], role_item])">\n
</dtml-in>\n
<dtml-else>\n
(<dtml-sqlvar "uid[loop_item]" type="int">, NULL)\n
</dtml-if>\n
</dtml-let>\n
</dtml-in>\n
</dtml-in>\n
<dtml-if expr="row_list">\n
INSERT INTO\n
subject\n
(`subject_set_uid`, `subject`)\n
VALUES\n
<dtml-in prefix="row" expr="row_list">\n
(<dtml-sqlvar expr="row_item[0]" type="string">, <dtml-sqlvar expr="row_item[1]" type="string">)\n
<dtml-if sequence-end><dtml-else>,</dtml-if>\n
</dtml-in>\n
</dtml-if>\n
</dtml-let>\n
]]></string> </value>
......@@ -163,20 +157,25 @@ REPLACE INTO subject VALUES \n
<key> <string>raw</string> </key>
<value> <string encoding="cdata"><![CDATA[
REPLACE INTO subject VALUES \n
<dtml-in prefix="loop" expr="_.range(_.len(uid))">\n
<dtml-if sequence-start><dtml-else>,</dtml-if>\n
<dtml-let subject="getSubjectList[loop_item]">\n
<dtml-if subject>\n
<dtml-in prefix="word" expr="subject">\n
<dtml-if sequence-start><dtml-else>,</dtml-if>\n
(<dtml-sqlvar "uid[loop_item]" type="int">, <dtml-sqlvar word_item type="string">)\n
<dtml-let row_list="[]">\n
<dtml-in prefix="loop" expr="_.range(_.len(subject_set_uid))">\n
<dtml-if expr="optimised_subject_list[loop_item]">\n
<dtml-in prefix="role" expr="optimised_subject_list[loop_item]">\n
<dtml-call expr="row_list.append([subject_set_uid[loop_item], role_item])">\n
</dtml-in>\n
<dtml-else>\n
(<dtml-sqlvar "uid[loop_item]" type="int">, NULL)\n
</dtml-if>\n
</dtml-let>\n
</dtml-in>\n
</dtml-in>\n
<dtml-if expr="row_list">\n
INSERT INTO\n
subject\n
(`subject_set_uid`, `subject`)\n
VALUES\n
<dtml-in prefix="row" expr="row_list">\n
(<dtml-sqlvar expr="row_item[0]" type="string">, <dtml-sqlvar expr="row_item[1]" type="string">)\n
<dtml-if sequence-end><dtml-else>,</dtml-if>\n
</dtml-in>\n
</dtml-if>\n
</dtml-let>\n
]]></string> </value>
......
......@@ -62,6 +62,12 @@
<dictionary/>
</value>
</item>
<item>
<key> <string>subject_set_uid</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>uid</string> </key>
<value>
......@@ -79,6 +85,7 @@
<string>getLanguage</string>
<string>getVersion</string>
<string>getRevision</string>
<string>subject_set_uid</string>
<string>getEffectiveDate</string>
<string>getExpirationDate</string>
<string>getCreationDateIndex</string>
......@@ -109,10 +116,12 @@
getLanguage\r\n
getVersion\r\n
getRevision\r\n
subject_set_uid\r\n
getEffectiveDate\r\n
getExpirationDate\r\n
getCreationDateIndex\r\n
getFrequencyIndex</string> </value>
getFrequencyIndex\r\n
</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
......@@ -154,6 +163,8 @@ getFrequencyIndex</string> </value>
REPLACE INTO\n
versioning\n
(`uid`, `version`, `language`, `revision`, `subject_set_uid`, `effective_date`,\n
`expiration_date`, `creation_date_index`, `frequency_index`)\n
VALUES\n
<dtml-in prefix="loop" expr="_.range(_.len(uid))">\n
(\n
......@@ -161,6 +172,7 @@ VALUES\n
<dtml-sqlvar expr="getVersion[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getLanguage[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getRevision[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="subject_set_uid[loop_item]" type="int" optional>,\n
<dtml-sqlvar expr="getEffectiveDate[loop_item]" type="datetime" optional>,\n
<dtml-sqlvar expr="getExpirationDate[loop_item]" type="datetime" optional>,\n
<dtml-sqlvar expr="getCreationDateIndex[loop_item]" type="int" optional>,\n
......@@ -213,6 +225,8 @@ VALUES\n
REPLACE INTO\n
versioning\n
(`uid`, `version`, `language`, `revision`, `subject_set_uid`, `effective_date`,\n
`expiration_date`, `creation_date_index`, `frequency_index`)\n
VALUES\n
<dtml-in prefix="loop" expr="_.range(_.len(uid))">\n
(\n
......@@ -220,6 +234,7 @@ VALUES\n
<dtml-sqlvar expr="getVersion[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getLanguage[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getRevision[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="subject_set_uid[loop_item]" type="int" optional>,\n
<dtml-sqlvar expr="getEffectiveDate[loop_item]" type="datetime" optional>,\n
<dtml-sqlvar expr="getExpirationDate[loop_item]" type="datetime" optional>,\n
<dtml-sqlvar expr="getCreationDateIndex[loop_item]" type="int" optional>,\n
......
......@@ -2,10 +2,7 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
<tuple/>
</tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
......@@ -83,9 +80,9 @@
<item>
<key> <string>src</string> </key>
<value> <string>CREATE TABLE subject (\n
uid BIGINT UNSIGNED NOT NULL,\n
subject_set_uid INT UNSIGNED NOT NULL,\n
subject VARCHAR(255),\n
PRIMARY KEY `uid` (`uid`),\n
KEY `subject_set_uid` (`subject_set_uid`),\n
KEY `subject` (`subject`)\n
) TYPE=InnoDB; \n
</string> </value>
......@@ -125,9 +122,9 @@
<item>
<key> <string>raw</string> </key>
<value> <string>CREATE TABLE subject (\n
uid BIGINT UNSIGNED NOT NULL,\n
subject_set_uid INT UNSIGNED NOT NULL,\n
subject VARCHAR(255),\n
PRIMARY KEY `uid` (`uid`),\n
KEY `subject_set_uid` (`subject_set_uid`),\n
KEY `subject` (`subject`)\n
) TYPE=InnoDB; \n
</string> </value>
......
......@@ -58,13 +58,15 @@
`version` varchar(10) default \'\',\n
`language` varchar(5) default \'\',\n
`revision` varchar(10) default \'\',\n
`subject_set_uid` INT UNSIGNED,\n
`effective_date` datetime default NULL,\n
`expiration_date` datetime default NULL,\n
`creation_date_index` INT, \n
`frequency_index` INT, \n
`creation_date_index` INT,\n
`frequency_index` INT,\n
PRIMARY KEY (`uid`),\n
KEY `version` (`version`),\n
KEY `language` (`language`),\n
KEY `subject_set_uid` (`subject_set_uid`),\n
KEY `effective_date` (`effective_date`),\n
KEY `expiration_date` (`effective_date`),\n
KEY `frequency_index` (`creation_date_index`, `frequency_index`)\n
......@@ -110,13 +112,15 @@
`version` varchar(10) default \'\',\n
`language` varchar(5) default \'\',\n
`revision` varchar(10) default \'\',\n
`subject_set_uid` INT UNSIGNED,\n
`effective_date` datetime default NULL,\n
`expiration_date` datetime default NULL,\n
`creation_date_index` INT, \n
`frequency_index` INT, \n
`creation_date_index` INT,\n
`frequency_index` INT,\n
PRIMARY KEY (`uid`),\n
KEY `version` (`version`),\n
KEY `language` (`language`),\n
KEY `subject_set_uid` (`subject_set_uid`),\n
KEY `effective_date` (`effective_date`),\n
KEY `expiration_date` (`effective_date`),\n
KEY `frequency_index` (`creation_date_index`, `frequency_index`)\n
......
......@@ -2,10 +2,7 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
<tuple/>
</tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
......@@ -24,13 +21,13 @@
<value>
<dictionary>
<item>
<key> <string>isDocument</string> </key>
<key> <string>table_0</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>uid</string> </key>
<key> <string>table_1</string> </key>
<value>
<dictionary/>
</value>
......@@ -42,8 +39,8 @@
<key> <string>_keys</string> </key>
<value>
<list>
<string>uid</string>
<string>isDocument</string>
<string>table_0</string>
<string>table_1</string>
</list>
</value>
</item>
......@@ -60,8 +57,8 @@
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>uid\r\n
isDocument</string> </value>
<value> <string>table_0\r\n
table_1</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
......@@ -87,7 +84,7 @@ isDocument</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z0_uncatalog_subject</string> </value>
<value> <string>z_related_subject</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
......@@ -101,7 +98,8 @@ isDocument</string> </value>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
DELETE FROM subject WHERE <dtml-sqltest uid op=eq type=int>
<dtml-var table_0>.uid = catalog.uid AND\n
<dtml-var table_0>.subject_set_uid = <dtml-var table_1>.subject_set_uid
]]></string> </value>
</item>
......@@ -141,7 +139,8 @@ DELETE FROM subject WHERE <dtml-sqltest uid op=eq type=int>
<key> <string>raw</string> </key>
<value> <string encoding="cdata"><![CDATA[
DELETE FROM subject WHERE <dtml-sqltest uid op=eq type=int>
<dtml-var table_0>.uid = catalog.uid AND\n
<dtml-var table_0>.subject_set_uid = <dtml-var table_1>.subject_set_uid
]]></string> </value>
</item>
......
......@@ -46,6 +46,7 @@
<key>stock_resource_category_uid | category/category_uid/z_related_resource_uid_from_stock</key>
<key>stock_section_category_strict_membership_uid | category/category_uid/z_related_strict_membership_section_uid_from_stock</key>
<key>stock_section_category_uid | category/category_uid/z_related_section_uid_from_stock</key>
<key>subject | versioning,subject/subject/z_related_subject</key>
<key>translated_causality_state | translation/translated_message/z_related_translated_causality_state</key>
<key>translated_causality_state_title | translation/translated_message/z_related_translated_causality_state_title</key>
<key>translated_opportunity_state | translation/translated_message/z_related_translated_opportunity_state</key>
......
......@@ -12,5 +12,6 @@
<key>predicate_category</key>
<key>roles_and_users</key>
<key>stock</key>
<key>subject</key>
<key>versioning</key>
</key_list>
\ No newline at end of file
2010-11-08 Kazuhiko
* support cataloging multiple subjects.
* subject related tables are moved from erp5_ingestion_mysql_innodb_catalog.
2010-11-05 Kazuhiko
* remove 'z_related_security' method and 'allowedRolesAndUsers' related key, that are not used because of the conflict with existing 'allowedRolesAndUsers' column.
......
208
\ No newline at end of file
209
\ No newline at end of file
......@@ -17,6 +17,7 @@ erp5_mysql_innodb/z0_drop_quantity_unit_conversion
erp5_mysql_innodb/z0_drop_record
erp5_mysql_innodb/z0_drop_roles_and_users
erp5_mysql_innodb/z0_drop_stock
erp5_mysql_innodb/z0_drop_subject
erp5_mysql_innodb/z0_drop_transformation
erp5_mysql_innodb/z0_drop_translation
erp5_mysql_innodb/z0_drop_versioning
......@@ -51,6 +52,7 @@ erp5_mysql_innodb/z_catalog_predicate_list
erp5_mysql_innodb/z_catalog_quantity_unit_conversion_list
erp5_mysql_innodb/z_catalog_roles_and_users_list
erp5_mysql_innodb/z_catalog_stock_list
erp5_mysql_innodb/z_catalog_subject_list
erp5_mysql_innodb/z_catalog_transformation_list
erp5_mysql_innodb/z_catalog_translation_list
erp5_mysql_innodb/z_catalog_versioning_list
......@@ -72,6 +74,7 @@ erp5_mysql_innodb/z_create_quantity_unit_conversion
erp5_mysql_innodb/z_create_record
erp5_mysql_innodb/z_create_roles_and_users
erp5_mysql_innodb/z_create_stock
erp5_mysql_innodb/z_create_subject
erp5_mysql_innodb/z_create_transformation
erp5_mysql_innodb/z_create_translation
erp5_mysql_innodb/z_create_versioning
......@@ -114,6 +117,7 @@ erp5_mysql_innodb/z_related_strict_membership_payment_uid_from_stock
erp5_mysql_innodb/z_related_strict_membership_project_uid_from_stock
erp5_mysql_innodb/z_related_strict_membership_resource_uid_from_stock
erp5_mysql_innodb/z_related_strict_membership_section_uid_from_stock
erp5_mysql_innodb/z_related_subject
erp5_mysql_innodb/z_related_translated_causality_state
erp5_mysql_innodb/z_related_translated_causality_state_title
erp5_mysql_innodb/z_related_translated_opportunity_state
......
item_resource_category_uid | category/category_uid/z_related_resource_uid_from_item
stock_section_category_strict_membership_uid | category/category_uid/z_related_strict_membership_section_uid_from_stock
subject | versioning,subject/subject/z_related_subject
predicate_uid | predicate/uid/z_related_predicate
translated_opportunity_state | translation/translated_message/z_related_translated_opportunity_state
translated_opportunity_state_title | translation/translated_message/z_related_translated_opportunity_state_title
......
......@@ -11,4 +11,5 @@ predicate
predicate_category
roles_and_users
stock
subject
versioning
\ No newline at end of file
......@@ -745,6 +745,9 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
if predicate_property_dict is not None:
w.predicate_property_dict = predicate_property_dict
w.security_uid = security_uid
(subject_set_uid, optimised_subject_list) = catalog.getSubjectSetUid(document_w)
w.optimised_subject_list = optimised_subject_list
w.subject_set_uid = subject_set_uid
return ImplicitAcquisitionWrapper(w, aq_parent(document_object))
......
......@@ -2194,7 +2194,6 @@ return 1
self.assertEquals('test-en-003-title', document.getTitle())
self.assertEquals('test-en-003-keywords', document.getSubject())
@expectedFailure
def test_DocumentIndexation(self):
"""
Test how a document is being indexed in MySQL.
......@@ -2212,10 +2211,11 @@ return 1
self.assertTrue(document.getReference() in full_text_result[0]['searchabletext'])
# subject indexation
subject_result = portal.erp5_sql_connection.manage_test('select * from subject where uid="%s"' %document.getUid())
self.assertTrue('subject2' in subject_result[0]['subject'])
self.assertTrue('subject1' in subject_result[0]['subject'])
for subject_list in (['subject1',], ['subject2',],
['subject1', 'subject2',],):
subject_result = portal.portal_catalog(subject=subject_list)
self.assertEquals(len(subject_result), 1)
self.assertEquals(subject_result[0].getPath(), document.getPath())
class TestDocumentWithSecurity(TestDocumentMixin):
......
......@@ -759,6 +759,10 @@ class Catalog(Folder,
self.security_uid_dict = OIBTree()
self.security_uid_index = None
def _clearSubjectCache(self):
self.subject_set_uid_dict = OIBTree()
self.subject_set_uid_index = None
security.declarePrivate('getSecurityUid')
def getSecurityUid(self, wrapped_object):
"""
......@@ -826,6 +830,49 @@ class Catalog(Folder,
extend([(role, security_uid) for role in role_list])
return result
security.declarePrivate('getSubjectSetUid')
def getSubjectSetUid(self, wrapped_object):
"""
Cache a uid for each unique subject tuple.
Return a tuple with a subject uid (string) and a new subject tuple
if not exist already.
"""
getSubjectList = getattr(wrapped_object, 'getSubjectList', None)
if getSubjectList is None:
return (None, None)
# Get subject information
# XXX if more collation is available, we can have smaller number of
# unique subject sets.
subject_list = tuple(sorted(set([(x or '').lower() for x in getSubjectList()])))
if not subject_list:
return (None, None)
# Make sure no duplicates
if getattr(aq_base(self), 'subject_set_uid_dict', None) is None:
self._clearSubjectCache()
elif self.subject_set_uid_dict.has_key(subject_list):
return (self.subject_set_uid_dict[subject_list], None)
# If the id_tool is there, it is better to use it, it allows
# to create many new subject uids by the same time
# because with this tool we are sure that we will have 2 different
# uids if two instances are doing this code in the same time
id_tool = getattr(self.getPortalObject(), 'portal_ids', None)
if id_tool is not None:
default = 1
# We must keep compatibility with existing sites
previous_subject_set_uid = getattr(self, 'subject_set_uid_index', None)
if previous_subject_set_uid is not None:
default = previous_subject_set_uid
subject_set_uid = int(id_tool.generateNewId(id_generator='uid',
id_group='subject_set_uid_index', default=default))
else:
previous_subject_set_uid = getattr(self, 'subject_set_uid_index', None)
if previous_subject_set_uid is None:
previous_subject_set_uid = 0
subject_set_uid = previous_subject_set_uid + 1
self.subject_set_uid_index = subject_set_uid
self.subject_set_uid_dict[subject_list] = subject_set_uid
return (subject_set_uid, subject_list)
def clear(self):
"""
Clears the catalog by calling a list of methods
......@@ -851,6 +898,7 @@ class Catalog(Folder,
self.insertMaxUid()
self._clearSecurityCache()
self._clearSubjectCache()
self._clearCaches()
def insertMaxUid(self):
......
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