Commit 843010d7cf90ac36f43f412484be26ce24109988

Authored by Conrad Vermeulen
1 parent 713f2aee

KTS-2743

"upgrade functionality needs to apply foreign key constrains."
Implemented.

Committed By: Conrad Vermeulen
Reviewed By: Kevin Fourie

git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@7821 c91229c3-7414-0410-bfa2-8a42b809f60b
bin/recreateIndexes.php
@@ -39,785 +39,24 @@ @@ -39,785 +39,24 @@
39 /* 39 /*
40 * PURPOSE: This script will recreate the indexes on the database. It will also attempt to add foreign key constraints. 40 * PURPOSE: This script will recreate the indexes on the database. It will also attempt to add foreign key constraints.
41 * 41 *
42 - * NOTE: It was developed on mysql 5, so there may be a requirement for this to be running!  
43 - * NOTE: This assumes that the db is in the 3.5.0 state!  
44 - *  
45 * It will produce 'errors' when there are issues. Many may be ignored as some do not apply to open source. 42 * It will produce 'errors' when there are issues. Many may be ignored as some do not apply to open source.
46 */ 43 */
47 44
  45 +define('USE_DB_ADMIN_USER',1);
48 chdir(dirname(__FILE__)); 46 chdir(dirname(__FILE__));
49 require_once('../config/dmsDefaults.php'); 47 require_once('../config/dmsDefaults.php');
  48 +require_once(KT_LIB_DIR . '/database/schema.inc.php');
