40 function parse_tables_xml($xml_file)
45 $root =
new SimpleXMLElement($xml_file, LIBXML_NOCDATA, TRUE);
46 }
catch (Exception $e) {
47 throw new Exception(
'Could not parse tables XML file: '.$e->getMessage());
50 if (($root->getName() !=
'schema') || !isset($root->tables) || !isset($root->sequences)) {
51 throw new Exception(
'Tables XML file is not valid.');
52 trigger_localised_error(
'SYS0012', E_USER_WARNING);
57 $info[
'tables'] = Array();
58 $info[
'sequences'] = Array();
62 foreach ($root->tables->table as $table) {
63 $table_name = (string)$table->attributes()->name;
65 $info[
'tables'][$table_name] = Array();
66 $info[
'tables'][$table_name][
'rollback'] = (($table->attributes()->{
'require_rollback'} == 1) ? TRUE : FALSE);
69 $info[
'tables'][$table_name][
'columns'] = Array();
71 foreach ($table->columns->column as $table_column) {
72 $column_name = (string)$table_column->attributes()->name;
74 $info[
'tables'][$table_name][
'columns'][$column_name] = Array();
75 $info[
'tables'][$table_name][
'columns'][$column_name][
'allow_null'] = (($table_column->attributes()->{
'allow_null'} == 1) ? TRUE : FALSE);
82 foreach ($table_column->children() as $column_var) {
83 switch (strtolower($column_var->getName())) {
87 if (is_null($type)) $type = (
string)$column_var;
89 case 'type_variations' :
91 foreach ($column_var->children() as $variation) {
93 $type = (string)$variation;
99 if (trim((
string)$column_var) !=
'') {
100 $default = (string)$column_var;
108 $info[
'tables'][$table_name][
'columns'][$column_name][
'type'] = $type;
109 $info[
'tables'][$table_name][
'columns'][$column_name][
'default'] = $default;
113 $info[
'tables'][$table_name][
'primary_key'] = Array();
114 $info[
'tables'][$table_name][
'unique_key'] = Array();
116 if (isset($table->keys) && (count($table->keys->children()) > 0)) {
117 foreach ($table->keys->children() as $table_key) {
118 $index_db_type = $table_key->attributes()->db;
124 $key_columns = Array();
125 foreach ($table_key->column as $table_key_column) {
126 $col_name = (string)$table_key_column->attributes()->name;
127 $key_columns[] = $col_name;
130 if ($table_key->getName() ==
'primary_key') {
131 $info[
'tables'][$table_name][
'primary_key'][] = $col_name;
133 if ($table_key->getName() ==
'unique_key') {
134 $info[
'tables'][$table_name][
'unique_key'][] = $col_name;
143 if (!empty($table->indexes->index)) {
144 foreach ($table->indexes->index as $table_index) {
147 $index_cols = Array();
148 foreach ($table_index->column as $table_index_column) {
149 $index_cols[] = (string)$table_index_column->attributes()->name;
153 $index_name = isset($table_index->attributes()->name) ? (
string)$table_index->attributes()->name : reset($index_cols);
154 $index_type = isset($table_index->attributes()->type) ? (
string)$table_index->attributes()->type : NULL;
155 $index_db_type = isset($table_index->attributes()->db) ? (
string)$table_index->attributes()->db : NULL;
158 'columns' => $index_cols,
159 'type' => $index_type,
160 'db_type' => $index_db_type,
162 $info['tables'][$table_name]['indexes'][$index_name] = $index_info;
168 foreach ($root->sequences->sequence as $sequence) {
169 $sequence_name = (string)$sequence->attributes()->name;
170 $info[
'sequences'][] = $sequence_name;
189 function create_index($tablename, $columns, $index_name=NULL, $index_type=NULL)
192 if (is_null($index_name)) $index_name = implode(
'_', $columns);
196 $sql =
'CREATE INDEX sq_'.substr($tablename.
'_'.$index_name, 0, 27).
' ON sq_'.$tablename;
197 if (!empty($index_type)) {
199 $sql .=
'('.implode(
', ', $columns).
') indextype is '.$index_type;
201 $sql .=
' USING '.$index_type.
'('.implode(
', ', $columns).
')';
204 $sql .=
' ('.implode(
', ', $columns).
')';
227 function create_table($tablename, $table_info)
230 $sql =
'CREATE TABLE sq_'.$tablename.
'(';
234 foreach ($table_info[
'columns'] as $col_name => $col_info) {
235 if ($i++ != 0) $sql .=
',';
236 $sql .= $col_name.
' '.$col_info[
'type'];
237 if (!is_null($col_info[
'default'])) {
238 $sql .=
' DEFAULT '.$col_info[
'default'];
240 if (!$col_info[
'allow_null']) $sql .=
' NOT NULL';
244 if (!empty($table_info[
'primary_key'])) {
245 $sql .=
', CONSTRAINT '.$tablename.
'_pk PRIMARY KEY ('.implode(
',', $table_info[
'primary_key']).
')';
247 if (!empty($table_info[
'unique_key'])) {
248 $sql .=
', UNIQUE ('.implode(
',', $table_info[
'unique_key']).
')';
255 $sql .=
' ROWDEPENDENCIES';
277 function get_database_indexes($tablename, $include_rollback=TRUE)
282 if ($db_type ==
'pgsql') {
288 tablename = :std_table';
289 if ($include_rollback) {
290 $sql .=
' OR tablename = :rollback_table';
292 }
else if ($db_type ==
'oci') {
298 LOWER(table_name) = :std_table';
299 if ($include_rollback) {
300 $sql .=
' OR LOWER(table_name) = :rollback_table';
313 for (reset($indexes_in_db); NULL !== ($key = key($indexes_in_db)); next($indexes_in_db)) {
314 $indexes_in_db[$key] = strtolower($indexes_in_db[$key]);
317 return $indexes_in_db;
328 function get_database_sequences()
333 if ($db_type ==
'pgsql') {
334 $sql =
'SELECT c.relname
335 FROM pg_class c, pg_user u
336 WHERE c.relowner = u.usesysid
337 AND c.relkind = \'S\'
338 AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname)
339 AND c.relname !~ :pattern';
348 }
else if ($db_type ==
'oci') {
349 $sql =
'SELECT sequence_name FROM user_sequences';
364 for (reset($sequences_in_db); NULL !== ($key = key($sequences_in_db)); next($sequences_in_db)) {
365 $sequences_in_db[$key] = strtolower($sequences_in_db[$key]);
368 return $sequences_in_db;
379 function get_database_tables()
384 if ($db_type ==
'pgsql') {
386 $sql =
'SELECT c.relname
387 FROM pg_class c, pg_user u
388 WHERE c.relowner = u.usesysid
389 AND c.relkind = \'r\'
390 AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname)
391 AND c.relname !~ :pattern
395 WHERE c.relkind = \'r\'
396 AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname)
397 AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner)
398 AND c.relname !~ \'^pg_\'';
407 }
else if ($db_type ==
'oci') {
408 $sql =
'SELECT table_name FROM user_tables';
423 for (reset($tables_in_db); NULL !== ($key = key($tables_in_db)); next($tables_in_db)) {
424 $tables_in_db[$key] = strtolower($tables_in_db[$key]);
426 return $tables_in_db;
441 function db_install($xml_file, $verbose=TRUE)
444 $info = parse_tables_xml($xml_file);
445 $tables_in_db = get_database_tables();
450 $current_cached_tables = Array();
451 if (file_exists(SQ_DATA_PATH.
'/private/db/table_columns.inc')) {
452 require SQ_DATA_PATH.
'/private/db/table_columns.inc';
453 $current_cached_tables = $tables;
456 $created_tables = Array();
457 $created_indexes = Array();
459 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
461 foreach ($info[
'tables'] as $tablename => $table_info) {
465 if ($tablename ==
'cache') {
467 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
468 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'dbcache');
469 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
471 $old_tables_in_db = $tables_in_db;
472 $tables_in_db = get_database_tables();
476 if (!in_array(
'sq_'.$tablename, $tables_in_db)) {
477 create_table($tablename, $table_info);
478 $created_tables[] =
'sq_'.$tablename;
481 if ($table_info[
'rollback']) {
488 if (!in_array(
'sq_rb_'.$tablename, $tables_in_db)) {
489 $rb_table_info = $table_info;
490 $rb_col[
'sq_eff_from'] = Array(
491 'type' => $date_type,
493 'allow_null' => FALSE,
495 $rb_col[
'sq_eff_to'] = Array(
496 'type' => $date_type,
498 'allow_null' => TRUE,
503 $rb_table_info[
'columns'] = array_merge($rb_col, $rb_table_info[
'columns']);
505 if (!empty($rb_table_info[
'primary_key'])) {
506 foreach ($rb_table_info[
'primary_key'] as $field) {
509 $table_info[
'rb_indexes'][$field] = Array(
510 'columns' => Array($field),
515 array_unshift($rb_table_info[
'primary_key'],
'sq_eff_from');
517 if (!empty($rb_table_info[
'unique_key'])) {
518 foreach ($rb_table_info[
'unique_key'] as $field) {
520 $table_info[
'rb_indexes'][$field] = Array(
521 'columns' => Array($field),
526 array_unshift($rb_table_info[
'unique_key'],
'sq_eff_from');
530 $table_info[
'rb_indexes'][
'effrm'] = Array(
531 'columns' => Array(
'sq_eff_from'),
535 $table_info[
'rb_indexes'][
'efto'] = Array(
536 'columns' => Array(
'sq_eff_to'),
541 create_table(
'rb_'.$tablename, $rb_table_info);
542 $created_tables[] =
'sq_rb_'.$tablename;
549 $indexes_in_db = get_database_indexes($tablename, TRUE);
551 if (!empty($table_info[
'indexes'])) {
552 foreach ($table_info[
'indexes'] as $index_name => $index_info) {
554 if (!in_array(
'sq_'.$tablename.
'_'.$index_name, $indexes_in_db)) {
555 create_index($tablename, $index_info[
'columns'], $index_name, $index_info[
'type']);
556 $created_indexes[] =
'sq_'.$tablename.
'_'.$index_name;
558 if ($table_info[
'rollback']) {
559 if (!in_array(
'sq_rb_'.$tablename.
'_'.$index_name, $indexes_in_db)) {
560 create_index(
'rb_'.$tablename, $index_info[
'columns'], $index_name, $index_info[
'type']);
561 $created_indexes[] =
'sq_rb_'.$tablename.
'_'.$index_name;
572 $indexes_in_db = get_database_indexes($tablename, TRUE);
575 if (($table_info[
'rollback']) && (!empty($table_info[
'rb_indexes']))) {
576 foreach ($table_info[
'rb_indexes'] as $index_name => $index_info) {
577 if (!in_array(
'sq_rb_'.$tablename.
'_'.$index_name, $indexes_in_db)) {
578 create_index(
'rb_'.$tablename, $index_info[
'columns'], $index_name, $index_info[
'type']);
579 $created_indexes[] =
'sq_rb_'.$tablename.
'_'.$index_name;
584 if ($tablename ==
'cache') {
586 $tables_in_db = $old_tables_in_db;
587 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
588 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
589 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
595 $table_names = empty($created_tables) ?
'No new tables added' :
'New Tables:'.
"\n".implode($created_tables,
"\n");
596 pre_echo(
"TABLE CREATION COMPLETE\n".$table_names);
598 $index_names = empty($created_indexes) ?
'No Indexes added' :
'New Indexes:'.
"\n".implode($created_indexes,
"\n");
599 pre_echo(
"INDEX CREATION COMPLETE\n".$index_names);
604 $sequences_in_db = get_database_sequences();
605 foreach ($info[
'sequences'] as $sequence_name) {
606 if (in_array(
'sq_'.$sequence_name.
'_seq', $sequences_in_db)) {
612 $sql =
'CREATE SEQUENCE sq_'.$sequence_name.
'_seq';
619 if ($verbose) pre_echo(
'SEQUENCE CREATION COMPLETE');
623 $cached_sequences_string =
'<'.
'?php $sequences = '.var_export($info[
'sequences'], TRUE).
'; ?'.
'>';
624 if (!string_to_file($cached_sequences_string, SQ_DATA_PATH.
'/private/db/sequences.inc')) {
625 trigger_localised_error(
'SYS0010', E_USER_WARNING);
626 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
632 $cached_table_info = $info[
'tables'];
633 foreach ($cached_table_info as $table => $info) {
634 $cached_table_info[$table][
'columns'] = array_keys($info[
'columns']);
636 $cached_table_info = array_merge($current_cached_tables, $cached_table_info);
638 $cached_tables_string =
'<'.
'?php $tables = '.var_export($cached_table_info, TRUE).
'; ?'.
'>';
639 if (!string_to_file($cached_tables_string, SQ_DATA_PATH.
'/private/db/table_columns.inc')) {
640 trigger_localised_error(
'SYS0011', E_USER_WARNING);
641 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
646 if (SQ_CONF_ROLLBACK_ENABLED) {
647 install_rollback_triggers($cached_table_info, $verbose);
649 uninstall_rollback_triggers();
652 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
669 function grant_secondary_user_perms($verbose=TRUE)
672 $db_conf = require(SQ_SYSTEM_ROOT.
'/data/private/conf/db.inc');
675 $primary_dsn = !isset($db_conf[
'db'][
'DSN']) && isset($db_conf[
'db'][0]) ? $db_conf[
'db'][0] : $db_conf[
'db'];
676 $secondary_dsn = $db_conf[
'db2'];
677 $tertiary_dsn = $db_conf[
'db3'];
678 $cache_dsn = $db_conf[
'dbcache'];
679 $search_dsn = $db_conf[
'dbsearch'];
680 $grant_sql =
'SELECT sq_grant_access(:user, :access_type)';
693 if ($primary_dsn[
'user'] != $secondary_dsn[
'user']) {
705 if (($primary_dsn[
'user'] != $tertiary_dsn[
'user']) && ($secondary_dsn[
'user'] != $tertiary_dsn[
'user'])) {
717 pre_echo(
'PGSQL SECONDARY AND TERTIARY USER PERMISSIONS FIXED');
721 $diff_dbcache_user = $primary_dsn[
'user'] != $cache_dsn[
'user'] && $secondary_dsn[
'user'] != $cache_dsn[
'user'] && $tertiary_dsn[
'user'] != $cache_dsn[
'user'];;
722 $diff_dbcache_dsn = $primary_dsn[
'DSN'] != $cache_dsn[
'DSN'];
725 if ($postgres_db && !is_null($cache_dsn) && ($diff_dbcache_user || $diff_dbcache_dsn)) {
727 if ($diff_dbcache_dsn) {
728 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'dbcache');
729 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
742 pre_echo(
'PGSQL CACHE USER PERMISSIONS FIXED');
745 if ($diff_dbcache_dsn) {
746 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
747 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
751 $diff_dbsearch_user = $primary_dsn[
'user'] != $search_dsn[
'user'] && $secondary_dsn[
'user'] != $search_dsn[
'user'] && $tertiary_dsn[
'user'] != $search_dsn[
'user'] && $cache_dsn[
'user'] != $search_dsn[
'user'];
752 $diff_dbsearch_dsn = $primary_dsn[
'DSN'] != $search_dsn[
'DSN'];
755 if ($postgres_db && !is_null($search_dsn) && ($diff_dbsearch_user || $diff_dbsearch_dsn)) {
758 if ($diff_dbsearch_dsn) {
759 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'dbsearch');
760 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
773 pre_echo(
'PGSQL SEARCH USER PERMISSIONS FIXED');
776 if ($diff_dbsearch_dsn) {
777 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
778 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
797 function install_stored_relations($relations, $package=NULL, $verbose=TRUE)
802 if (is_null($package)) {
805 $subdir =
'packages/'.$package;
807 $fns_file = SQ_SYSTEM_ROOT.
'/'.$subdir.
'/'.$db_type.
'_'.$relations.
'.xml';
811 if (!file_exists($fns_file)) {
812 $fns_file = SQ_SYSTEM_ROOT.
'/'.$subdir.
'/common_'.$relations.
'.xml';
815 if (file_exists($fns_file)) {
819 $root =
new SimpleXMLElement($fns_file, LIBXML_NOCDATA, TRUE);
820 }
catch (Exception $e) {
821 throw new Exception(
'Could not parse stored relations file: '.$e->getMessage());
824 if ($root->getName() !=
'sql') {
825 throw new Exception(
'Cannot install stored relations file: expected root element "sql", found "'.$root->getName().
'".');
826 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
830 $display_names = Array();
832 foreach ($root->children() as $sql_element) {
833 $element_name = $sql_element->getName();
834 if ($sql_element->getName() !=
'sql_element') {
835 throw new Exception(
'Cannot install stored relations file: expected element "sql_element", found "'.$sql_element->getName().
'".');
838 $display_names[] = isset($sql_element->attributes()->{
'display_name'}) ? $sql_element->attributes()->{
'display_name'} :
'<Unknown Element>';
839 $sql = trim(xml_entity_decode((
string)$sql_element));
851 if (is_null($package)) {
852 pre_echo(strtoupper($db_type).
' STORED '.strtoupper($relations).
' CREATED'.
"\n".implode(
"\n", $display_names));
854 pre_echo(strtoupper($db_type).
' STORED '.strtoupper($relations).
' FOR PACKAGE '.$package.
' CREATED'.
"\n".implode(
"\n", $display_names));
868 function get_installed_rollback_triggers()
873 $sql =
'SELECT trigger_name FROM user_triggers WHERE LOWER(trigger_name)';
875 $sql =
'SELECT tgname FROM pg_trigger WHERE tgname';
877 $sql .=
' LIKE :trigger_pattern';
906 function install_rollback_triggers($table_columns, $verbose=TRUE, $override=FALSE)
909 $curr_triggers = Array();
910 $installed_triggers = Array();
916 $curr_triggers = get_installed_rollback_triggers();
918 for (reset($curr_triggers); NULL !== ($key = key($curr_triggers)); next($curr_triggers)) {
919 $curr_triggers[$key] = strtolower($curr_triggers[$key]);
922 foreach ($table_columns as $table_name => $table_info) {
924 if (!isset($table_info[
'rollback']) || !$table_info[
'rollback']) {
927 $rollback_table =
'sq_rb_'.$table_name;
928 $trigger_name = strtolower(
'sq_'.$table_name.
'_rb_trg');
929 $table =
'sq_'.$table_name;
933 if (in_array($trigger_name, $curr_triggers))
continue;
936 $sql =
'CREATE TRIGGER '.$trigger_name.
937 ' BEFORE INSERT OR UPDATE OR DELETE ON '.$table.
941 $sql .=
' DECLARE BEGIN ';
945 $sql .=
'IF DBMS_REPUTIL.FROM_REMOTE = TRUE THEN
951 $sql .=
'sq_common_pkg.sq_set_rollback_timestamp;';
953 $if_inserting =
'IF INSERTING THEN ';
954 $if_updating =
'IF UPDATING THEN ';
955 $if_deleting =
'IF DELETING THEN ';
957 $get_timestamp_fn =
'sq_common_pkg.sq_get_rollback_timestamp';
962 $sql .=
'EXECUTE PROCEDURE '.$trigger_name.
'_fn();';
968 $sql .=
'CREATE OR REPLACE FUNCTION '.$trigger_name.
"_fn() RETURNS trigger AS '";
970 $sql .=
'rollback_timestamp timestamp;';
975 $sql .=
"EXECUTE ''SELECT sq_get_rollback_timestamp();'' INTO rollback_timestamp;";
977 $if_inserting =
"IF TG_OP = ''INSERT'' THEN ";
978 $if_updating =
"IF TG_OP = ''UPDATE'' THEN ";
979 $if_deleting =
"IF TG_OP = ''DELETE'' THEN ";
984 $get_timestamp_fn =
'rollback_timestamp';
987 $old_primary_key_where =
'';
988 $new_primary_key_where =
'';
989 $primary_key_where =
'';
993 foreach ($table_info[
'primary_key'] as $key) {
994 $primary_key_where =
'';
995 if ($i++ != 0) $primary_key_where =
' AND ';
996 $primary_key_where .= $key.
' = ';
1001 $old_primary_key_where .= $primary_key_where.
'OLD.'.$key;
1002 $new_primary_key_where .= $primary_key_where.
'NEW.'.$key;
1004 $old_primary_key_where .=
';';
1005 $new_primary_key_where .=
';';
1012 $col_string =
' (sq_eff_from, sq_eff_to,';
1013 $new_val_string =
' ('.$get_timestamp_fn.
',null,';
1014 $old_val_string = $new_val_string;
1015 $update_string =
'';
1019 foreach ($table_info[
'columns'] as $column) {
1022 $is_unique_key = (isset($table_info[
'primary_key']) && in_array($column, $table_info[
'primary_key']));
1023 $is_unique_key |= (isset($table_info[
'unique_key']) && in_array($column, $table_info[
'unique_key']));
1024 $col_string .= $column;
1026 if (!$is_unique_key) $update_string .= $column.
' = ';
1031 $new_val_string .=
':';
1032 $old_val_string .=
':';
1033 if (!$is_unique_key) $update_string .=
':';
1035 $new_val_string .=
'NEW.'.$column;
1036 $old_val_string .=
'OLD.'.$column;
1037 if (!$is_unique_key) $update_string .=
'NEW.'.$column;
1039 if (++$i != count($table_info[
'columns'])) {
1041 $new_val_string .=
',';
1042 $old_val_string .=
',';
1043 if (!$is_unique_key) $update_string .=
',';
1048 $new_val_string .=
');';
1049 $old_val_string .=
');';
1051 $update_string = rtrim($update_string,
',');
1054 $not_found =
'SQL%NOTFOUND';
1056 $not_found =
'NOT FOUND';
1062 $remove_rollback_collision =
'DELETE FROM '.
1064 ' WHERE sq_eff_from = '.$get_timestamp_fn.
1065 ' AND '.$new_primary_key_where;
1070 $sql .= $if_inserting.
1071 $remove_rollback_collision.
1072 'INSERT INTO '.$rollback_table.
1073 $col_string.
' VALUES '.$new_val_string;
1082 $update_sql =
'UPDATE '.$rollback_table.
1083 ' SET sq_eff_to = '.$get_timestamp_fn.
1084 ' WHERE sq_eff_to IS NULL AND '.
1085 $old_primary_key_where;
1089 $replace_sql =
'UPDATE '.$rollback_table.
1090 ' SET '.$update_string.
1091 ' WHERE sq_eff_from = '.$get_timestamp_fn.
' AND '.$old_primary_key_where;
1093 if (trim($update_string) !=
'') {
1094 $sql .= $if_updating.
1096 ' IF '.$not_found.
' THEN '.
1098 'INSERT INTO '.$rollback_table.
1099 $col_string.
' VALUES '.$new_val_string.
1108 $sql .= $if_updating.
'RETURN NEW;END IF;';
1114 $sql .= $if_deleting.$update_sql;
1122 $sql .=
"' LANGUAGE plpgsql;";
1126 if (!$override) $sql = $sql.$trigger_sql;
1135 $installed_triggers[] = $trigger_name;
1140 $trigger_names = (!empty($installed_triggers)) ?
'New Triggers:'.
"\n".implode(
"\n", $installed_triggers) :
'No Triggers Installed';
1141 pre_echo(
'DATABASE TRIGGER CREATION COMPLETE'.
"\n".$trigger_names);
1153 function uninstall_rollback_triggers()
1155 $triggers = get_installed_rollback_triggers();
1156 if (!empty($triggers)) {
1158 foreach ($triggers as $trigger_name) {
1161 $sql =
'DROP TRIGGER '.$trigger_name;
1164 preg_match(
'/^sq_(.*)_rb_trg$/i', $trigger_name, $matches);
1165 $sql .=
' on sq_'.$matches[1].
' CASCADE';