/[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 16126 - (show annotations)
Thu Sep 6 15:14:50 2007 UTC (5 years, 8 months ago) by aurel
File MIME type: text/x-python
File size: 10487 byte(s)
initial upload of archive tool
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 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 def getSQLCatalogIdList(self):
56 """
57 Wrapper to CatalogTool method
58 """
59 return self.portal_catalog.getSQLCatalogIdList()
60
61 def SQLConnectionIDs(self):
62 """
63 Wrapper to CatalogTool method
64 """
65 return self.portal_catalog.SQLConnectionIDs()
66
67 def getArchiveIdList(self):
68 """
69 Return list of usable archive displayed to user
70 """
71 return ["%s - %s" %(x.getId(), x.getTitle()) for x in \
72 self.portal_catalog(portal_type="Archive",
73 validation_state="ready")]
74
75
76 def getArchiveList(self):
77 """
78 Return the list of archive use by catalog
79 """
80 def _getArchiveList():
81 return [x.getPath() for x in self.objectValues() if x.getValidationState() == "validated"]
82
83 # getArchiveList = CachingMethod(_getArchiveList,
84 # id='getArchiveList',
85 # cache_factory='erp5_content_short')
86
87 return _getArchiveList()
88
89
90 def manage_archive(self, destination_archive_id,
91 archive_id,
92 update_destination_sql_catalog=None,
93 update_archive_sql_catalog=None,
94 clear_destination_sql_catalog=None,
95 clear_archive_sql_catalog=None,
96 REQUEST=None, RESPONSE=None):
97 """
98 This method is used to populate an archive from the current catalog
99 It is base on hot reindexing, we start from a current catalog
100 in order to create a new current catalog plus an archive catalog.
101 Archives are defined in portal_archives, they are predicate thus
102 we use test method to know in which catalog objects must go.
103 At the end it creates inventories in order to have
104 consistent data within the new catalog
105 """
106 # First check parameter for destination catalog
107 if destination_archive_id == archive_id:
108 raise ValueError, "Archive and destination archive can't be the same"
109 portal_catalog =self.portal_catalog
110 # Guess connection id from current catalog
111 source_catalog = portal_catalog.getSQLCatalog()
112 source_catalog_id = source_catalog.getId()
113 source_connection_id = None
114 source_deferred_connection_id = None
115 for method in source_catalog.objectValues():
116 if method.meta_type == "Z SQL Method":
117 if 'deferred' in method.connection_id:
118 source_deferred_connection_id = method.connection_id
119 elif 'transactionless' not in method.connection_id:
120 source_connection_id = method.connection_id
121 if source_connection_id is not None and \
122 source_deferred_connection_id is not None:
123 break
124
125 if source_connection_id is None or source_deferred_connection_id is None:
126 raise ValueError, "Unable to determine connection id for the current catalog"
127
128 # Get destination property from archive
129 destination_archive_id = destination_archive_id.split(' - ')[0]
130 destination_archive = self._getOb(destination_archive_id)
131 destination_sql_catalog_id = destination_archive.getCatalogId()
132 destination_connection_id = destination_archive.getConnectionId()
133 destination_deferred_connection_id = destination_archive.getDeferredConnectionId()
134
135 # Get archive property from archive
136 archive_id = archive_id.split(' - ')[0]
137 archive = self._getOb(archive_id)
138 archive_sql_catalog_id = archive.getCatalogId()
139 archive_connection_id = archive.getConnectionId()
140 archive_deferred_connection_id = archive.getDeferredConnectionId()
141
142 # Check we don't use same connection id for source and destination
143 if destination_sql_catalog_id == source_catalog_id:
144 raise ValueError, "Destination and source catalog can't be the same"
145 if destination_connection_id == source_connection_id:
146 raise ValueError, "Destination and source connection can't be the same"
147 if destination_deferred_connection_id == source_deferred_connection_id:
148 raise ValueError, "Destination and source deferred connection can't be the same"
149 # Same for source and archive
150 if archive_sql_catalog_id == source_catalog_id:
151 raise ValueError, "Archive and source catalog can't be the same"
152 if archive_connection_id == source_connection_id:
153 raise ValueError, "Archive and source connection can't be the same"
154 if archive_deferred_connection_id == source_deferred_connection_id:
155 raise ValueError, "Archive and source deferred connection can't be the same"
156 # Same for destination and archive
157 if archive_sql_catalog_id == destination_sql_catalog_id:
158 raise ValueError, "Archive and destination catalog can't be the same"
159 if archive_connection_id == destination_connection_id:
160 raise ValueError, "Archive and destination connection can't be the same"
161 if archive_deferred_connection_id == destination_deferred_connection_id:
162 raise ValueError, "Archive and destination deferred connection can't be the same"
163
164 # Update connection id in destination and archive catalog if asked
165 destination_sql_catalog = getattr(portal_catalog, destination_sql_catalog_id)
166 if update_destination_sql_catalog:
167 sql_connection_id_dict = {source_connection_id : destination_connection_id,
168 source_deferred_connection_id : destination_deferred_connection_id}
169 portal_catalog.changeSQLConnectionIds(destination_sql_catalog,
170 sql_connection_id_dict)
171
172 archive_sql_catalog = getattr(portal_catalog, archive_sql_catalog_id)
173 if update_archive_sql_catalog:
174 sql_connection_id_dict = {source_connection_id : archive_connection_id,
175 source_deferred_connection_id : archive_deferred_connection_id}
176 portal_catalog.changeSQLConnectionIds(archive_sql_catalog,
177 sql_connection_id_dict)
178
179 # Clear destination and archive catalog if asked
180 if clear_destination_sql_catalog:
181 portal_catalog.manage_catalogClear(sql_catalog_id=destination_sql_catalog_id)
182 if clear_archive_sql_catalog:
183 portal_catalog.manage_catalogClear(sql_catalog_id=archive_sql_catalog_id)
184
185 # validate archive
186 archive.validate()
187 destination_archive.validate()
188
189 # Call hot reindexing
190 portal_catalog.manage_hotReindexAll(source_sql_catalog_id=source_catalog_id,
191 destination_sql_catalog_id=destination_sql_catalog_id,
192 archive=archive,
193 source_sql_connection_id_list=[source_connection_id, source_deferred_connection_id],
194 destination_sql_connection_id_list=[destination_connection_id, destination_deferred_connection_id],
195 REQUEST=REQUEST, RESPONSE=RESPONSE)
196
197 # Create inventory just before finish of hot reindexing
198 inventory_date = "%s 23:59:59" %str(archive.getStopDateRangeMax().Date())
199 LOG("inventory_date", 300, inventory_date)
200 self.activate(passive_commit=1,
201 after_method_id=('playBackRecordedObjectList'),
202 priority=5).runInventoryMethod(archive.id,
203 source_connection_id,
204 destination_sql_catalog_id,
205 inventory_date
206 )
207
208
209 if RESPONSE is not None:
210 URL1 = REQUEST.get('URL1')
211 RESPONSE.redirect(URL1 + '/portal_archives?portal_status_message=Archiving%20Started')
212
213
214 def runInventoryMethod(self, archive_id, source_connection_id, destination_sql_catalog_id, inventory_date):
215 """
216 Use a specific method to create inventory in order to use
217 activity to execute it
218 """
219 #destination_sql_catalog = getattr(self.portal_catalog, destination_sql_catalog_id)
220 archive = self._getOb(archive_id)
221 inventory_method_id = archive.getInventoryMethodId()
222 inventory_method = getattr(archive, inventory_method_id, None)
223 if inventory_method is not None:
224 inventory_method(source_connection_id, destination_sql_catalog_id, inventory_date, tag='runInventoryMethod')
225
226
227 InitializeClass(ArchiveTool)

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.2