50 49
51 print _kt('Recreate DB Indexes') . "...\n\n"; 50 print _kt('Recreate DB Indexes') . "...\n\n";
52 51
53 -$recreator = new IndexRecreator();  
54 -$recreator->globalStart();  
55 -  
56 -do  
57 -{  
58 - $dropped = $recreator->dropIndexes();  
59 -} while ($dropped != 0);  
60 -  
61 -$recreator->applyPreFixes();  
62 -$recreator->addPrimaryKeys();  
63 -$recreator->addForeignKeys();  
64 -$recreator->removeDuplicateIndexes();  
65 -$recreator->addOtherIndexes();  
66 -$recreator->applyPostFixes();  
67 -  
68 -print sprintf(_kt('Total time: %s'), $recreator->globalEnd());  
69 -  
70 -print _kt('Done.') . "\n";  
71 -exit;  
72 -  
73 -class IndexRecreator  
74 -{  
75 - var $knownKeys;  
76 - var $knownPrimary;  
77 - var $newPrimary;  
78 - var $newKeys;  
79 - var $exec;  
80 - var $debugSQL = false;  
81 - var $verbose = true;  
82 -  
83 - var $foreignkeys;  
84 - var $primary;  
85 - var $globalstart;  
86 - var $start;  
87 - var $tables;  
88 -  
89 - function microtimeFloat()  
90 - {  
91 - list($usec, $sec) = explode(" ", microtime());  
92 - return ((float)$usec + (float)$sec);  
93 - }  
94 -  
95 - function globalStart()  
96 - {  
97 - $this->globalstart = $this->microtimeFloat();  
98 - }  
99 -  
100 - function start()  
101 - {  
102 - $this->start = $this->microtimeFloat();  
103 - }  
104 -  
105 - function globalEnd()  
106 - {  
107 - $time = $this->microtimeFloat() - $this->globalstart;  
108 -  
109 - return number_format($time,2,'.',',') . 's';  
110 - }  
111 -  
112 - function end()  
113 - {  
114 - $time = $this->microtimeFloat() - $this->start;  
115 - return number_format($time,2,'.',',') . "s";  
116 - }  
117 -  
118 - function IndexRecreator()  
119 - {  
120 - $this->knownKeys = array();  
121 - $this->knownPrimary = array();  
122 - $this->newPrimary = array();  
123 - $this->newKeys = array();  
124 - $this->exec = true;  
125 - }  
126 -  
127 - function applyPreFixes()  
128 - {  
129 -  
130 - }  
131 -  
132 - function addForeignKeys()  
133 - {  
134 - $this->addForeignKey('active_sessions', 'user_id', 'users', 'id');  
135 -  
136 - $this->addForeignKey('archive_restoration_request', 'document_id', 'documents', 'id');  
137 - $this->addForeignKey('archive_restoration_request', 'request_user_id', 'users', 'id');  
138 - $this->addForeignKey('archive_restoration_request', 'admin_user_id', 'users', 'id');  
139 -  
140 - $this->addForeignKey('archiving_settings', 'archiving_type_id', 'archiving_type_lookup', 'id');  
141 - $this->addForeignKey('archiving_settings', 'time_period_id', 'time_period', 'id');  
142 -  
143 - $this->addForeignKey('baobab_user_keys', 'user_id', 'users', 'id');  
144 - $this->addForeignKey('baobab_user_keys', 'key_id', 'baobab_keys', 'id');  
145 -  
146 - $this->addForeignKey('comment_searchable_text', 'comment_id', 'discussion_comments', 'id');  
147 - $this->addForeignKey('comment_searchable_text', 'document_id', 'documents', 'id');  
148 -  
149 - $this->addForeignKey('dashlet_disables', 'user_id', 'users', 'id');  
150 -  
151 - $this->addForeignKey('discussion_comments', 'thread_id', 'discussion_threads', 'id');  
152 - $this->addForeignKey('discussion_comments', 'user_id', 'users', 'id');  
153 - $this->addForeignKey('discussion_comments', 'in_reply_to', 'discussion_comments', 'id');  
154 -  
155 - $this->addForeignKey('discussion_threads', 'document_id', 'documents', 'id');  
156 - $this->addForeignKey('discussion_threads', 'first_comment_id', 'discussion_comments', 'id');  
157 - $this->addForeignKey('discussion_threads', 'last_comment_id', 'discussion_comments', 'id');  
158 - $this->addForeignKey('discussion_threads', 'creator_id', 'users', 'id');  
159 -  
160 - $this->addForeignKey('document_archiving_link', 'document_id', 'documents', 'id');  
161 - $this->addForeignKey('document_archiving_link', 'archiving_settings_id', 'archiving_settings', 'id');  
162 -  
163 - $this->addForeignKey('document_content_version', 'document_id', 'documents', 'id');  
164 - $this->addForeignKey('document_content_version', 'mime_id', 'mime_types', 'id');  
165 -  
166 - $this->addForeignKey('document_fields','parent_fieldset','fieldsets','id');  
167 -  
168 - $this->addForeignKey('document_fields_link','document_field_id','document_fields','id');  
169 - $this->addForeignKey('document_fields_link','metadata_version_id','document_metadata_version','id');  
170 -  
171 - $this->addForeignKey('document_link','parent_document_id', 'documents', 'id');  
172 - $this->addForeignKey('document_link','child_document_id', 'documents', 'id');  
173 - $this->addForeignKey('document_link','link_type_id','document_link_types','id');  
174 -  
175 - $this->addForeignKey('document_metadata_version','document_type_id','document_types_lookup','id');  
176 - $this->addForeignKey('document_metadata_version','status_id','status_lookup','id');  
177 - $this->addForeignKey('document_metadata_version','document_id','documents','id');  
178 - $this->addForeignKey('document_metadata_version','version_creator_id','users','id');  
179 - $this->addForeignKey('document_metadata_version','content_version_id','document_content_version','id');  
180 - $this->addForeignKey('document_metadata_version','workflow_id','workflows','id');  
181 - $this->addForeignKey('document_metadata_version','workflow_state_id','workflow_states','id');  
182 -  
183 - $this->addForeignKey('document_role_allocations','role_id','roles','id');  
184 - $this->addForeignKey('document_role_allocations','permission_descriptor_id','permission_descriptors','id');  
185 -  
186 - $this->addForeignKey('document_searchable_text','document_id','documents','id');  
187 -  
188 - $this->addForeignKey('document_subscriptions','user_id','users','id');  
189 - $this->addForeignKey('document_subscriptions','document_id','documents','id');  
190 -  
191 - $this->addForeignKey('document_tags','document_id','documents','id');  
192 - $this->addForeignKey('document_tags','tag_id','tag_words','id');  
193 -  
194 - $this->addForeignKey('document_text','document_id','documents','id');  
195 -  
196 -  
197 - $this->addForeignKey('document_transaction_text','document_id','documents','id');  
198 -  
199 - $this->addForeignKey('document_type_fields_link','document_type_id', 'document_types_lookup','id');  
200 - $this->addForeignKey('document_type_fields_link','field_id','document_fields','id');  
201 -  
202 - $this->addForeignKey('document_type_fieldsets_link','document_type_id', 'document_types_lookup','id');  
203 - $this->addForeignKey('document_type_fieldsets_link','fieldset_id','fieldsets','id');  
204 -  
205 - $this->addForeignKey('documents','creator_id','users','id', 'SET NULL', 'SET NULL');  
206 - $this->addForeignKey('documents','folder_id','folders','id'); // we don't want this  
207 - $this->addForeignKey('documents','checked_out_user_id','users','id', 'SET NULL', 'SET NULL');  
208 - $this->addForeignKey('documents','status_id','status_lookup','id');  
209 - $this->addForeignKey('documents','permission_object_id','permission_objects','id');  
210 - $this->addForeignKey('documents','permission_lookup_id','permission_lookups','id');  
211 - $this->addForeignKey('documents','modified_user_id','users','id', 'SET NULL', 'SET NULL');  
212 - $this->addForeignKey('documents','metadata_version_id','document_metadata_version','id');  
213 -  
214 - $this->addForeignKey('download_files','document_id','documents','id');  
215 -  
216 - $this->addForeignKey('field_behaviour_options','behaviour_id','field_behaviours','id');  
217 - $this->addForeignKey('field_behaviour_options','field_id','document_fields','id');  
218 - $this->addForeignKey('field_behaviour_options','instance_id','field_value_instances','id');  
219 -  
220 - $this->addForeignKey('field_behaviours','field_id','document_fields','id');  
221 -  
222 - $this->addForeignKey('field_orders','child_field_id','document_fields','id');  
223 - $this->addForeignKey('field_orders','parent_field_id','document_fields','id');  
224 - $this->addForeignKey('field_orders','fieldset_id','fieldsets','id');  
225 -  
226 - $this->addForeignKey('field_value_instances','field_value_id','metadata_lookup','id'); // it is so.. strange ;)  
227 - $this->addForeignKey('field_value_instances','behaviour_id','field_behaviours','id');  
228 - $this->addForeignKey('field_value_instances','field_id','document_fields','id');  
229 -  
230 - $this->addForeignKey('fieldsets','master_field','document_fields','id');  
231 -  
232 - $this->addForeignKey('folder_descendants','parent_id','folders','id');  
233 - $this->addForeignKey('folder_descendants','folder_id','folders','id');  
234 -  
235 - $this->addForeignKey('folder_doctypes_link','folder_id','folders','id');  
236 - $this->addForeignKey('folder_doctypes_link','document_type_id','document_types_lookup','id');  
237 -  
238 - $this->addForeignKey('folder_searchable_text','folder_id','folders','id');  
239 -  
240 - $this->addForeignKey('folder_subscriptions','user_id','users','id');  
241 - $this->addForeignKey('folder_subscriptions','folder_id','folders','id');  
242 -  
243 - $this->addForeignKey('folder_workflow_map','folder_id', 'folders','id');  
244 - $this->addForeignKey('folder_workflow_map','workflow_id', 'workflows','id');  
245 -  
246 - $this->addForeignKey('folders','creator_id','users','id');  
247 - $this->addForeignKey('folders','permission_object_id','permission_objects','id');  
248 - $this->addForeignKey('folders','permission_lookup_id','permission_lookups','id');  
249 - $this->addForeignKey('folders','parent_id','folders','id');  
250 -  
251 - $this->addForeignKey('folders_users_roles_link','user_id','users','id');  
252 - $this->addForeignKey('folders_users_roles_link','document_id','documents','id');  
253 -  
254 - $this->addForeignKey('groups_groups_link','parent_group_id','groups_lookup','id');  
255 - $this->addForeignKey('groups_groups_link','member_group_id','groups_lookup','id');  
256 -  
257 - $this->addForeignKey('groups_lookup','unit_id', 'units_lookup','id');  
258 -  
259 - $this->addForeignKey('index_files','document_id','documents','id');  
260 - $this->addForeignKey('index_files','user_id','users','id');  
261 -  
262 - $this->addForeignKey('metadata_lookup','document_field_id','document_fields','id');  
263 -// $this->addForeignKey('metadata_lookup','treeorg_parent','??','id');  
264 -  
265 - $this->addForeignKey('metadata_lookup_tree','document_field_id', 'document_fields','id');  
266 -// $this->addForeignKey('metadata_lookup_tree','metadata_lookup_tree_parent', '??','id');  
267 -  
268 - $this->addForeignKey('mime_types','mime_document_id','mime_documents','id', 'set null', 'set null');  
269 - $this->addForeignKey('mime_types','extractor_id','mime_extractors','id', 'set null', 'set null');  
270 -  
271 - $this->addForeignKey('mime_document_mapping','mime_type_id','mime_types','id');  
272 - $this->addForeignKey('mime_document_mapping','mime_document_id','mime_documents','id');  
273 -  
274 - $this->addForeignKey('news','image_mime_type_id','mime_types','id');  
275 -  
276 - $this->addForeignKey('notifications','user_id', 'users','id');  
277 -  
278 - $this->addForeignKey('permission_assignments','permission_id', 'permissions','id');  
279 - $this->addForeignKey('permission_assignments','permission_object_id','permission_objects','id'); // duplicate  
280 - $this->addForeignKey('permission_assignments','permission_descriptor_id','permission_descriptors','id');  
281 -  
282 - $this->addForeignKey('permission_descriptor_groups','descriptor_id','permission_descriptors','id');  
283 - $this->addForeignKey('permission_descriptor_groups','group_id','groups_lookup','id');  
284 -  
285 - $this->addForeignKey('permission_descriptor_roles','descriptor_id','permission_descriptors','id');  
286 - $this->addForeignKey('permission_descriptor_roles','role_id','roles','id');  
287 -  
288 - $this->addForeignKey('permission_descriptor_users','descriptor_id','permission_descriptors','id');  
289 - $this->addForeignKey('permission_descriptor_users','user_id','users','id');  
290 -  
291 - $this->addForeignKey('permission_dynamic_assignments','dynamic_condition_id','permission_dynamic_conditions','id');  
292 - $this->addForeignKey('permission_dynamic_assignments','permission_id','permissions','id');  
293 -  
294 - $this->addForeignKey('permission_dynamic_conditions','permission_object_id','permission_objects','id');  
295 - $this->addForeignKey('permission_dynamic_conditions','group_id','groups_lookup','id');  
296 - $this->addForeignKey('permission_dynamic_conditions','condition_id','saved_searches','id');  
297 -  
298 - $this->addForeignKey('permission_lookup_assignments','permission_id','permissions','id');  
299 - $this->addForeignKey('permission_lookup_assignments','permission_lookup_id','permission_lookups','id'); // duplicate  
300 - $this->addForeignKey('permission_lookup_assignments','permission_descriptor_id','permission_descriptors','id');  
301 -  
302 - $this->addForeignKey('plugin_rss','user_id','users','id');  
303 -  
304 - $this->addForeignKey('quicklinks','user_id','users','id');  
305 -  
306 - $this->addForeignKey('role_allocations','folder_id','folders','id');  
307 - $this->addForeignKey('role_allocations','role_id', 'roles','id');  
308 - $this->addForeignKey('role_allocations','permission_descriptor_id','permission_descriptors','id');  
309 -  
310 - $this->addForeignKey('saved_searches','user_id','users','id');  
311 -  
312 - $this->addForeignKey('search_document_user_link','document_id','documents','id');  
313 - $this->addForeignKey('search_document_user_link','user_id','users','id');  
314 -  
315 - $this->addForeignKey('search_saved','user_id','users','id');  
316 - $this->addForeignKey('search_saved_events','document_id','documents','id');  
317 -  
318 - $this->addForeignKey('time_period','time_unit_id','time_unit_lookup','id');  
319 -  
320 - $this->addForeignKey('type_workflow_map','document_type_id','document_types_lookup','id');  
321 - $this->addForeignKey('type_workflow_map','workflow_id','workflows','id');  
322 -  
323 - $this->addForeignKey('units_lookup','folder_id','folders','id');  
324 -  
325 - $this->addForeignKey('units_organisations_link','unit_id','units_lookup','id');  
326 - $this->addForeignKey('units_organisations_link','organisation_id','organisations_lookup','id');  
327 -  
328 - $this->addForeignKey('uploaded_files','userid','users','id');  
329 - $this->addForeignKey('uploaded_files','document_id','documents','id');  
330 -  
331 - $this->addForeignKey('user_history','user_id','users','id');  
332 -  
333 - $this->addForeignKey('user_history_documents','document_id','documents','id');  
334 - $this->addForeignKey('user_history_documents','user_id','users','id');  
335 -  
336 - $this->addForeignKey('user_history_folders','folder_id','folders','id');  
337 - $this->addForeignKey('user_history_folders','user_id','users','id');  
338 -  
339 - $this->addForeignKey('users','authentication_source_id','authentication_sources','id');  
340 -  
341 - $this->addForeignKey('users_groups_link', 'user_id','users','id');  
342 - $this->addForeignKey('users_groups_link', 'group_id','groups_lookup', 'id');  
343 -  
344 - $this->addForeignKey('workflow_documents','document_id', 'documents','id');  
345 - $this->addForeignKey('workflow_documents','workflow_id', 'workflows','id');  
346 - $this->addForeignKey('workflow_documents','state_id','workflow_states','id');  
347 -  
348 - $this->addForeignKey('workflow_state_actions','state_id','workflow_states','id');  
349 -  
350 - $this->addForeignKey('workflow_state_disabled_actions','state_id','workflow_states','id');  
351 -  
352 - $this->addForeignKey('workflow_state_permission_assignments','permission_id','permissions','id');  
353 - $this->addForeignKey('workflow_state_permission_assignments','permission_descriptor_id','permission_descriptors','id');  
354 - $this->addForeignKey('workflow_state_permission_assignments','workflow_state_id','workflow_states','id');  
355 -  
356 - $this->addForeignKey('workflow_state_transitions','state_id','workflow_states','id');  
357 - $this->addForeignKey('workflow_state_transitions','transition_id','workflow_transitions','id');  
358 -  
359 - $this->addForeignKey('workflow_states','workflow_id', 'workflows','id');  
360 - $this->addForeignKey('workflow_states','inform_descriptor_id', 'permission_descriptors','id');  
361 -  
362 - $this->addForeignKey('workflow_transitions','workflow_id','workflows','id');  
363 - $this->addForeignKey('workflow_transitions','target_state_id','workflow_states','id');  
364 - $this->addForeignKey('workflow_transitions','guard_permission_id','permissions','id');  
365 - $this->addForeignKey('workflow_transitions','guard_condition_id','saved_searches','id');  
366 - $this->addForeignKey('workflow_transitions','guard_group_id','groups_lookup','id');  
367 - $this->addForeignKey('workflow_transitions','guard_role_id','roles','id');  
368 -  
369 - $this->addForeignKey('workflow_trigger_instances','workflow_transition_id','workflow_transitions','id');  
370 -  
371 - $this->addForeignKey('workflows','start_state_id','workflow_states','id');  
372 -  
373 - }  
374 -  
375 - function removeDuplicateIndexes()  
376 - {  
377 - foreach($this->primary as $table=>$key)  
378 - {  
379 - $this->dropIndex($table,$key);  
380 - }  
381 -  
382 - }  
383 - function addOtherIndexes()  
384 - {  
385 - $this->addIndex('active_sessions', 'session_id');  
386 - $this->addIndex('authentication_sources','namespace');  
387 -  
388 - $this->addIndex('column_entries','view_namespace');  
389 -  
390 - $this->addIndex('comment_searchable_text', 'body', 'FULLTEXT');  
391 -  
392 -  
393 - $this->addIndex('dashlet_disables','dashlet_namespace');  
394 - $this->addIndex('document_content_version','storage_path');  
395 -  
396 - $this->addIndex('document_metadata_version','version_created');  
397 - $this->addIndex('document_role_allocations', array('document_id', 'role_id'));  
398 -  
399 - $this->addIndex('document_searchable_text','document_text', 'FULLTEXT');  
400 -  
401 - $this->addIndex('document_text','document_text', 'FULLTEXT');  
402 - $this->addIndex('document_transaction_text','document_text', 'FULLTEXT');  
403 -  
404 - $this->addIndex('document_transaction_types_lookup','namespace', 'UNIQUE');  
405 -  
406 - $this->addIndex('document_transactions','session_id');  
407 - $this->addIndex('document_transactions','document_id');  
408 -  
409 - $this->addIndex('document_types_lookup','name');  
410 - //$this->addIndex('document_types_lookup','disabled'); ? used  
411 -  
412 - $this->addIndex('documents','created');  
413 - $this->addIndex('documents','modified');  
414 - $this->addIndex('documents','full_path','','(255)');  
415 - $this->addIndex('documents','immutable');  
416 - $this->addIndex('documents','checkedout');  
417 -  
418 - $this->addIndex('document_content_version','filename','','(255)');  
419 - $this->addIndex('document_content_version','size');  
420 -  
421 - $this->addIndex('field_behaviour_options',array('behaviour_id','field_id'));  
422 -  
423 - $this->addIndex('field_behaviours','name');  
424 -  
425 - $this->addIndex('fieldsets','is_generic');  
426 - $this->addIndex('fieldsets','is_complete');  
427 - $this->addIndex('fieldsets','is_system');  
428 -  
429 - $this->addIndex('field_orders','child_field_id', 'UNIQUE');  
430 -  
431 - $this->addIndex('folder_searchable_text','folder_text' ,'FULLTEXT');  
432 -  
433 - $this->addIndex('folder_transactions','folder_id');  
434 - $this->addIndex('folder_transactions','session_id');  
435 -  
436 -// $this->addIndex('folders','name');  
437 - $this->addIndex('folders', array('parent_id','name'));  
438 -  
439 - $this->addIndex('groups_lookup','name', 'UNIQUE');  
440 - $this->addIndex('groups_lookup', array('authentication_source_id','authentication_details_s1'));  
441 -  
442 - $this->addIndex('interceptor_instances','interceptor_namespace'); // unique?  
443 -  
444 - $this->addIndex('metadata_lookup','disabled');  
445 - //$this->addNewIndex('metadata_lookup','is_stuck'); don't think this is used anywhere....  
446 -  
447 - $this->addIndex('metadata_lookup_tree','metadata_lookup_tree_parent');  
448 -  
449 - $this->addIndex('mime_types','filetypes');  
450 - $this->addIndex('mime_types','mimetypes');  
451 -  
452 - $this->addIndex('notifications','data_int_1'); // document id seems to be stored in this. used by clearnotifications.  
453 -// $this->addIndex('notifications','type'); // don't think this is used  
454 -  
455 - $this->addIndex('organisations_lookup','name', 'UNIQUE');  
456 -  
457 - $this->addIndex('permission_assignments', array('permission_object_id','permission_id'), 'UNIQUE'); // note change of order  
458 -// $this->dropIndex('permission_assignments','permission_object_id'); // duplicate  
459 -  
460 - //$this->dropIndex('permission_descriptor_groups','descriptor_id'); // in primary key  
461 - $this->addIndex('permission_descriptor_groups','group_id');  
462 -  
463 - //$this->dropIndex('permission_descriptor_roles','descriptor_id'); // in primary key  
464 - $this->addIndex('permission_descriptor_roles','role_id');  
465 -  
466 - //$this->dropIndex('permission_descriptor_users','descriptor_id'); // in primary  
467 - $this->addIndex('permission_descriptor_users','user_id');  
468 -  
469 - $this->addIndex('permission_descriptors','descriptor','UNIQUE');  
470 -  
471 - $this->addIndex('permission_lookup_assignments', array('permission_lookup_id', 'permission_id'), 'UNIQUE');  
472 - //$this->dropIndex('permission_lookup_assignments','permission_lookup_id'); // in composite  
473 -  
474 - $this->addIndex('permissions','name', 'UNIQUE');  
475 -  
476 - $this->addIndex('plugins','namespace','UNIQUE');  
477 - $this->addIndex('plugins','disabled');  
478 -  
479 - $this->addIndex('quicklinks','target_id');  
480 -  
481 - $this->addIndex('roles','name','UNIQUE');  
482 - $this->addIndex('saved_searches','namespace','UNIQUE');  
483 -  
484 - $this->addIndex('scheduler_tasks','task', 'UNIQUE');  
485 -  
486 - $this->addIndex('system_settings','name', 'UNIQUE');  
487 -  
488 - $this->addIndex('units_lookup','name' ,'UNIQUE');  
489 -// $this->dropIndex('units_lookup','folder_id');  
490 - $this->addIndex('units_lookup','folder_id' ,'UNIQUE');  
491 -  
492 - $this->addIndex('upgrades','descriptor');  
493 - $this->addIndex('upgrades','parent');  
494 -  
495 - $this->addIndex('user_history','action_namespace');  
496 - $this->addIndex('user_history','datetime');  
497 - $this->addIndex('user_history','session_id');  
498 -  
499 - $this->addIndex('user_history_documents', array('user_id','document_id'));  
500 - //$this->dropIndex('user_history_documents', 'user_id'); // duplicate  
501 -  
502 - $this->addIndex('user_history_folders', array('user_id','folder_id'));  
503 - //$this->dropIndex('user_history_folders', 'user_id'); // duplicate  
504 -  
505 - $this->addIndex('users','username' ,'UNIQUE');  
506 - $this->addIndex('users','authentication_source_id');  
507 - //$this->addNewIndex('users','authentication_details_b1');  
508 - //$this->addNewIndex('users','authentication_details_b2');  
509 - $this->addIndex('users','last_login');  
510 - $this->addIndex('users','disabled');  
511 -  
512 - $this->addIndex('workflow_states','name');  
513 - $this->addIndex('workflow_states','inform_descriptor_id'); //?  
514 -  
515 - $this->addIndex('workflow_transitions',array('workflow_id','name'), 'UNIQUE');  
516 - //$this->dropIndex('workflow_transitions','workflow_id'); // duplicate  
517 - $this->addIndex('workflow_transitions','name');  
518 - $this->addIndex('workflow_transitions','guard_permission_id'); //?  
519 -  
520 - $this->addIndex('workflow_trigger_instances','namespace');  
521 -  
522 - $this->addIndex('workflows','name', 'UNIQUE');  
523 -  
524 -  
525 - }  
526 -  
527 - function applyPostFixes()  
528 - {  
529 -  
530 - }  
531 -  
532 - function dropIndex($table, $field)  
533 - {  
534 - if (!is_array($fields)) $field = array($field);  
535 - $field = implode('_', $field);  
536 - $sql = "alter table $table drop index $field";  
537 - $this->_exec($sql);  
538 - }  
539 -  
540 - function addIndex($table, $fields, $type='', $extra='')  
541 - {  
542 - if (!in_array($table, $this->tables)) return;  
543 -  
544 - if (!is_array($fields)) $fields = array($fields);  
545 - $index = implode('_', $fields);  
546 - //$index = str_replace('_id','',$index);  
547 - $fields = implode(',',$fields);  
548 - $sql = "alter table $table add $type index $index ($fields$extra) ";  
549 - $this->_exec($sql);  
550 - }  
551 -  
552 - function addForeignKey($table, $field, $othertable, $otherfield, $ondelete='cascade', $onupdate='cascade')  
553 - {  
554 - if (!in_array($table, $this->tables)) return;  
555 - if (!in_array($othertable, $this->tables)) return;  
556 -  
557 - $sql = "alter table $table add foreign key ($field) references $othertable ($otherfield) ";  
558 - if ($ondelete != '')  
559 - $sql .= " on delete $ondelete";  
560 - if ($onupdate != '')  
561 - $sql .= " on update $onupdate";  
562 - $this->_exec($sql);  
563 - }  
564 -  
565 - function addPrimaryKeys()  
566 - {  
567 - $this->addPrimaryKey('active_sessions', 'id');  
568 - $this->addPrimaryKey('archive_restoration_request','id');  
569 - $this->addPrimaryKey('archiving_settings','id');  
570 - $this->addPrimaryKey('archiving_type_lookup','id');  
571 - $this->addPrimaryKey('authentication_sources','id');  
572 - $this->addPrimaryKey('baobab_keys','id');  
573 - $this->addPrimaryKey('baobab_user_keys','id');  
574 - $this->addPrimaryKey('column_entries','id');  
575 - $this->addPrimaryKey('comment_searchable_text','comment_id');  
576 - $this->addPrimaryKey('dashlet_disables','id');  
577 - $this->addPrimaryKey('data_types','id');  
578 - $this->addPrimaryKey('discussion_comments','id');  
579 - $this->addPrimaryKey('discussion_threads','id');  
580 - $this->addPrimaryKey('document_archiving_link','id');  
581 - $this->addPrimaryKey('document_content_version','id');  
582 - $this->addPrimaryKey('document_fields','id');  
583 - $this->addPrimaryKey('document_fields_link','id');  
584 - $this->addPrimaryKey('document_incomplete','id');  
585 - $this->addPrimaryKey('document_link','id');  
586 - $this->addPrimaryKey('document_link_types','id');  
587 - $this->addPrimaryKey('document_metadata_version','id');  
588 - $this->addPrimaryKey('document_role_allocations','id');  
589 - $this->addPrimaryKey('document_subscriptions','id');  
590 - $this->addPrimaryKey('document_tags',array('document_id','tag_id'));  
591 - $this->addPrimaryKey('document_text', 'document_id');  
592 - $this->addPrimaryKey('document_transaction_types_lookup', 'id');  
593 - $this->addPrimaryKey('document_transaction_text', 'document_id');  
594 - $this->addPrimaryKey('document_transactions','id');  
595 - $this->addPrimaryKey('document_type_fields_link','id');  
596 - $this->addPrimaryKey('document_type_fieldsets_link','id');  
597 - $this->addPrimaryKey('document_types_lookup','id');  
598 - $this->addPrimaryKey('documents','id');  
599 - $this->addPrimaryKey('download_files',array('document_id','session'));  
600 - $this->addPrimaryKey('field_behaviours','id');  
601 - $this->addPrimaryKey('field_value_instances','id');  
602 - $this->addPrimaryKey('fieldsets','id');  
603 - $this->addPrimaryKey('folder_doctypes_link','id');  
604 - $this->addPrimaryKey('folder_searchable_text','folder_id');  
605 - $this->addPrimaryKey('folder_subscriptions','id');  
606 - $this->addPrimaryKey('folder_transactions','id');  
607 - $this->addPrimaryKey('folder_workflow_map','folder_id');  
608 - $this->addPrimaryKey('folders','id');  
609 - $this->addPrimaryKey('folders_users_roles_link','id');  
610 - $this->addPrimaryKey('groups_groups_link','id');  
611 - $this->addPrimaryKey('groups_lookup','id');  
612 - $this->addPrimaryKey('help','id');  
613 - $this->addPrimaryKey('help_replacement','id');  
614 - $this->addPrimaryKey('index_files','document_id');  
615 - $this->addPrimaryKey('interceptor_instances','id');  
616 - $this->addPrimaryKey('links','id');  
617 - $this->addPrimaryKey('metadata_lookup','id');  
618 - $this->addPrimaryKey('metadata_lookup_tree','id');  
619 - $this->addPrimaryKey('mime_documents','id');  
620 - $this->addPrimaryKey('mime_extractors','id');  
621 - $this->addPrimaryKey('mime_document_mapping',array('mime_type_id','mime_document_id'));  
622 - $this->addPrimaryKey('mime_types','id');  
623 - $this->addPrimaryKey('news','id');  
624 - $this->addPrimaryKey('notifications','id');  
625 - $this->addPrimaryKey('organisations_lookup','id');  
626 - $this->addPrimaryKey('permission_assignments','id');  
627 - $this->addPrimaryKey('permission_descriptor_groups', array('descriptor_id','group_id'));  
628 - $this->addPrimaryKey('permission_descriptor_roles', array('descriptor_id','role_id'));  
629 - $this->addPrimaryKey('permission_descriptor_users', array('descriptor_id','user_id'));  
630 - $this->addPrimaryKey('permission_descriptors','id');  
631 - $this->addPrimaryKey('permission_dynamic_conditions','id');  
632 - $this->addPrimaryKey('permission_lookup_assignments','id');  
633 - $this->addPrimaryKey('permission_lookups','id');  
634 - $this->addPrimaryKey('permission_objects','id');  
635 - $this->addPrimaryKey('permissions','id');  
636 - $this->addPrimaryKey('plugin_rss','id');  
637 - $this->addPrimaryKey('plugins','id');  
638 - $this->addPrimaryKey('quicklinks','id');  
639 - $this->addPrimaryKey('role_allocations','id');  
640 - $this->addPrimaryKey('roles','id');  
641 - $this->addPrimaryKey('saved_searches','id');  
642 - $this->addPrimaryKey('scheduler_tasks','id');  
643 - $this->addPrimaryKey('search_ranking',array('groupname','itemname'));  
644 - $this->addPrimaryKey('search_saved','id');  
645 - $this->addPrimaryKey('search_saved_events','document_id');  
646 - $this->addPrimaryKey('status_lookup','id');  
647 - $this->addPrimaryKey('system_settings','id');  
648 - $this->addPrimaryKey('tag_words','id');  
649 - $this->addPrimaryKey('time_period','id');  
650 - $this->addPrimaryKey('time_unit_lookup','id');  
651 - $this->addPrimaryKey('trigger_selection','event_ns');  
652 - $this->addPrimaryKey('type_workflow_map','document_type_id');  
653 - $this->addPrimaryKey('units_lookup','id');  
654 - $this->addPrimaryKey('units_organisations_link','id');  
655 - $this->addPrimaryKey('upgrades','id');  
656 - $this->addPrimaryKey('uploaded_files','tempfilename');  
657 - $this->addPrimaryKey('user_history','id');  
658 - $this->addPrimaryKey('user_history_documents','id');  
659 - $this->addPrimaryKey('user_history_folders','id');  
660 - $this->addPrimaryKey('users','id');  
661 - $this->addPrimaryKey('users_groups_link','id');  
662 - $this->addPrimaryKey('workflow_actions','workflow_id');  
663 - $this->addPrimaryKey('workflow_documents','document_id');  
664 - $this->addPrimaryKey('workflow_state_permission_assignments','id');  
665 - $this->addPrimaryKey('workflow_states','id');  
666 - $this->addPrimaryKey('workflow_state_transitions',array('state_id','transition_id'));  
667 - $this->addPrimaryKey('workflow_transitions','id');  
668 - $this->addPrimaryKey('workflow_trigger_instances','id');  
669 - $this->addPrimaryKey('workflows','id');  
670 - }  
671 -  
672 - function addPrimaryKey($table, $primarykey)  
673 - {  
674 - if (!in_array($table, $this->tables)) return;  
675 - if (is_array($primarykey))  
676 - {  
677 - $primarykey = implode(',', $primarykey);  
678 - }  
679 -  
680 - $sql="alter table $table add primary key ($primarykey)";  
681 - $this->_exec($sql, false);  
682 -  
683 - if (strpos($primarykey,',') === false)  
684 - {  
685 - $this->primary[$table] = $primarykey;  
686 - $sql="alter table $table add unique key ($primarykey)";  
687 - $this->_exec($sql);  
688 - }  
689 - }  
690 -  
691 - function dropIndexes()  
692 - {  
693 - $result = DBUtil::getResultArray("show tables");  
694 - $tables=array();  
695 - $this->tables = array();  
696 -  
697 - foreach($result as $table)  
698 - {  
699 - $keys = array_keys($table);  
700 -  
701 - $tablename = $table[$keys[0]];  
702 - if (substr($tablename,0,5) == 'zseq_')  
703 - {  
704 - continue;  
705 - }  
706 -  
707 - $stmt = DBUtil::getResultArray("show create table $tablename");  
708 - $this->tables[] = $tablename;  
709 -  
710 - $keys = array_keys($stmt[0]);  
711 -  
712 - $sql = $stmt[0][$keys[1]];  
713 -  
714 - $table = array('fks'=>array(), 'pk'=>array(), 'keys'=>array());  
715 - $lines = explode("\n", $sql);  
716 - foreach($lines as $line)  
717 - {  
718 - $line = trim($line);  
719 - if (strpos($line, 'PRIMARY KEY') === 0)  
720 - {  
721 - preg_match('(\`([^\`])*\`)',$line, $params);  
722 - $primaryKey = explode(',', $params[0]);  
723 - foreach($primaryKey as $value)  
724 - {  
725 - $fieldname = substr($value,1,-1);  
726 - $table['pk'][] = $fieldname;  
727 - }  
728 - continue;  
729 - }  
730 - elseif (strpos($line, 'CONSTRAINT') === 0)  
731 - {  
732 - preg_match_all('(\`([^\`])*\`)',$line, $params);  
733 -  
734 - $fieldname = substr($params[0][1],1,-1);  
735 -  
736 - $table['fks'][$fieldname] = array(  
737 - 'constraint'=>substr($params[0][0],1,-1),  
738 - 'table'=>substr($params[0][2],1,-1),  
739 - 'field'=>substr($params[0][3],1,-1)  
740 - );  
741 - continue;  
742 - }  
743 - elseif (strpos($line, 'KEY') !== false)  
744 - {  
745 - preg_match_all('(\`([^\`])*\`)',$line, $params);  
746 - $fieldname = substr($params[0][1],1,-1);  
747 - $key = substr($params[0][0],1,-1);  
748 - $table['keys'][$fieldname] = array('name'=>$key, 'unique'=>false);  
749 - if (strpos($line, 'UNIQUE KEY') !== false)  
750 - {  
751 - if (count($params[0]) == 2)  
752 - {  
753 - $table['keys'][$fieldname]['unique']=true;  
754 - }  
755 - }  
756 - continue;  
757 - }  
758 - }  
759 -  
760 - $tables[$tablename]= $table;  
761 - }  
762 -  
763 - $dropped = 0;  
764 -  
765 - // drop foreign keys  
766 - foreach($tables as $tablename=>$table)  
767 - {  
768 - foreach($table['fks'] as $fieldname=>$constraint)  
769 - {  
770 - $name = $constraint['constraint'];  
771 - $table = $constraint['table'];  
772 - $field = $constraint['field'];  
773 - $sql = "ALTER TABLE $tablename DROP FOREIGN KEY $name;";  
774 - if ($this->_exec($sql)) $dropped++;  
775 - }  
776 - }  
777 -  
778 - // drop primary keys  
779 - foreach($tables as $tablename=>$table)  
780 - {  
781 - foreach($table['pk'] as $fieldname)  
782 - {  
783 - $sql = "ALTER TABLE $tablename DROP primary key;";  
784 - if ($this->_exec($sql,false)) $dropped++;  
785 - break;  
786 - }  
787 - }  
788 -  
789 - // drop normal indexes  
790 -  
791 - foreach($tables as $tablename=>$table)  
792 - {  
793 - foreach($table['keys'] as $fieldname=>$keyinfo)  
794 - {  
795 - $keyname = $keyinfo['name'];  
796 - $sql = "ALTER TABLE $tablename DROP key $keyname;";  
797 - if ($this->_exec($sql)) $dropped++;  
798 - break;  
799 - }  
800 - }  
801 -  
802 -  
803 - return $dropped;  
804 - }  
805 -  
806 - function _exec($sql, $report = true)  
807 - {  
808 - print "Action: $sql";  
809 - $this->start();  
810 - $rs = DBUtil::runQuery($sql);  
811 - print " - " . $this->end() . "\n";  
812 - if (PEAR::isError($rs))  
813 - {  
814 - if ($report) print "* " . $rs->getMessage() . "\n";  
815 - return false;  
816 - }  
817 - return true;  
818 - }  
819 -  
820 -} 52 +ini_set('display_errors','Off');
  53 +$schemautil = KTSchemaUtil::getSingleton();
