/[public]/erp5/trunk/products/ERP5Catalog/Tool/ArchiveTool.py
ERP5 logo

Contents of /erp5/trunk/products/ERP5Catalog/Tool/ArchiveTool.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 45126 - (show annotations)
Wed Apr 6 09:54:23 2011 UTC (2 years, 1 month ago) by aurel
File MIME type: text/x-python
File size: 11607 byte(s)
manage_archive can take more argument as the research of currently
used connection might failed in some cases (no zsql method using a
deferred connection for example)

This should be replace later using a mapping between connection as parameter

1 ##############################################################################
2 #
3 # Copyright (c) 2007 Nexedi SARL and Contributors. All Rights Reserved.
4 # Aurelien Calonne <aurel@nexedi.com>
5 #
6 # WARNING: This program as such is intended to be used by professional
7 # programmers who take the whole responsability of assessing all potential
8 # consequences resulting from its eventual inadequacies and bugs
9 # End users who are looking for a ready-to-use solution with commercial
10 # garantees and support are strongly adviced to contract a Free Software
11 # Service Company
12 #
13 # This program is Free Software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; either version 2
16 # of the License, or (at your option) any later version.
17 #
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #
27 ##############################################################################
28
29
30 from AccessControl import ClassSecurityInfo
31 from Products.ERP5Type.Globals import InitializeClass, DTMLFile
32 from Products.ERP5Type.Tool.BaseTool import BaseTool
33 from Products.ERP5Type import Permissions
34 from Products.ERP5Type.Cache import CachingMethod, clearCache
35 from Products.ERP5Catalog import _dtmldir
36 from zLOG import LOG, INFO
37
38 class ArchiveTool(BaseTool):
39 """
40 Archive Tool contains archive objects
41 """
42 title = 'Archive Tool'
43 id = 'portal_archives'
44 meta_type = 'ERP5 Archive Tool'
45 portal_type = 'Archive Tool'
46 allowed_types = ('ERP5 Archive',)
47
48 # Declarative Security
49 security = ClassSecurityInfo()
50
51 security.declareProtected(Permissions.ManagePortal, 'manage_overview' )
52
53 manage_overview = DTMLFile( 'explainArchiveTool', _dtmldir)
54
55
56 def getSQLCatalogIdList(self):
57 """
58 Wrapper to CatalogTool method
59 """
60 return self.portal_catalog.getSQLCatalogIdList()
61
62 def SQLConnectionIDs(self):
63 """
64 Wrapper to CatalogTool method
65 """
66 return self.portal_catalog.SQLConnectionIDs()
67
68 def getArchiveIdList(self):
69 """
70 Return list of usable archive displayed to user
71 """
72 return ["%s - %s" %(x.getId(), x.getTitle()) for x in \
73 self.portal_catalog(portal_type="Archive",
74 validation_state="ready")]
75
76
77 def getCurrentArchive(self):
78 """
79 Return the archive used for the current catalog
80 """
81 current_catalog = self.portal_catalog.default_sql_catalog_id
82 current_archive_list = [x.getObject() for x in self.searchFolder(validation_state="validated") \
83 if x.getCatalogId() == current_catalog]
84 if len(current_archive_list) == 0:
85 return None
86 else:
87 return current_archive_list[0]
88
89
90 def getArchiveList(self):
91 """
92 Return the list of archive use by catalog
93 """
94 def _getArchiveList():
95 return [x.getPath() for x in self.objectValues() if x.getValidationState() == "validated"]
96
97 # getArchiveList = CachingMethod(_getArchiveList,
98 # id='getArchiveList',
99 # cache_factory='erp5_content_short')
100
101 return _getArchiveList()
102
103
104 def manage_archive(self, destination_archive_id,
105 archive_id,
106 source_connection_id=None,
107 source_deferred_connection_id=None,
108 update_destination_sql_catalog=None,
109 update_archive_sql_catalog=None,
110 clear_destination_sql_catalog=None,
111 clear_archive_sql_catalog=None,
112 REQUEST=None, RESPONSE=None):
113 """
114 This method is used to populate an archive from the current catalog
115 It is base on hot reindexing, we start from a current catalog
116 in order to create a new current catalog plus an archive catalog.
117 Archives are defined in portal_archives, they are predicate thus
118 we use test method to know in which catalog objects must go.
119 At the end it creates inventories in order to have
120 consistent data within the new catalog
121 """
122 # First check parameter for destination catalog
123 if destination_archive_id == archive_id:
124 raise ValueError, "Archive and destination archive can't be the same"
125 portal_catalog =self.portal_catalog
126 # Guess connection id from current catalog
127 source_catalog = portal_catalog.getSQLCatalog()
128 source_catalog_id = source_catalog.getId()
129 if source_connection_id is None or source_deferred_connection_id is None:
130 for method in source_catalog.objectValues():
131 if method.meta_type == "Z SQL Method":
132 if source_deferred_connection_id is None and 'deferred' in method.connection_id:
133 source_deferred_connection_id = method.connection_id
134 elif source_connection_id is None and 'transactionless' not in method.connection_id:
135 source_connection_id = method.connection_id
136 if source_connection_id is not None and \
137 source_deferred_connection_id is not None:
138 break
139
140 if source_connection_id is None or source_deferred_connection_id is None:
141 raise ValueError, "Unable to determine connection id for the current catalog"
142
143 # Get destination property from archive
144 destination_archive_id = destination_archive_id.split(' - ')[0]
145 destination_archive = self._getOb(destination_archive_id)
146 destination_sql_catalog_id = destination_archive.getCatalogId()
147 destination_connection_id = destination_archive.getConnectionId()
148 destination_deferred_connection_id = destination_archive.getDeferredConnectionId()
149
150 # Get archive property from archive
151 archive_id = archive_id.split(' - ')[0]
152 archive = self._getOb(archive_id)
153 archive_sql_catalog_id = archive.getCatalogId()
154 archive_connection_id = archive.getConnectionId()
155 archive_deferred_connection_id = archive.getDeferredConnectionId()
156
157 # Check we don't use same connection id for source and destination
158 if destination_sql_catalog_id == source_catalog_id:
159 raise ValueError, "Destination and source catalog can't be the same"
160 if destination_connection_id == source_connection_id:
161 raise ValueError, "Destination and source connection can't be the same"
162 if destination_deferred_connection_id == source_deferred_connection_id:
163 raise ValueError, "Destination and source deferred connection can't be the same"
164 # Same for source and archive
165 if archive_sql_catalog_id == source_catalog_id:
166 raise ValueError, "Archive and source catalog can't be the same"
167 if archive_connection_id == source_connection_id:
168 raise ValueError, "Archive and source connection can't be the same"
169 if archive_deferred_connection_id == source_deferred_connection_id:
170 raise ValueError, "Archive and source deferred connection can't be the same"
171 # Same for destination and archive
172 if archive_sql_catalog_id == destination_sql_catalog_id:
173 raise ValueError, "Archive and destination catalog can't be the same"
174 if archive_connection_id == destination_connection_id:
175 raise ValueError, "Archive and destination connection can't be the same"
176 if archive_deferred_connection_id == destination_deferred_connection_id:
177 raise ValueError, "Archive and destination deferred connection can't be the same"
178
179 # Update connection id in destination and archive catalog if asked
180 destination_sql_catalog = getattr(portal_catalog, destination_sql_catalog_id)
181 if update_destination_sql_catalog:
182 sql_connection_id_dict = {source_connection_id : destination_connection_id,
183 source_deferred_connection_id : destination_deferred_connection_id}
184 portal_catalog.changeSQLConnectionIds(destination_sql_catalog,
185 sql_connection_id_dict)
186
187 archive_sql_catalog = getattr(portal_catalog, archive_sql_catalog_id)
188 if update_archive_sql_catalog:
189 sql_connection_id_dict = {source_connection_id : archive_connection_id,
190 source_deferred_connection_id : archive_deferred_connection_id}
191 portal_catalog.changeSQLConnectionIds(archive_sql_catalog,
192 sql_connection_id_dict)
193
194 # Clear destination and archive catalog if asked
195 if clear_destination_sql_catalog:
196 portal_catalog.manage_catalogClear(sql_catalog_id=destination_sql_catalog_id)
197 if clear_archive_sql_catalog:
198 portal_catalog.manage_catalogClear(sql_catalog_id=archive_sql_catalog_id)
199
200 # validate archive
201 archive.validate()
202 destination_archive.validate()
203
204 # Call hot reindexing
205 portal_catalog.manage_hotReindexAll(source_sql_catalog_id=source_catalog_id,
206 destination_sql_catalog_id=destination_sql_catalog_id,
207 archive_path=archive.getPath(),
208 source_sql_connection_id_list=[source_connection_id, \
209 source_deferred_connection_id],
210 destination_sql_connection_id_list=[destination_connection_id, \
211 destination_deferred_connection_id],
212 REQUEST=REQUEST, RESPONSE=RESPONSE)
213
214 # Create inventory just before finish of hot reindexing
215 inventory_date = archive.getStopDateRangeMax()
216 self.activate(passive_commit=1,
217 after_method_id=('playBackRecordedObjectList'),
218 priority=5).runInventoryMethod(archive.id,
219 source_connection_id,
220 destination_sql_catalog_id,
221 inventory_date
222 )
223
224
225 self.activate(passive_commit=1,
226 after_method_id=('runInventoryMethod'),
227 after_tag="runInventoryMethod",
228 priority=5).InventoryModule_reindexMovementList(sql_catalog_id=destination_sql_catalog_id,
229 final_activity_tag="InventoryModule_reindexMovementList"
230 )
231
232 if RESPONSE is not None:
233 URL1 = REQUEST.get('URL1')
234 RESPONSE.redirect(URL1 + '/portal_archives?portal_status_message=Archiving%20Started')
235
236
237 def runInventoryMethod(self, archive_id, source_connection_id,
238 destination_sql_catalog_id, inventory_date):
239 """
240 Use a specific method to create inventory in order to use
241 activity to execute it
242 """
243 archive = self._getOb(archive_id)
244 inventory_method_id = archive.getInventoryMethodId()
245 inventory_method = getattr(archive, inventory_method_id, None)
246 if inventory_method is not None:
247 inventory_method(source_connection_id, destination_sql_catalog_id,
248 inventory_date, tag='runInventoryMethod')
249
250
251 InitializeClass(ArchiveTool)

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.2