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 39 /*
40 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 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 46 chdir(dirname(__FILE__));
49 47 require_once('../config/dmsDefaults.php');
  48 +require_once(KT_LIB_DIR . '/database/schema.inc.php');
50 49  
51 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 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 1002 \ No newline at end of file
... ...
lib/upgrades/UpgradeFunctions.inc.php
... ... @@ -37,6 +37,7 @@
37 37  
38 38 require_once(KT_LIB_DIR . '/upgrades/Ini.inc.php');
39 39 require_once(KT_DIR . '/plugins/ktcore/scheduler/scheduler.php');
  40 +require_once(KT_LIB_DIR . '/database/schema.inc.php');
40 41  
41 42 class UpgradeFunctions {
42 43 var $upgrades = array(
... ... @@ -56,6 +57,7 @@ class UpgradeFunctions {
56 57 '3.1.5' => array('upgradeSavedSearches'),
57 58 '3.1.6.3' => array('cleanupGroupMembership'),
58 59 '3.5.0' => array('cleanupOldKTAdminVersionNotifier', 'updateConfigFile35', 'registerIndexingTasks'),
  60 + '3.5.2' => array('dropForeignKeys','dropPrimaryKeys','dropIndexes','createPrimaryKeys','createForeignKeys','createIndexes'),
59 61 );
60 62  
61 63 var $descriptions = array(
... ... @@ -77,7 +79,13 @@ class UpgradeFunctions {
77 79 'cleanupGroupMembership' => 'Cleanup any old references to missing groups, etc.',
78 80 'cleanupOldKTAdminVersionNotifier' => 'Cleanup any old files from the old KTAdminVersionNotifier',
79 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 90 var $phases = array(
83 91 "setPermissionFolder" => 1,
... ... @@ -87,8 +95,51 @@ class UpgradeFunctions {
87 95 "fixUnits" => 1,
88 96 'applyDiscussionUpgrade' => -1,
89 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 143 // {{{ _setPermissionFolder
93 144 function _setPermissionFolder($iFolderId) {
94 145 global $default;
... ...