821 54
  55 +$schemautil->dropForeignKeys();
  56 +$schemautil->dropPrimaryKeys();
  57 +$schemautil->dropIndexes();
  58 +$schemautil->createPrimaryKeys();
  59 +$schemautil->createForeignKeys();
  60 +$schemautil->createIndexes();
822 61
823 ?> 62 ?>
824 \ No newline at end of file 63 \ No newline at end of file
lib/database/schema.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +//require_once('../../config/dmsDefaults.php');
  4 +
  5 +//ini_set('display_errors','Off');
  6 +//$schemautil = KTSchemaUtil::getSingleton();
  7 +
  8 +//$schemautil->dropForeignKeys();
  9 +//$schemautil->dropPrimaryKeys();
  10 +//$schemautil->dropIndexes();
  11 +//$schemautil->createPrimaryKeys();
  12 +//$schemautil->createForeignKeys();
  13 +//$schemautil->createIndexes();
  14 +
  15 +class KTSchemaUtil
  16 +{
  17 + /**
  18 + * Indicates if statements to the database must be performed.
  19 + *
  20 + * @var boolean
  21 + */
  22 + public $persist;
  23 +
  24 + /**
  25 + * Primary key definitions.
  26 + *
  27 + * @var array
  28 + */
  29 + private $primaryKeys;
  30 +
  31 + /**
  32 + * Foreign key definitions
  33 + *
  34 + * @var array
  35 + */
  36 + private $foreignKeys;
  37 +
  38 + /**
  39 + * Index definitions
  40 + *
  41 + * @var array
  42 + */
  43 + private $indexes;
  44 +
  45 + /**
  46 + * Schema of database
  47 + *
  48 + * @var array
  49 + */
  50 + private $schema;
  51 +
  52 + private $primary;
  53 +
  54 +
  55 + private function __construct($setup=false)
  56 + {
  57 + $this->persist = true;
  58 +
  59 + $this->getDBSchema();
  60 + if ($setup)
  61 + {
  62 + $this->setupAdminDatabase();
  63 + }
  64 +
  65 + $this->definePrimaryKeys();
  66 + $this->defineForeignKeys();
  67 + $this->defineOtherIndexes();
  68 + $this->_exec('SET FOREIGN_KEY_CHECKS = 0');
  69 + }
  70 +
  71 + public function __destruct()
  72 + {
  73 + $this->_exec('SET FOREIGN_KEY_CHECKS = 1');
  74 + }
  75 +
  76 + private function createFixUser()
  77 + {
  78 + $sql = "SELECT 1 FROM users WHERE id = -10;";
  79 + $rs = DBUtil::getResultArray($sql);
  80 + if (PEAR::isError($rs))
  81 + {
  82 + print '';
  83 + }
  84 + if (count($rs) == 0)
  85 + {
  86 + $sql = "INSERT INTO users (id,username,name,password,max_sessions) VALUES (-10,'_deleted_helper','Deleted User','---------------',0)";
  87 + $this->_exec($sql);
  88 + }
  89 + }
  90 +
  91 + public function setupAdminDatabase()
  92 + {
  93 + global $default;
  94 + $dsn = array(
  95 + 'phptype' => $default->dbType,
  96 + 'username' => $default->dbAdminUser,
  97 + 'password' => $default->dbAdminPass,
  98 + 'hostspec' => $default->dbHost,
  99 + 'database' => $default->dbName,
  100 + 'port' => $default->dbPort,
  101 + );
  102 +
  103 + $options = array(
  104 + 'debug' => 2,
  105 + 'portability' => DB_PORTABILITY_ERRORS,
  106 + 'seqname_format' => 'zseq_%s',
  107 + );
  108 +
  109 + $default->_admindb = &DB::connect($dsn, $options);
  110 + if (PEAR::isError($default->_admindb))
  111 + {
  112 + die($default->_admindb->toString());
  113 + }
  114 + $default->_admindb->setFetchMode(DB_FETCHMODE_ASSOC);
  115 + return;
  116 + }
  117 +
  118 + private function removeDuplicateIndexes()
  119 + {
  120 + foreach($this->primary as $table=>$key)
  121 + {
  122 + $this->dropIndex($table,$key);
  123 + }
  124 +
  125 + }
  126 +
  127 +
  128 + /**
  129 + * Enter description here...
  130 + *
  131 + * @return KTSchemaUtil
  132 + */
  133 + public function getSingleton()
  134 + {
  135 + static $singleton = null;
  136 + if (is_null($singleton))
  137 + {
  138 + $singleton = new KTSchemaUtil();
  139 + }
  140 + return $singleton;
  141 + }
  142 +
  143 + /**
  144 + * Adds primary keys to the database
  145 + *
  146 + */
  147 + private function definePrimaryKeys()
  148 + {
  149 + $this->primaryKeys = array();
  150 + $this->definePrimaryKey('active_sessions', 'id');
  151 + $this->definePrimaryKey('archive_restoration_request','id');
  152 + $this->definePrimaryKey('archiving_settings','id');
  153 + $this->definePrimaryKey('archiving_type_lookup','id');
  154 + $this->definePrimaryKey('authentication_sources','id');
  155 + $this->definePrimaryKey('baobab_keys','id');
  156 + $this->definePrimaryKey('baobab_user_keys','id');
  157 + $this->definePrimaryKey('column_entries','id');
  158 + $this->definePrimaryKey('comment_searchable_text','comment_id');
  159 + $this->definePrimaryKey('dashlet_disables','id');
  160 + $this->definePrimaryKey('data_types','id');
  161 + $this->definePrimaryKey('discussion_comments','id');
  162 + $this->definePrimaryKey('discussion_threads','id');
  163 + $this->definePrimaryKey('document_archiving_link','id');
  164 + $this->definePrimaryKey('document_content_version','id');
  165 + $this->definePrimaryKey('document_fields','id');
  166 + $this->definePrimaryKey('document_fields_link','id');
  167 + $this->definePrimaryKey('document_incomplete','id');
  168 + $this->definePrimaryKey('document_link','id');
  169 + $this->definePrimaryKey('document_link_types','id');
  170 + $this->definePrimaryKey('document_metadata_version','id');
  171 + $this->definePrimaryKey('document_role_allocations','id');
  172 + $this->definePrimaryKey('document_subscriptions','id');
  173 + $this->definePrimaryKey('document_tags',array('document_id','tag_id'));
  174 + $this->definePrimaryKey('document_text', 'document_id');
  175 + $this->definePrimaryKey('document_transaction_types_lookup', 'id');
  176 + $this->definePrimaryKey('document_transaction_text', 'document_id');
  177 + $this->definePrimaryKey('document_transactions','id');
  178 + $this->definePrimaryKey('document_type_fields_link','id');
  179 + $this->definePrimaryKey('document_type_fieldsets_link','id');
  180 + $this->definePrimaryKey('document_types_lookup','id');
  181 + $this->definePrimaryKey('documents','id');
  182 + $this->definePrimaryKey('download_files',array('document_id','session'));
  183 + $this->definePrimaryKey('field_behaviours','id');
  184 + $this->definePrimaryKey('field_value_instances','id');
  185 + $this->definePrimaryKey('fieldsets','id');
  186 + $this->definePrimaryKey('folder_doctypes_link','id');
  187 + $this->definePrimaryKey('folder_searchable_text','folder_id');
  188 + $this->definePrimaryKey('folder_subscriptions','id');
  189 + $this->definePrimaryKey('folder_transactions','id');
  190 + $this->definePrimaryKey('folder_workflow_map','folder_id');
  191 + $this->definePrimaryKey('folders','id');
  192 + $this->definePrimaryKey('folders_users_roles_link','id');
  193 + $this->definePrimaryKey('groups_groups_link','id');
  194 + $this->definePrimaryKey('groups_lookup','id');
  195 + $this->definePrimaryKey('help','id');
  196 + $this->definePrimaryKey('help_replacement','id');
  197 + $this->definePrimaryKey('index_files','document_id');
  198 + $this->definePrimaryKey('interceptor_instances','id');
  199 + $this->definePrimaryKey('links','id');
  200 + $this->definePrimaryKey('metadata_lookup','id');
  201 + $this->definePrimaryKey('metadata_lookup_tree','id');
  202 + $this->definePrimaryKey('mime_documents','id');
  203 + $this->definePrimaryKey('mime_extractors','id');
  204 + $this->definePrimaryKey('mime_document_mapping',array('mime_type_id','mime_document_id'));
  205 + $this->definePrimaryKey('mime_types','id');
  206 + $this->definePrimaryKey('news','id');
  207 + $this->definePrimaryKey('notifications','id');
  208 + $this->definePrimaryKey('organisations_lookup','id');
  209 + $this->definePrimaryKey('permission_assignments','id');
  210 + $this->definePrimaryKey('permission_descriptor_groups', array('descriptor_id','group_id'));
  211 + $this->definePrimaryKey('permission_descriptor_roles', array('descriptor_id','role_id'));
  212 + $this->definePrimaryKey('permission_descriptor_users', array('descriptor_id','user_id'));
  213 + $this->definePrimaryKey('permission_descriptors','id');
  214 + $this->definePrimaryKey('permission_dynamic_conditions','id');
  215 + $this->definePrimaryKey('permission_lookup_assignments','id');
  216 + $this->definePrimaryKey('permission_lookups','id');
  217 + $this->definePrimaryKey('permission_objects','id');
  218 + $this->definePrimaryKey('permissions','id');
  219 + $this->definePrimaryKey('plugin_rss','id');
  220 + $this->definePrimaryKey('plugins','id');
  221 + $this->definePrimaryKey('plugin_helper','id');
  222 + $this->definePrimaryKey('quicklinks','id');
  223 + $this->definePrimaryKey('role_allocations','id');
  224 + $this->definePrimaryKey('roles','id');
  225 + $this->definePrimaryKey('saved_searches','id');
  226 + $this->definePrimaryKey('scheduler_tasks','id');
  227 + $this->definePrimaryKey('search_ranking',array('groupname','itemname'));
  228 + $this->definePrimaryKey('search_saved','id');
  229 + $this->definePrimaryKey('search_saved_events','document_id');
  230 + $this->definePrimaryKey('status_lookup','id');
  231 + $this->definePrimaryKey('system_settings','id');
  232 + $this->definePrimaryKey('tag_words','id');
  233 + $this->definePrimaryKey('time_period','id');
  234 + $this->definePrimaryKey('time_unit_lookup','id');
  235 + $this->definePrimaryKey('trigger_selection','event_ns');
  236 + $this->definePrimaryKey('type_workflow_map','document_type_id');
  237 + $this->definePrimaryKey('units_lookup','id');
  238 + $this->definePrimaryKey('units_organisations_link','id');
  239 + $this->definePrimaryKey('upgrades','id');
  240 + $this->definePrimaryKey('uploaded_files','tempfilename');
  241 + $this->definePrimaryKey('user_history','id');
  242 + $this->definePrimaryKey('user_history_documents','id');
  243 + $this->definePrimaryKey('user_history_folders','id');
  244 + $this->definePrimaryKey('users','id');
  245 + $this->definePrimaryKey('users_groups_link','id');
  246 + $this->definePrimaryKey('workflow_actions','workflow_id');
  247 + $this->definePrimaryKey('workflow_documents','document_id');
  248 + $this->definePrimaryKey('workflow_state_permission_assignments','id');
  249 + $this->definePrimaryKey('workflow_states','id');
  250 + $this->definePrimaryKey('workflow_state_transitions',array('state_id','transition_id'));
  251 + $this->definePrimaryKey('workflow_transitions','id');
  252 + $this->definePrimaryKey('workflow_trigger_instances','id');
  253 + $this->definePrimaryKey('workflows','id');
  254 + }
  255 +
  256 + /**
  257 + * Adds foreign keys to the database
  258 + *
  259 + */
  260 + private function defineForeignKeys()
  261 + {
  262 + $this->foreignKeys = array();
  263 + $this->defineForeignKey('active_sessions', 'user_id', 'users', 'id');
  264 +
  265 + $this->defineForeignKey('archive_restoration_request', 'document_id', 'documents', 'id');
  266 + $this->defineForeignKey('archive_restoration_request', 'request_user_id', 'users', 'id');
  267 + $this->defineForeignKey('archive_restoration_request', 'admin_user_id', 'users', 'id');
  268 +
  269 + $this->defineForeignKey('archiving_settings', 'archiving_type_id', 'archiving_type_lookup', 'id');
  270 + $this->defineForeignKey('archiving_settings', 'time_period_id', 'time_period', 'id');
  271 +
  272 + $this->defineForeignKey('baobab_user_keys', 'user_id', 'users', 'id');
  273 + $this->defineForeignKey('baobab_user_keys', 'key_id', 'baobab_keys', 'id');
  274 +
  275 + $this->defineForeignKey('comment_searchable_text', 'comment_id', 'discussion_comments', 'id');
  276 + $this->defineForeignKey('comment_searchable_text', 'document_id', 'documents', 'id');
  277 +
  278 + $this->defineForeignKey('dashlet_disables', 'user_id', 'users', 'id');
  279 +
  280 + $this->defineForeignKey('discussion_comments', 'thread_id', 'discussion_threads', 'id');
  281 + $this->defineForeignKey('discussion_comments', 'user_id', 'users', 'id');
  282 + $this->defineForeignKey('discussion_comments', 'in_reply_to', 'discussion_comments', 'id');
  283 +
  284 + $this->defineForeignKey('discussion_threads', 'document_id', 'documents', 'id');
  285 + $this->defineForeignKey('discussion_threads', 'first_comment_id', 'discussion_comments', 'id');
  286 + $this->defineForeignKey('discussion_threads', 'last_comment_id', 'discussion_comments', 'id');
  287 + $this->defineForeignKey('discussion_threads', 'creator_id', 'users', 'id');
  288 +
  289 + $this->defineForeignKey('document_archiving_link', 'document_id', 'documents', 'id');
  290 + $this->defineForeignKey('document_archiving_link', 'archiving_settings_id', 'archiving_settings', 'id');
  291 +
  292 + $this->defineForeignKey('document_content_version', 'document_id', 'documents', 'id');
  293 + $this->defineForeignKey('document_content_version', 'mime_id', 'mime_types', 'id');
  294 +
  295 + $this->defineForeignKey('document_fields','parent_fieldset','fieldsets','id');
  296 +
  297 + $this->defineForeignKey('document_fields_link','document_field_id','document_fields','id');
  298 + $this->defineForeignKey('document_fields_link','metadata_version_id','document_metadata_version','id');
  299 +
  300 + $this->defineForeignKey('document_link','parent_document_id', 'documents', 'id');
  301 + $this->defineForeignKey('document_link','child_document_id', 'documents', 'id');
  302 + $this->defineForeignKey('document_link','link_type_id','document_link_types','id');
  303 +
  304 + $this->defineForeignKey('document_metadata_version','document_type_id','document_types_lookup','id');
  305 + $this->defineForeignKey('document_metadata_version','status_id','status_lookup','id');
  306 + $this->defineForeignKey('document_metadata_version','document_id','documents','id');
  307 + $this->defineForeignKey('document_metadata_version','version_creator_id','users','id');
  308 + $this->defineForeignKey('document_metadata_version','content_version_id','document_content_version','id');
  309 + $this->defineForeignKey('document_metadata_version','workflow_id','workflows','id');
  310 + $this->defineForeignKey('document_metadata_version','workflow_state_id','workflow_states','id');
  311 +
  312 + $this->defineForeignKey('document_role_allocations','role_id','roles','id');
  313 + $this->defineForeignKey('document_role_allocations','permission_descriptor_id','permission_descriptors','id');
  314 +
  315 + $this->defineForeignKey('document_searchable_text','document_id','documents','id');
  316 +
  317 + $this->defineForeignKey('document_subscriptions','user_id','users','id');
  318 + $this->defineForeignKey('document_subscriptions','document_id','documents','id');
  319 +
  320 + $this->defineForeignKey('document_tags','document_id','documents','id');
  321 + $this->defineForeignKey('document_tags','tag_id','tag_words','id');
  322 +
  323 + $this->defineForeignKey('document_text','document_id','documents','id');
  324 +
  325 +
  326 + $this->defineForeignKey('document_transaction_text','document_id','documents','id');
  327 +
  328 + $this->defineForeignKey('document_type_fields_link','document_type_id', 'document_types_lookup','id');
  329 + $this->defineForeignKey('document_type_fields_link','field_id','document_fields','id');
  330 +
  331 + $this->defineForeignKey('document_type_fieldsets_link','document_type_id', 'document_types_lookup','id');
  332 + $this->defineForeignKey('document_type_fieldsets_link','fieldset_id','fieldsets','id');
  333 +
  334 + $this->defineForeignKey('documents','creator_id','users','id', 'SET NULL', 'SET NULL');
  335 + $this->defineForeignKey('documents','folder_id','folders','id');
  336 + $this->defineForeignKey('documents','checked_out_user_id','users','id', 'SET NULL', 'SET NULL');
  337 + $this->defineForeignKey('documents','status_id','status_lookup','id');
  338 + $this->defineForeignKey('documents','permission_object_id','permission_objects','id');
  339 + $this->defineForeignKey('documents','permission_lookup_id','permission_lookups','id');
  340 + $this->defineForeignKey('documents','modified_user_id','users','id', 'SET NULL', 'SET NULL');
  341 + $this->defineForeignKey('documents','metadata_version_id','document_metadata_version','id');
  342 +
  343 + $this->defineForeignKey('download_files','document_id','documents','id');
  344 +
  345 + $this->defineForeignKey('field_behaviour_options','behaviour_id','field_behaviours','id');
  346 + $this->defineForeignKey('field_behaviour_options','field_id','document_fields','id');
  347 + $this->defineForeignKey('field_behaviour_options','instance_id','field_value_instances','id');
  348 +
  349 + $this->defineForeignKey('field_behaviours','field_id','document_fields','id');
  350 +
  351 + $this->defineForeignKey('field_orders','child_field_id','document_fields','id');
  352 + $this->defineForeignKey('field_orders','parent_field_id','document_fields','id');
  353 + $this->defineForeignKey('field_orders','fieldset_id','fieldsets','id');
  354 +
  355 + $this->defineForeignKey('field_value_instances','field_value_id','metadata_lookup','id'); // it is so.. strange ;)
  356 + $this->defineForeignKey('field_value_instances','behaviour_id','field_behaviours','id');
  357 + $this->defineForeignKey('field_value_instances','field_id','document_fields','id');
  358 +
  359 + $this->defineForeignKey('fieldsets','master_field','document_fields','id');
  360 +
  361 + $this->defineForeignKey('folder_descendants','parent_id','folders','id');
  362 + $this->defineForeignKey('folder_descendants','folder_id','folders','id');
  363 +
  364 + $this->defineForeignKey('folder_doctypes_link','folder_id','folders','id');
  365 + $this->defineForeignKey('folder_doctypes_link','document_type_id','document_types_lookup','id');
  366 +
  367 + $this->defineForeignKey('folder_searchable_text','folder_id','folders','id');
  368 +
  369 + $this->defineForeignKey('folder_subscriptions','user_id','users','id');
  370 + $this->defineForeignKey('folder_subscriptions','folder_id','folders','id');
  371 +
  372 + $this->defineForeignKey('folder_workflow_map','folder_id', 'folders','id');
  373 + $this->defineForeignKey('folder_workflow_map','workflow_id', 'workflows','id');
  374 +
  375 + $this->defineForeignKey('folders','creator_id','users','id');
  376 + $this->defineForeignKey('folders','permission_object_id','permission_objects','id');
  377 + $this->defineForeignKey('folders','permission_lookup_id','permission_lookups','id');
  378 + $this->defineForeignKey('folders','parent_id','folders','id');
  379 +
  380 + $this->defineForeignKey('folders_users_roles_link','user_id','users','id');
  381 + $this->defineForeignKey('folders_users_roles_link','document_id','documents','id');
  382 +
  383 + $this->defineForeignKey('groups_groups_link','parent_group_id','groups_lookup','id');
  384 + $this->defineForeignKey('groups_groups_link','member_group_id','groups_lookup','id');
  385 +
  386 + $this->defineForeignKey('groups_lookup','unit_id', 'units_lookup','id');
  387 +
  388 + $this->defineForeignKey('index_files','document_id','documents','id');
  389 + $this->defineForeignKey('index_files','user_id','users','id');
  390 +
  391 + $this->defineForeignKey('metadata_lookup','document_field_id','document_fields','id');
  392 +
  393 + $this->defineForeignKey('metadata_lookup_tree','document_field_id', 'document_fields','id');
  394 +
  395 + $this->defineForeignKey('mime_types','mime_document_id','mime_documents','id', 'set null', 'set null');
  396 + $this->defineForeignKey('mime_types','extractor_id','mime_extractors','id', 'set null', 'set null');
  397 +
  398 + $this->defineForeignKey('mime_document_mapping','mime_type_id','mime_types','id');
  399 + $this->defineForeignKey('mime_document_mapping','mime_document_id','mime_documents','id');
  400 +
  401 + $this->defineForeignKey('news','image_mime_type_id','mime_types','id');
  402 +
  403 + $this->defineForeignKey('notifications','user_id', 'users','id');
  404 +
  405 + $this->defineForeignKey('permission_assignments','permission_id', 'permissions','id');
  406 + $this->defineForeignKey('permission_assignments','permission_object_id','permission_objects','id'); // duplicate
  407 + $this->defineForeignKey('permission_assignments','permission_descriptor_id','permission_descriptors','id');
  408 +
  409 + $this->defineForeignKey('permission_descriptor_groups','descriptor_id','permission_descriptors','id');
  410 + $this->defineForeignKey('permission_descriptor_groups','group_id','groups_lookup','id');
  411 +
  412 + $this->defineForeignKey('permission_descriptor_roles','descriptor_id','permission_descriptors','id');
  413 + $this->defineForeignKey('permission_descriptor_roles','role_id','roles','id');
  414 +
  415 + $this->defineForeignKey('permission_descriptor_users','descriptor_id','permission_descriptors','id');
  416 + $this->defineForeignKey('permission_descriptor_users','user_id','users','id');
  417 +
  418 + $this->defineForeignKey('permission_dynamic_assignments','dynamic_condition_id','permission_dynamic_conditions','id');
  419 + $this->defineForeignKey('permission_dynamic_assignments','permission_id','permissions','id');
  420 +
  421 + $this->defineForeignKey('permission_dynamic_conditions','permission_object_id','permission_objects','id');
  422 + $this->defineForeignKey('permission_dynamic_conditions','group_id','groups_lookup','id');
  423 + $this->defineForeignKey('permission_dynamic_conditions','condition_id','saved_searches','id');
  424 +
  425 + $this->defineForeignKey('permission_lookup_assignments','permission_id','permissions','id');
  426 + $this->defineForeignKey('permission_lookup_assignments','permission_lookup_id','permission_lookups','id'); // duplicate
  427 + $this->defineForeignKey('permission_lookup_assignments','permission_descriptor_id','permission_descriptors','id');
  428 +
  429 + $this->defineForeignKey('plugin_rss','user_id','users','id');
  430 +
  431 + $this->defineForeignKey('quicklinks','user_id','users','id');
  432 +
  433 + $this->defineForeignKey('role_allocations','folder_id','folders','id');
  434 + $this->defineForeignKey('role_allocations','role_id', 'roles','id');
  435 + $this->defineForeignKey('role_allocations','permission_descriptor_id','permission_descriptors','id');
  436 +
  437 + $this->defineForeignKey('saved_searches','user_id','users','id');
  438 +
  439 + $this->defineForeignKey('search_document_user_link','document_id','documents','id');
  440 + $this->defineForeignKey('search_document_user_link','user_id','users','id');
  441 +
  442 + $this->defineForeignKey('search_saved','user_id','users','id');
  443 + $this->defineForeignKey('search_saved_events','document_id','documents','id');
  444 +
  445 + $this->defineForeignKey('time_period','time_unit_id','time_unit_lookup','id');
  446 +
  447 + $this->defineForeignKey('type_workflow_map','document_type_id','document_types_lookup','id');
  448 + $this->defineForeignKey('type_workflow_map','workflow_id','workflows','id');
  449 +
  450 + $this->defineForeignKey('units_lookup','folder_id','folders','id');
  451 +
  452 + $this->defineForeignKey('units_organisations_link','unit_id','units_lookup','id');
  453 + $this->defineForeignKey('units_organisations_link','organisation_id','organisations_lookup','id');
  454 +
  455 + $this->defineForeignKey('uploaded_files','userid','users','id');
  456 + $this->defineForeignKey('uploaded_files','document_id','documents','id');
  457 +
  458 + $this->defineForeignKey('user_history','user_id','users','id');
  459 +
  460 + $this->defineForeignKey('user_history_documents','document_id','documents','id');
  461 + $this->defineForeignKey('user_history_documents','user_id','users','id');
  462 +
  463 + $this->defineForeignKey('user_history_folders','folder_id','folders','id');
  464 + $this->defineForeignKey('user_history_folders','user_id','users','id');
  465 +
  466 + $this->defineForeignKey('users','authentication_source_id','authentication_sources','id');
  467 +
  468 + $this->defineForeignKey('users_groups_link', 'user_id','users','id');
  469 + $this->defineForeignKey('users_groups_link', 'group_id','groups_lookup', 'id');
  470 +
  471 + $this->defineForeignKey('workflow_documents','document_id', 'documents','id');
  472 + $this->defineForeignKey('workflow_documents','workflow_id', 'workflows','id');
  473 + $this->defineForeignKey('workflow_documents','state_id','workflow_states','id');
  474 +
  475 + $this->defineForeignKey('workflow_state_actions','state_id','workflow_states','id');
  476 +
  477 + $this->defineForeignKey('workflow_state_disabled_actions','state_id','workflow_states','id');
  478 +
  479 + $this->defineForeignKey('workflow_state_permission_assignments','permission_id','permissions','id');
  480 + $this->defineForeignKey('workflow_state_permission_assignments','permission_descriptor_id','permission_descriptors','id');
  481 + $this->defineForeignKey('workflow_state_permission_assignments','workflow_state_id','workflow_states','id');
  482 +
  483 + $this->defineForeignKey('workflow_state_transitions','state_id','workflow_states','id');
  484 + $this->defineForeignKey('workflow_state_transitions','transition_id','workflow_transitions','id');
  485 +
  486 + $this->defineForeignKey('workflow_states','workflow_id', 'workflows','id');
  487 + $this->defineForeignKey('workflow_states','inform_descriptor_id', 'permission_descriptors','id');
  488 +
  489 + $this->defineForeignKey('workflow_transitions','workflow_id','workflows','id');
  490 + $this->defineForeignKey('workflow_transitions','target_state_id','workflow_states','id');
  491 + $this->defineForeignKey('workflow_transitions','guard_permission_id','permissions','id');
  492 + $this->defineForeignKey('workflow_transitions','guard_condition_id','saved_searches','id');
  493 + $this->defineForeignKey('workflow_transitions','guard_group_id','groups_lookup','id');
  494 + $this->defineForeignKey('workflow_transitions','guard_role_id','roles','id');
  495 +
  496 + $this->defineForeignKey('workflow_trigger_instances','workflow_transition_id','workflow_transitions','id');
  497 +
  498 + $this->defineForeignKey('workflows','start_state_id','workflow_states','id');
  499 + }
  500 +
  501 + /**
  502 + * Adds indexes that are not defined automatically via foreign key constraints and also adds criteria such as uniqueness.
  503 + *
  504 + */
  505 + private function defineOtherIndexes()
  506 + {
  507 + $this->indexes = array();
  508 + $this->defineIndex('active_sessions', 'session_id');
  509 + $this->defineIndex('authentication_sources','namespace');
  510 +
  511 + $this->defineIndex('column_entries','view_namespace');
  512 +
  513 + $this->defineIndex('comment_searchable_text', 'body', 'FULLTEXT');
  514 +
  515 +
  516 + $this->defineIndex('dashlet_disables','dashlet_namespace');
  517 + $this->defineIndex('document_content_version','storage_path');
  518 +
  519 + $this->defineIndex('document_metadata_version','version_created');
  520 + $this->defineIndex('document_role_allocations', array('document_id', 'role_id'));
  521 +
  522 + $this->defineIndex('document_searchable_text','document_text', 'FULLTEXT');
  523 +
  524 + $this->defineIndex('document_text','document_text', 'FULLTEXT');
  525 + $this->defineIndex('document_transaction_text','document_text', 'FULLTEXT');
  526 +
  527 + $this->defineIndex('document_transaction_types_lookup','namespace', 'UNIQUE');
  528 +
  529 + $this->defineIndex('document_transactions','session_id');
  530 + $this->defineIndex('document_transactions','document_id');
  531 +
  532 + $this->defineIndex('document_types_lookup','name');
  533 +
  534 + $this->defineIndex('documents','created');
  535 + $this->defineIndex('documents','modified');
  536 + $this->defineIndex('documents','full_path','','(255)');
  537 + $this->defineIndex('documents','immutable');
  538 + $this->defineIndex('documents','checkedout');
  539 +
  540 + $this->defineIndex('document_content_version','filename','','(255)');
  541 + $this->defineIndex('document_content_version','size');
  542 +
  543 + $this->defineIndex('field_behaviour_options',array('behaviour_id','field_id'));
  544 +
  545 + $this->defineIndex('field_behaviours','name');
  546 +
  547 + $this->defineIndex('fieldsets','is_generic');
  548 + $this->defineIndex('fieldsets','is_complete');
  549 + $this->defineIndex('fieldsets','is_system');
  550 +
  551 + $this->defineIndex('field_orders','child_field_id', 'UNIQUE');
  552 +
  553 + $this->defineIndex('folder_searchable_text','folder_text' ,'FULLTEXT');
  554 +
  555 + $this->defineIndex('folder_transactions','folder_id');
  556 + $this->defineIndex('folder_transactions','session_id');
  557 + $this->defineIndex('folders', array('parent_id','name'));
  558 +
  559 + $this->defineIndex('groups_lookup','name', 'UNIQUE');
  560 + $this->defineIndex('groups_lookup', array('authentication_source_id','authentication_details_s1'));
  561 +
  562 + $this->defineIndex('interceptor_instances','interceptor_namespace');
  563 +
  564 + $this->defineIndex('metadata_lookup','disabled');
  565 +
  566 + $this->defineIndex('metadata_lookup_tree','metadata_lookup_tree_parent');
  567 +
  568 + $this->defineIndex('mime_types','filetypes');
  569 + $this->defineIndex('mime_types','mimetypes');
  570 +
  571 + $this->defineIndex('notifications','data_int_1');
  572 +
  573 + $this->defineIndex('organisations_lookup','name', 'UNIQUE');
  574 +
  575 + $this->defineIndex('permission_assignments', array('permission_object_id','permission_id'), 'UNIQUE');
  576 +
  577 + $this->defineIndex('permission_descriptor_groups','group_id');
  578 +
  579 + $this->defineIndex('permission_descriptor_roles','role_id');
  580 +
  581 + $this->defineIndex('permission_descriptor_users','user_id');
  582 +
  583 + $this->defineIndex('permission_descriptors','descriptor','UNIQUE');
  584 +
  585 + $this->defineIndex('permission_lookup_assignments', array('permission_lookup_id', 'permission_id'), 'UNIQUE');
  586 +
  587 + $this->defineIndex('permissions','name', 'UNIQUE');
  588 +
  589 + $this->defineIndex('plugins','namespace','UNIQUE');
  590 + $this->defineIndex('plugins','disabled');
  591 +
  592 + $this->defineIndex('plugin_helper','namespace');
  593 + $this->defineIndex('plugin_helper','plugin');
  594 + $this->defineIndex('plugin_helper','classtype');
  595 +
  596 +
  597 + $this->defineIndex('quicklinks','target_id');
  598 +
  599 + $this->defineIndex('roles','name','UNIQUE');
  600 + $this->defineIndex('saved_searches','namespace','UNIQUE');
  601 +
  602 + $this->defineIndex('scheduler_tasks','task', 'UNIQUE');
  603 +
  604 + $this->defineIndex('system_settings','name', 'UNIQUE');
  605 +
  606 + $this->defineIndex('units_lookup','name' ,'UNIQUE');
  607 + $this->defineIndex('units_lookup','folder_id' ,'UNIQUE');
  608 +
  609 + $this->defineIndex('upgrades','descriptor');
  610 + $this->defineIndex('upgrades','parent');
  611 +
  612 + $this->defineIndex('user_history','action_namespace');
  613 + $this->defineIndex('user_history','datetime');
  614 + $this->defineIndex('user_history','session_id');
  615 +
  616 + $this->defineIndex('user_history_documents', array('user_id','document_id'));
  617 +
  618 + $this->defineIndex('user_history_folders', array('user_id','folder_id'));
  619 +
  620 + $this->defineIndex('users','username' ,'UNIQUE');
  621 + $this->defineIndex('users','authentication_source_id');
  622 + $this->defineIndex('users','last_login');
  623 + $this->defineIndex('users','disabled');
  624 +
  625 + $this->defineIndex('workflow_states','name');
  626 + $this->defineIndex('workflow_states','inform_descriptor_id'); //?
  627 +
  628 + $this->defineIndex('workflow_transitions',array('workflow_id','name'), 'UNIQUE');
  629 + $this->defineIndex('workflow_transitions','name');
  630 + $this->defineIndex('workflow_transitions','guard_permission_id'); //?
  631 +
  632 + $this->defineIndex('workflow_trigger_instances','namespace');
  633 +
  634 + $this->defineIndex('workflows','name', 'UNIQUE');
  635 + }
  636 +
  637 + private function definePrimaryKey($table, $primaryKey)
  638 + {
  639 + $definition = new stdClass();
  640 + $definition->table = $table;
  641 + $definition->primaryKey = $primaryKey;
  642 + $this->primaryKeys[] = $definition;
  643 + }
  644 +
  645 + private function defineForeignKey($table, $field, $otherTable, $otherField, $onDelete='cascade', $onUpdate='cascade')
  646 + {
  647 + $definition = new stdClass();
  648 + $definition->table = $table;
  649 + $definition->field = $field;
  650 + $definition->otherTable = $otherTable;
  651 + $definition->otherField = $otherField;
  652 + $definition->onDelete = $onDelete;
  653 + $definition->onUpdate = $onUpdate;
  654 + $this->foreignKeys[] = $definition;
  655 + }
  656 +
  657 + private function defineIndex($table, $fields, $type='', $extra='')
  658 + {
  659 + $definition = new stdClass();
  660 + $definition->table = $table;
  661 + $definition->fields = $fields;
  662 + $definition->type = $type;
  663 + $definition->extra = $extra;
  664 + $this->indexes[] = $definition;
  665 + }
  666 +
  667 + public function createPrimaryKeys()
  668 + {
  669 + foreach($this->primaryKeys as $primaryKey)
  670 + {
  671 + $this->createPrimaryKey($primaryKey->table, $primaryKey->primaryKey);
  672 + }
  673 + }
  674 +
  675 + /**
  676 + * Add a primary key to a table.
  677 + *
  678 + * @param string $tablename
  679 + * @param string $primaryKey
  680 + */
  681 + private function createPrimaryKey($tablename, $primaryKey)
  682 + {
  683 + if (!array_key_exists($tablename, $this->schema))
  684 + {
  685 + // if we don't know about the table, possibly it is in the commercial version.
  686 + // exit gracefully.
  687 + return;
  688 + }
  689 +
  690 + if (is_array($primaryKey))
  691 + {
  692 + $primaryKey = implode(',', $primaryKey);
  693 + }
  694 +
  695 + $sql="ALTER TABLE $tablename ADD PRIMARY KEY ($primaryKey)";
  696 + $this->_exec($sql, false);
  697 +
  698 + if (strpos($primaryKey,',') === false)
  699 + {
  700 + // for some reason, there seems to be a problem periodically when adding foreign key constraints
  701 + // unless there is a unique key. just a primary key isn't good enough for some reason. so for now,
  702 + // we add the unique key, doubling up the effort of the primary key. we can drop these indexes again
  703 + // later after the constraints have been added.
  704 + $this->primary[$tablename] = $primaryKey;
  705 + $sql="ALTER TABLE $tablename ADD UNIQUE KEY ($primaryKey)";
  706 + $this->_exec($sql);
  707 + }
  708 + }
  709 +
  710 + public function createForeignKeys()
  711 + {
  712 + foreach($this->foreignKeys as $foreignKey)
  713 + {
  714 + $this->createForeignKey($foreignKey->table,$foreignKey->field,$foreignKey->otherTable,$foreignKey->otherField,$foreignKey->onDelete, $foreignKey->onUpdate);
  715 + }
  716 + }
  717 +
  718 + /**
  719 + * Add a foreign key constraint for a table.
  720 + *
  721 + * @param string $table
  722 + * @param string $field
  723 + * @param string $othertable
  724 + * @param string $otherfield
  725 + * @param string $ondelete
  726 + * @param string $onupdate
  727 + */
  728 + private function createForeignKey($table, $field, $otherTable, $otherField, $onDelete='cascade', $onUpdate='cascade')
  729 + {
  730 + if (!array_key_exists($table, $this->schema) || !array_key_exists($otherTable, $this->schema))
  731 + {
  732 + // if we don't know about the tables, possibly it is in the commercial version.
  733 + // exit gracefully.
  734 + return;
  735 + }
  736 +
  737 + $this->fixForeignKey($table, $field, $otherTable, $otherField);
  738 +
  739 + $sql = "ALTER TABLE $table ADD FOREIGN KEY ($field) REFERENCES $otherTable ($otherField) ";
  740 + if ($onDelete != '')
  741 + {
  742 + $sql .= " ON DELETE $onDelete";
  743 + }
  744 + if ($onUpdate != '')
  745 + {
  746 + $sql .= " ON UPDATE $onUpdate";
  747 + }
  748 + $this->_exec($sql);
  749 + }
  750 +
  751 + public function createIndexes()
  752 + {
  753 + foreach($this->indexes as $index)
  754 + {
  755 + $this->createIndex($index->table, $index->fields, $index->type, $index->extra);
  756 + }
  757 + $this->removeDuplicateIndexes();
  758 + }
  759 +
  760 + private function fixForeignKey($table, $field, $otherTable, $otherField)
  761 + {
  762 + if ($otherTable == 'users' && $otherField == 'id')
  763 + {
  764 + $this->createFixUser();
  765 + $sql = "UPDATE $table SET $field = -10 WHERE $field is not null and $field not in (select distinct id from users)";
  766 + $this->_exec($sql);
  767 + return;
  768 + }
  769 +
  770 + $sql = "DELETE FROM $table WHERE $field is not null and $field not in (select distinct $otherField FROM $otherTable)";
  771 + $this->_exec($sql);
  772 + }
  773 +
  774 + /**
  775 + * Add an index to a table.
  776 + *
  777 + * @param string $table
  778 + * @param array $fields
  779 + * @param string $type
  780 + * @param string $extra
  781 + */
  782 + private function createIndex($table, $fields, $type='', $extra='')
  783 + {
  784 + if (!array_key_exists($table, $this->schema))
  785 + {
  786 + // if we don't know about the tables, possibly it is in the commercial version.
  787 + // exit gracefully.
  788 + return;
  789 + }
  790 +
  791 + if (!is_array($fields))
  792 + {
  793 + $fields = array($fields);
  794 + }
  795 + $index = implode('_', $fields);
  796 + $fields = implode(',',$fields);
  797 + $sql = "ALTER TABLE $table ADD $type INDEX $index ($fields$extra) ";
  798 + $this->_exec($sql);
  799 + }
  800 +
  801 +
  802 + /**
  803 + * Drop all indexes and foreign key constraints from the system.
  804 + *
  805 + * @return int The number of elements cleared.
  806 + */
  807 + private function getDBSchema()
  808 + {
  809 + $this->schema = array();
  810 + $result = DBUtil::getResultArray('SHOW TABLES');
  811 + $tables=array();
  812 +
  813 + foreach($result as $table)
  814 + {
  815 + $keys = array_keys($table);
  816 +
  817 + $tablename = $table[$keys[0]];
  818 + if (substr($tablename,0,5) == 'zseq_')
  819 + {
  820 + continue;
  821 + }
  822 +
  823 + $stmt = DBUtil::getResultArray("SHOW CREATE TABLE $tablename;");
  824 +
  825 + $keys = array_keys($stmt[0]);
  826 +
  827 + $sql = $stmt[0][$keys[1]];
  828 +
  829 + $this->schema[$tablename] = $sql;
  830 + }
  831 + }
  832 +
  833 + private function dropForeignKey($tablename, $foreignKey)
  834 + {
  835 + $sql = "ALTER TABLE $tablename DROP FOREIGN KEY $foreignKey;";
  836 + return $this->_exec($sql);
  837 + }
  838 +
  839 + /**
  840 + * Drops foreign keys based on the current schema
  841 + *
  842 + * @return int
  843 + */
  844 + public function dropForeignKeys()
  845 + {
  846 + $dropped = 0;
  847 + foreach($this->schema as $tablename=>$schema)
  848 + {
  849 + $lines = explode("\n", $schema);
  850 + foreach($lines as $line)
  851 + {
  852 + if (strpos($line, 'CONSTRAINT') === false)
  853 + {
  854 + continue;
  855 + }
  856 + preg_match_all('(\`([^\`])*\`)',$line, $params);
  857 +
  858 + $constraint=substr($params[0][0],1,-1);
  859 + $table= substr($params[0][2],1,-1);
  860 +
  861 + ($this->dropForeignKey($tablename, $constraint));
  862 + $dropped++;
  863 + }
  864 + }
  865 + return $dropped;
  866 + }
  867 +
  868 + /**
  869 + * Drops primary keys based on the current schema
  870 + *
  871 + * @return int
  872 + */
  873 + public function dropPrimaryKeys()
  874 + {
  875 + $dropped = 0;
  876 + foreach($this->schema as $tablename=>$schema)
  877 + {
  878 + $lines = explode("\n", $schema);
  879 + foreach($lines as $line)
  880 + {
  881 + if (strpos($line, 'PRIMARY KEY') === false)
  882 + {
  883 + continue;
  884 + }
  885 +
  886 + ($this->dropPrimaryKey($tablename));
  887 + $dropped++;
  888 + }
  889 + }
  890 + return $dropped;
  891 + }
  892 +
  893 + /**
  894 + * Drops the primary key from a table
  895 + *
  896 + * @param string $tablename
  897 + */
  898 + private function dropPrimaryKey($tablename)
  899 + {
  900 + $sql = "ALTER TABLE $tablename DROP primary key;";
  901 + return $this->_exec($sql,false);
  902 + }
  903 +
  904 + /**
  905 + * Drops indexes based on the current schema
  906 + *
  907 + * @return int
  908 + */
  909 + public function dropIndexes()
  910 + {
  911 + $dropped = 0;
  912 + foreach($this->schema as $tablename=>$schema)
  913 + {
  914 + $lines = explode("\n", $schema);
  915 + foreach($lines as $line)
  916 + {
  917 + if (strpos($line, 'KEY') === false)
  918 + {
  919 + continue;
  920 + }
  921 +
  922 + if (strpos($line, 'PRIMARY KEY') !== false)
  923 + {
  924 + continue;
  925 + }
  926 +
  927 + if (strpos($line, 'FOREIGN KEY') !== false)
  928 + {
  929 + continue;
  930 + }
  931 +
  932 + preg_match_all('(\`([^\`])*\`)',$line, $params);
  933 +
  934 + $key = substr($params[0][0],1,-1);
  935 + ($this->dropIndex($tablename, $key));
  936 + $dropped++;
  937 + }
  938 + }
  939 + return $dropped;
  940 + }
  941 +
  942 +
  943 + /**
  944 + * Drop an index from the database.
  945 + *
  946 + * @param string $table
  947 + * @param string $field
  948 + */
  949 + function dropIndex($table, $field)
  950 + {
  951 + if (!is_array($fields)) $field = array($field);
  952 + $field = implode('_', $field);
  953 + $sql = "ALTER TABLE $table DROP INDEX $field";
  954 + $result = $this->_exec($sql);
  955 +
  956 + if (!$result)
  957 + {
  958 + print "...";
  959 + }
  960 +
  961 + return $result;
  962 + }
  963 +
  964 + /**
  965 + * Execute a db sql statement on the database.
  966 + *
  967 + * @param string $sql
  968 + * @return boolean
  969 + */
  970 + private function _exec($sql )
  971 + {
  972 + global $default;
  973 + if (!$this->persist)
  974 + {
  975 + print "$sql\n";
  976 + return;
  977 + }
  978 + $this->log("Action: $sql");
  979 + $rs = DBUtil::runQuery($sql, $default->_admindb );
  980 + if (PEAR::isError($rs))
  981 + {
  982 + $this->log("* " . $rs->getMessage());
  983 + return false;
  984 + }
  985 + return true;
  986 + }
  987 +
  988 + /**
  989 + * Logs a message to the log file
  990 + *
  991 + * @param string $msg
  992 + */
  993 + private function log($msg, $level='info')
  994 + {
  995 + global $default;
  996 + $default->log->$level('KTSchemaUtil: ' .$msg);
  997 + }
  998 +}
  999 +
  1000 +
  1001 +?>
0 \ No newline at end of file 1002 \ No newline at end of file
lib/upgrades/UpgradeFunctions.inc.php
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 37
38 require_once(KT_LIB_DIR . '/upgrades/Ini.inc.php'); 38 require_once(KT_LIB_DIR . '/upgrades/Ini.inc.php');
39 require_once(KT_DIR . '/plugins/ktcore/scheduler/scheduler.php'); 39 require_once(KT_DIR . '/plugins/ktcore/scheduler/scheduler.php');
  40 +require_once(KT_LIB_DIR . '/database/schema.inc.php');
40 41
41 class UpgradeFunctions { 42 class UpgradeFunctions {
42 var $upgrades = array( 43 var $upgrades = array(
@@ -56,6 +57,7 @@ class UpgradeFunctions { @@ -56,6 +57,7 @@ class UpgradeFunctions {
56 '3.1.5' => array('upgradeSavedSearches'), 57 '3.1.5' => array('upgradeSavedSearches'),
57 '3.1.6.3' => array('cleanupGroupMembership'), 58 '3.1.6.3' => array('cleanupGroupMembership'),
58 '3.5.0' => array('cleanupOldKTAdminVersionNotifier', 'updateConfigFile35', 'registerIndexingTasks'), 59 '3.5.0' => array('cleanupOldKTAdminVersionNotifier', 'updateConfigFile35', 'registerIndexingTasks'),
  60 + '3.5.2' => array('dropForeignKeys','dropPrimaryKeys','dropIndexes','createPrimaryKeys','createForeignKeys','createIndexes'),
59 ); 61 );
60 62
61 var $descriptions = array( 63 var $descriptions = array(
@@ -77,7 +79,13 @@ class UpgradeFunctions { @@ -77,7 +79,13 @@ class UpgradeFunctions {
77 'cleanupGroupMembership' => 'Cleanup any old references to missing groups, etc.', 79 'cleanupGroupMembership' => 'Cleanup any old references to missing groups, etc.',
78 'cleanupOldKTAdminVersionNotifier' => 'Cleanup any old files from the old KTAdminVersionNotifier', 80 'cleanupOldKTAdminVersionNotifier' => 'Cleanup any old files from the old KTAdminVersionNotifier',
79 'updateConfigFile35' => 'Update the config.ini file for 3.5', 81 'updateConfigFile35' => 'Update the config.ini file for 3.5',
80 - 'registerIndexingTasks'=>'Register the required indexing background tasks' 82 + 'registerIndexingTasks'=>'Register the required indexing background tasks',
  83 + 'dropForeignKeys'=>'Recreate db integrity: Drop foreign keys on the database',
  84 + 'dropPrimaryKeys'=>'Recreate db integrity:Drop primary keys on the database',
  85 + 'dropIndexes'=>'Recreate db integrity:Drop indexes on the database',
  86 + 'createPrimaryKeys'=>'Recreate db integrity:Create primary keys on the database',
  87 + 'createForeignKeys'=>'Recreate db integrity:Create foreign keys on the database',
  88 + 'createIndexes'=>'Recreate db integrity:Create indexes on the database'
81 ); 89 );
82 var $phases = array( 90 var $phases = array(
83 "setPermissionFolder" => 1, 91 "setPermissionFolder" => 1,
@@ -87,8 +95,51 @@ class UpgradeFunctions { @@ -87,8 +95,51 @@ class UpgradeFunctions {
87 "fixUnits" => 1, 95 "fixUnits" => 1,
88 'applyDiscussionUpgrade' => -1, 96 'applyDiscussionUpgrade' => -1,
89 'fixDocumentRoleAllocation' => -1, 97 'fixDocumentRoleAllocation' => -1,
  98 + 'dropForeignKeys'=>1,
  99 + 'dropPrimaryKeys'=>2,
  100 + 'dropIndexes'=>3,
  101 + 'createPrimaryKeys'=>4,
  102 + 'createForeignKeys'=>5,
  103 + 'createIndexes'=>6,
90 ); 104 );
91 105
  106 + function dropForeignKeys()
  107 + {
  108 + $schemautil = KTSchemaUtil::getSingleton();
  109 + $schemautil->dropForeignKeys();
  110 + }
  111 +
  112 + function dropPrimaryKeys()
  113 + {
  114 + $schemautil = KTSchemaUtil::getSingleton();
  115 + $schemautil->dropPrimaryKeys();
  116 + }
  117 +
  118 + function dropIndexes()
  119 + {
  120 + $schemautil = KTSchemaUtil::getSingleton();
  121 + $schemautil->dropIndexes();
  122 + }
  123 +
  124 + function createPrimaryKeys()
  125 + {
  126 + $schemautil = KTSchemaUtil::getSingleton();
  127 + $schemautil->createPrimaryKeys();
  128 + }
  129 +
  130 + function createForeignKeys()
  131 + {
  132 + $schemautil = KTSchemaUtil::getSingleton();
  133 + $schemautil->createForeignKeys();
  134 + }
  135 +
  136 + function createIndexes()
  137 + {
  138 + $schemautil = KTSchemaUtil::getSingleton();
  139 + $schemautil->createIndexes();
  140 + }
  141 +
  142 +
92 // {{{ _setPermissionFolder 143 // {{{ _setPermissionFolder
93 function _setPermissionFolder($iFolderId) { 144 function _setPermissionFolder($iFolderId) {
94 global $default; 145 global $default;