3 * Upgrading and patching functions of database.
5 * Functions to allow safe database modifications
6 * during upgrading and patches.
8 * Copyright (C) 2008-2012 Rod Roark <rod@sunsetsystems.com>
10 * LICENSE: This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>.
22 * @author Rod Roark <rod@sunsetsystems.com>
23 * @author Brady Miller <brady.g.miller@gmail.com>
24 * @author Teny <teny@zhservices.com>
25 * @link https://www.open-emr.org
29 * Check if a Sql table exists.
31 * @param string $tblname Sql Table Name
32 * @return boolean returns true if the sql table exists
34 function tableExists($tblname)
36 $row = sqlQuery("SHOW TABLES LIKE '$tblname'");
45 * Check if a Sql column exists in a selected table.
47 * @param string $tblname Sql Table Name
48 * @param string $colname Sql Column Name
49 * @return boolean returns true if the sql column exists
51 function columnExists($tblname, $colname)
53 $row = sqlQuery("SHOW COLUMNS FROM $tblname LIKE '$colname'");
62 * Check if a Sql column has a certain type.
64 * @param string $tblname Sql Table Name
65 * @param string $colname Sql Column Name
66 * @param string $coltype Sql Column Type
67 * @return boolean returns true if the sql column is of the specified type
69 function columnHasType($tblname, $colname, $coltype)
71 $row = sqlQuery("SHOW COLUMNS FROM $tblname LIKE '$colname'");
76 return (strcasecmp($row['Type'], $coltype) == 0);
80 * Check if a Sql row exists. (with one value)
82 * @param string $tblname Sql Table Name
83 * @param string $colname Sql Column Name
84 * @param string $value Sql value
85 * @return boolean returns true if the sql row does exist
87 function tableHasRow($tblname, $colname, $value)
89 $row = sqlQuery("SELECT COUNT(*) AS count FROM $tblname WHERE " .
90 "$colname LIKE '$value'");
91 return $row['count'] ?
true : false;
95 * Check if a Sql row exists. (with two values)
97 * @param string $tblname Sql Table Name
98 * @param string $colname Sql Column Name 1
99 * @param string $value Sql value 1
100 * @param string $colname2 Sql Column Name 2
101 * @param string $value2 Sql value 2
102 * @return boolean returns true if the sql row does exist
104 function tableHasRow2D($tblname, $colname, $value, $colname2, $value2)
106 $row = sqlQuery("SELECT COUNT(*) AS count FROM $tblname WHERE " .
107 "$colname LIKE '$value' AND $colname2 LIKE '$value2'");
108 return $row['count'] ?
true : false;
112 * Check if a Sql row exists. (with three values)
114 * @param string $tblname Sql Table Name
115 * @param string $colname Sql Column Name 1
116 * @param string $value Sql value 1
117 * @param string $colname2 Sql Column Name 2
118 * @param string $value2 Sql value 2
119 * @param string $colname3 Sql Column Name 3
120 * @param string $value3 Sql value 3
121 * @return boolean returns true if the sql row does exist
123 function tableHasRow3D($tblname, $colname, $value, $colname2, $value2, $colname3, $value3)
125 $row = sqlQuery("SELECT COUNT(*) AS count FROM $tblname WHERE " .
126 "$colname LIKE '$value' AND $colname2 LIKE '$value2' AND $colname3 LIKE '$value3'");
127 return $row['count'] ?
true : false;
131 * Check if a Sql row exists. (with four values)
133 * @param string $tblname Sql Table Name
134 * @param string $colname Sql Column Name 1
135 * @param string $value Sql value 1
136 * @param string $colname2 Sql Column Name 2
137 * @param string $value2 Sql value 2
138 * @param string $colname3 Sql Column Name 3
139 * @param string $value3 Sql value 3
140 * @param string $colname4 Sql Column Name 4
141 * @param string $value4 Sql value 4
142 * @return boolean returns true if the sql row does exist
144 function tableHasRow4D($tblname, $colname, $value, $colname2, $value2, $colname3, $value3, $colname4, $value4)
146 $row = sqlQuery("SELECT COUNT(*) AS count FROM $tblname WHERE " .
147 "$colname LIKE '$value' AND $colname2 LIKE '$value2' AND $colname3 LIKE '$value3' AND $colname4 LIKE '$value4'");
148 return $row['count'] ?
true : false;
152 * Check if a Sql table has a certain index/key.
154 * @param string $tblname Sql Table Name
155 * @param string $colname Sql Index/Key
156 * @return boolean returns true if the sql tables has the specified index/key
158 function tableHasIndex($tblname, $colname)
160 $row = sqlQuery("SHOW INDEX FROM `$tblname` WHERE `Key_name` = '$colname'");
161 return (empty($row)) ?
false : true;
166 * Check if a table has a certain engine
168 * @param string $tblname database table Name
169 * @param string $engine engine name ( myisam, memory, innodb )...
170 * @return boolean true if the table has been created using specified engine
172 function tableHasEngine($tblname, $engine)
174 $row = sqlQuery('SELECT 1 FROM information_schema.tables WHERE table_name=? AND engine=? AND table_type="BASE TABLE"', array($tblname,$engine ));
175 return (empty($row)) ?
false : true;
181 * Check if a list exists.
183 * @param string $option_id Sql List Option ID
184 * @return boolean returns true if the list exists
186 function listExists($option_id)
188 $row = sqlQuery("SELECT * FROM list_options WHERE list_id = 'lists' AND option_id = ?", array($option_id));
196 * Function to migrate the Clickoptions settings (if exist) from the codebase into the database.
197 * Note this function is only run once in the sql upgrade script (from 4.1.1 to 4.1.2) if the
198 * issue_types sql table does not exist.
200 function clickOptionsMigrate()
202 // If the clickoptions.txt file exist, then import it.
203 if (file_exists(dirname(__FILE__
)."/../sites/".$_SESSION['site_id']."/clickoptions.txt")) {
204 $file_handle = fopen(dirname(__FILE__
)."/../sites/".$_SESSION['site_id']."/clickoptions.txt", "rb");
207 echo "Importing clickoption setting<br>";
208 while (!feof($file_handle)) {
209 $line_of_text = fgets($file_handle);
210 if (preg_match('/^#/', $line_of_text)) {
214 if ($line_of_text == "") {
218 $parts = explode('::', $line_of_text);
219 $parts[0] = trim(str_replace("\r\n", "", $parts[0]));
220 $parts[1] = trim(str_replace("\r\n", "", $parts[1]));
221 if ($parts[0] != $prev) {
222 $sql1 = "INSERT INTO list_options (`list_id`,`option_id`,`title`) VALUES (?,?,?)";
223 SqlStatement($sql1, array('lists',$parts[0].'_issue_list',ucwords(str_replace("_", " ", $parts[0])).' Issue List'));
227 $sql2 = "INSERT INTO list_options (`list_id`,`option_id`,`title`,`seq`) VALUES (?,?,?,?)";
228 SqlStatement($sql2, array($parts[0].'_issue_list', $parts[1], $parts[1], $seq));
233 fclose($file_handle);
237 * Function to create list Occupation.
238 * Note this function is only run once in the sql upgrade script if the list Occupation does not exist
240 function CreateOccupationList()
242 $res = sqlStatement("SELECT DISTINCT occupation FROM patient_data WHERE occupation <> ''");
243 while ($row = sqlFetchArray($res)) {
244 $records[] = $row['occupation'];
247 sqlStatement("INSERT INTO list_options (list_id, option_id, title) VALUES('lists', 'Occupation', 'Occupation')");
248 if (count($records)>0) {
250 foreach ($records as $key => $value) {
251 sqlStatement("INSERT INTO list_options ( list_id, option_id, title, seq) VALUES ('Occupation', ?, ?, ?)", array($value, $value, ($seq+
10)));
257 * Function to create list reaction.
258 * Note this function is only run once in the sql upgrade script if the list reaction does not exist
260 function CreateReactionList()
262 $res = sqlStatement("SELECT DISTINCT reaction FROM lists WHERE reaction <> ''");
263 while ($row = sqlFetchArray($res)) {
264 $records[] = $row['reaction'];
267 sqlStatement("INSERT INTO list_options (list_id, option_id, title) VALUES('lists', 'reaction', 'Reaction')");
268 if (count($records)>0) {
270 foreach ($records as $key => $value) {
271 sqlStatement("INSERT INTO list_options ( list_id, option_id, title, seq) VALUES ('reaction', ?, ?, ?)", array($value, $value, ($seq+
10)));
278 * Function to add existing values in the immunization table to the new immunization manufacturer list
279 * This function will be executed always, but only missing values will ne inserted to the list
281 function CreateImmunizationManufacturerList()
283 $res = sqlStatement("SELECT DISTINCT manufacturer FROM immunizations WHERE manufacturer <> ''");
284 while ($row = sqlFetchArray($res)) {
285 $records[] = $row['manufacturer'];
288 sqlStatement("INSERT INTO list_options (list_id, option_id, title) VALUES ('lists','Immunization_Manufacturer','Immunization Manufacturer')");
289 if (count($records)>0) {
291 foreach ($records as $key => $value) {
292 sqlStatement("INSERT INTO list_options ( list_id, option_id, title, seq) VALUES ('Immunization_Manufacturer', ?, ?, ?)", array($value, $value, ($seq+
10)));
299 * This function is to populate the weno drug table if the feature is enabled before upgrade.
301 function ImportDrugInformation()
303 if ($GLOBALS['weno_rx_enable']) {
304 $drugs = file_get_contents('contrib/weno/erx_weno_drugs.sql');
305 $drugsArray = preg_split('/;\R/', $drugs);
307 // Settings to drastically speed up import with InnoDB
308 sqlStatementNoLog("SET autocommit=0");
309 sqlStatementNoLog("START TRANSACTION");
311 foreach ($drugsArray as $drug) {
315 sqlStatementNoLog($drug);
318 // Settings to drastically speed up import with InnoDB
319 sqlStatementNoLog("COMMIT");
320 sqlStatementNoLog("SET autocommit=1");
325 * Request to information_schema
327 * @param array $arg possible arguments: engine, table_name
328 * @return SQLStatement
330 function getTablesList($arg = array())
333 $sql = 'SELECT table_name FROM information_schema.tables WHERE table_schema=database() AND table_type="BASE TABLE"';
335 if (!empty($arg['engine'])) {
336 $binds[] = $arg['engine'];
337 $sql .= ' AND engine=?';
340 if (!empty($arg['table_name'])) {
341 $binds[] = $arg['table_name'];
342 $sql .= ' AND table_name=?';
345 $res = sqlStatement($sql, $binds);
348 while ($row = sqlFetchArray($res)) {
349 $records[ $row['table_name'] ] = $row['table_name'];
357 * Convert table engine.
358 * @param string $table
359 * @param string $engine
360 * ADODB will fail if there was an error during conversion
362 function MigrateTableEngine($table, $engine)
364 $r = sqlStatement('ALTER TABLE `'.$table.'` ENGINE=?', $engine);
368 function convertLayoutProperties()
370 $res = sqlStatement("SELECT DISTINCT form_id FROM layout_options ORDER BY form_id");
371 while ($row = sqlFetchArray($res)) {
372 $form_id = $row['form_id'];
374 'title' => 'Unknown',
378 'option_value' => '0',
380 if (substr($form_id, 0, 3) == 'LBF') {
382 "SELECT title, mapping, notes, activity, option_value FROM list_options WHERE list_id = 'lbfnames' AND option_id = ?",
388 if (empty($props['mapping'])) {
389 $props['mapping'] = 'Clinical';
391 } else if (substr($form_id, 0, 3) == 'LBT') {
393 "SELECT title, mapping, notes, activity, option_value FROM list_options WHERE list_id = 'transactions' AND option_id = ?",
399 if (empty($props['mapping'])) {
400 $props['mapping'] = 'Transactions';
402 } else if ($form_id == 'DEM') {
403 $props['title'] = 'Demographics';
404 } else if ($form_id == 'HIS') {
405 $props['title'] = 'History';
406 } else if ($form_id == 'FACUSR') {
407 $props['title'] = 'Facility Specific User Information';
408 } else if ($form_id == 'CON') {
409 $props['title'] = 'Contraception Issues';
410 } else if ($form_id == 'GCA') {
411 $props['title'] = 'Abortion Issues';
412 } else if ($form_id == 'SRH') {
413 $props['title'] = 'IPPF SRH Data';
416 $query = "INSERT INTO layout_group_properties SET " .
417 "grp_form_id = ?, " .
418 "grp_group_id = '', " .
420 "grp_mapping = ?, " .
421 "grp_activity = ?, " .
423 $sqlvars = array($form_id, $props['title'], $props['mapping'], $props['activity'], $props['option_value']);
424 if ($props['notes']) {
425 $jobj = json_decode($props['notes'], true);
426 if (isset($jobj['columns'])) {
427 $query .= ", grp_columns = ?";
428 $sqlvars[] = $jobj['columns'];
430 if (isset($jobj['size'])) {
431 $query .= ", grp_size = ?";
432 $sqlvars[] = $jobj['size'];
434 if (isset($jobj['issue'])) {
435 $query .= ", grp_issue_type = ?";
436 $sqlvars[] = $jobj['issue'];
438 if (isset($jobj['aco'])) {
439 $query .= ", grp_aco_spec = ?";
440 $sqlvars[] = $jobj['aco'];
442 if (isset($jobj['services'])) {
443 $query .= ", grp_services = ?";
444 // if present but empty, means all services
445 $sqlvars[] = $jobj['services'] ?
$jobj['services'] : '*';
447 if (isset($jobj['products'])) {
448 $query .= ", grp_products = ?";
449 // if present but empty, means all products
450 $sqlvars[] = $jobj['products'] ?
$jobj['products'] : '*';
452 if (isset($jobj['diags'])) {
453 $query .= ", grp_diags = ?";
454 // if present but empty, means all diags
455 $sqlvars[] = $jobj['diags'] ?
$jobj['diags'] : '*';
458 sqlStatement($query, $sqlvars);
460 $gres = sqlStatement(
461 "SELECT DISTINCT group_name FROM layout_options WHERE form_id = ? ORDER BY group_name",
465 // For each group within this layout...
466 while ($grow = sqlFetchArray($gres)) {
467 $group_name = $grow['group_name'];
470 $a = explode('|', $group_name);
471 foreach ($a as $tmp) {
472 $group_id .= substr($tmp, 0, 1);
473 $title = substr($tmp, 1);
476 "UPDATE layout_options SET group_id = ? WHERE form_id = ? AND group_name = ?",
477 array($group_id, $form_id, $group_name)
479 $query = "INSERT IGNORE INTO layout_group_properties SET " .
480 "grp_form_id = ?, " .
481 "grp_group_id = ?, " .
482 "grp_title = '" . add_escape_custom($title) . "'";
483 // grp_title not using $sqlvars because of a bug causing '' to become '0'.
484 $sqlvars = array($form_id, $group_id);
485 /****************************************************************
486 if ($props['notes']) {
487 if (isset($jobj['columns'])) {
488 $query .= ", grp_columns = ?";
489 $sqlvars[] = $jobj['columns'];
491 if (isset($jobj['size'])) {
492 $query .= ", grp_size = ?";
493 $sqlvars[] = $jobj['size'];
496 ****************************************************************/
497 // echo $query; foreach ($sqlvars as $tmp) echo " '$tmp'"; echo "<br />\n"; // debugging
498 sqlStatement($query, $sqlvars);
504 * Upgrade or patch the database with a selected upgrade/patch file.
506 * The following "functions" within the selected file will be processed:
509 * argument: table_name
510 * behavior: if the table_name does not exist, the block will be executed
513 * argument: table_name
514 * behavior: if the table_name does exist, the block will be executed
517 * arguments: table_name colname
518 * behavior: if the table and column exist, the block will be executed
521 * arguments: table_name colname
522 * behavior: if the table exists but the column does not, the block will be executed
525 * arguments: table_name colname value
526 * behavior: If the table table_name does not have a column colname with a data type equal to value, then the block will be executed
529 * arguments: table_name colname value
530 * behavior: If the table table_name does not have a row where colname = value, the block will be executed.
533 * arguments: table_name colname value colname2 value2
534 * behavior: If the table table_name does not have a row where colname = value AND colname2 = value2, the block will be executed.
537 * arguments: table_name colname value colname2 value2 colname3 value3
538 * behavior: If the table table_name does not have a row where colname = value AND colname2 = value2 AND colname3 = value3, the block will be executed.
541 * arguments: table_name colname value colname2 value2 colname3 value3 colname4 value4
542 * behavior: If the table table_name does not have a row where colname = value AND colname2 = value2 AND colname3 = value3 AND colname4 = value4, the block will be executed.
545 * desc: This is a very specialized function to allow adding items to the list_options table to avoid both redundant option_id and title in each element.
546 * arguments: table_name colname value colname2 value2 colname3 value3
547 * behavior: The block will be executed if both statements below are true:
548 * 1) The table table_name does not have a row where colname = value AND colname2 = value2.
549 * 2) The table table_name does not have a row where colname = value AND colname3 = value3.
552 * arguments: table_name colname value colname2 value2
553 * behavior: If the table table_name does have a row where colname = value AND colname2 = value2, the block will be executed.
556 * arguments: table_name colname value colname2 value2 colname3 value3
557 * behavior: If the table table_name does have a row where colname = value AND colname2 = value2 AND colname3 = value3, the block will be executed.
560 * desc: This function is most often used for dropping of indexes/keys.
561 * arguments: table_name colname
562 * behavior: If the table and index exist the relevant statements are executed, otherwise not.
565 * desc: This function will allow adding of indexes/keys.
566 * arguments: table_name colname
567 * behavior: If the index does not exist, it will be created
569 * #IfNotMigrateClickOptions
570 * Custom function for the importing of the Clickoptions settings (if exist) from the codebase into the database
572 * #IfNotListOccupation
573 * Custom function for creating Occupation List
576 * Custom function for creating Reaction List
579 * Custom function for importing new drug data
581 * #IfTextNullFixNeeded
582 * desc: convert all text fields without default null to have default null.
586 * desc: Execute SQL if the table has been created with given engine specified.
587 * arguments: table_name engine
588 * behavior: Use when engine conversion requires more than one ALTER TABLE
590 * #IfInnoDBMigrationNeeded
591 * desc: find all MyISAM tables and convert them to InnoDB.
593 * behavior: can take a long time.
596 * all blocks are terminated with a #EndIf statement.
598 * @param string $filename Sql upgrade/patch filename
600 function upgradeFromSqlFile($filename)
602 global $webserver_root;
605 echo "<font color='green'>Processing $filename ...</font><br />\n";
607 $fullname = "$webserver_root/sql/$filename";
609 $fd = fopen($fullname, 'r');
611 echo "ERROR. Could not open '$fullname'.\n";
621 $line = fgets($fd, 2048);
622 $line = rtrim($line);
624 if (preg_match('/^\s*--/', $line)) {
632 if (preg_match('/^#IfNotTable\s+(\S+)/', $line, $matches)) {
633 $skipping = tableExists($matches[1]);
635 echo "<font color='green'>Skipping section $line</font><br />\n";
637 } else if (preg_match('/^#IfTable\s+(\S+)/', $line, $matches)) {
638 $skipping = ! tableExists($matches[1]);
640 echo "<font color='green'>Skipping section $line</font><br />\n";
642 } else if (preg_match('/^#IfColumn\s+(\S+)\s+(\S+)/', $line, $matches)) {
643 if (tableExists($matches[1])) {
644 $skipping = !columnExists($matches[1], $matches[2]);
646 // If no such table then the column is deemed "missing".
651 echo "<font color='green'>Skipping section $line</font><br />\n";
653 } else if (preg_match('/^#IfMissingColumn\s+(\S+)\s+(\S+)/', $line, $matches)) {
654 if (tableExists($matches[1])) {
655 $skipping = columnExists($matches[1], $matches[2]);
657 // If no such table then the column is deemed not "missing".
662 echo "<font color='green'>Skipping section $line</font><br />\n";
664 } else if (preg_match('/^#IfNotColumnType\s+(\S+)\s+(\S+)\s+(.+)/', $line, $matches)) {
665 if (tableExists($matches[1])) {
666 $skipping = columnHasType($matches[1], $matches[2], $matches[3]);
668 // If no such table then the column type is deemed not "missing".
673 echo "<font color='green'>Skipping section $line</font><br />\n";
675 } else if (preg_match('/^#IfIndex\s+(\S+)\s+(\S+)/', $line, $matches)) {
676 if (tableExists($matches[1])) {
677 // If no such index then skip.
678 $skipping = !tableHasIndex($matches[1], $matches[2]);
680 // If no such table then skip.
685 echo "<font color='green'>Skipping section $line</font><br />\n";
687 } else if (preg_match('/^#IfNotIndex\s+(\S+)\s+(\S+)/', $line, $matches)) {
688 if (tableExists($matches[1])) {
689 $skipping = tableHasIndex($matches[1], $matches[2]);
691 // If no such table then the index is deemed not "missing".
696 echo "<font color='green'>Skipping section $line</font><br />\n";
698 } else if (preg_match('/^#IfNotRow\s+(\S+)\s+(\S+)\s+(.+)/', $line, $matches)) {
699 if (tableExists($matches[1])) {
700 $skipping = tableHasRow($matches[1], $matches[2], $matches[3]);
702 // If no such table then the row is deemed not "missing".
707 echo "<font color='green'>Skipping section $line</font><br />\n";
709 } else if (preg_match('/^#IfNotRow2D\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)/', $line, $matches)) {
710 if (tableExists($matches[1])) {
711 $skipping = tableHasRow2D($matches[1], $matches[2], $matches[3], $matches[4], $matches[5]);
713 // If no such table then the row is deemed not "missing".
718 echo "<font color='green'>Skipping section $line</font><br />\n";
720 } else if (preg_match('/^#IfNotRow3D\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)/', $line, $matches)) {
721 if (tableExists($matches[1])) {
722 $skipping = tableHasRow3D($matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6], $matches[7]);
724 // If no such table then the row is deemed not "missing".
729 echo "<font color='green'>Skipping section $line</font><br />\n";
731 } else if (preg_match('/^#IfNotRow4D\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)/', $line, $matches)) {
732 if (tableExists($matches[1])) {
733 $skipping = tableHasRow4D($matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6], $matches[7], $matches[8], $matches[9]);
735 // If no such table then the row is deemed not "missing".
740 echo "<font color='green'>Skipping section $line</font><br />\n";
742 } else if (preg_match('/^#IfNotRow2Dx2\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)/', $line, $matches)) {
743 if (tableExists($matches[1])) {
744 // If either check exist, then will skip
745 $firstCheck = tableHasRow2D($matches[1], $matches[2], $matches[3], $matches[4], $matches[5]);
746 $secondCheck = tableHasRow2D($matches[1], $matches[2], $matches[3], $matches[6], $matches[7]);
747 if ($firstCheck ||
$secondCheck) {
753 // If no such table then the row is deemed not "missing".
758 echo "<font color='green'>Skipping section $line</font><br />\n";
760 } else if (preg_match('/^#IfRow2D\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)/', $line, $matches)) {
761 if (tableExists($matches[1])) {
762 $skipping = !(tableHasRow2D($matches[1], $matches[2], $matches[3], $matches[4], $matches[5]));
764 // If no such table then should skip.
769 echo "<font color='green'>Skipping section $line</font><br />\n";
771 } else if (preg_match('/^#IfRow3D\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)/', $line, $matches)) {
772 if (tableExists($matches[1])) {
773 $skipping = !(tableHasRow3D($matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6], $matches[7]));
775 // If no such table then should skip.
780 echo "<font color='green'>Skipping section $line</font><br />\n";
782 } else if (preg_match('/^#IfNotMigrateClickOptions/', $line)) {
783 if (tableExists("issue_types")) {
786 // Create issue_types table and import the Issue Types and clickoptions settings from codebase into the database
787 clickOptionsMigrate();
792 echo "<font color='green'>Skipping section $line</font><br />\n";
794 } else if (preg_match('/^#IfNotListOccupation/', $line)) {
795 if ((listExists("Occupation")) ||
(!columnExists('patient_data', 'occupation'))) {
798 // Create Occupation list
799 CreateOccupationList();
801 echo "<font color='green'>Built Occupation List</font><br />\n";
805 echo "<font color='green'>Skipping section $line</font><br />\n";
807 } else if (preg_match('/^#IfNotListReaction/', $line)) {
808 if ((listExists("reaction")) ||
(!columnExists('lists', 'reaction'))) {
811 // Create Reaction list
812 CreateReactionList();
814 echo "<font color='green'>Built Reaction List</font><br />\n";
818 echo "<font color='green'>Skipping section $line</font><br />\n";
820 } else if (preg_match('/^#IfNotListImmunizationManufacturer/', $line)) {
821 if (listExists("Immunization_Manufacturer")) {
824 // Create Immunization Manufacturer list
825 CreateImmunizationManufacturerList();
827 echo "<font color='green'>Built Immunization Manufacturer List</font><br />\n";
831 echo "<font color='green'>Skipping section $line</font><br />\n";
833 } else if (preg_match('/^#IfNotWenoRx/', $line)) {
834 if (tableHasRow('erx_weno_drugs', "drug_id", '1008') == true) {
838 ImportDrugInformation();
840 echo "<font color='green'>Imported eRx Weno Drug Data</font><br />\n";
843 echo "<font color='green'>Skipping section $line</font><br />\n";
845 // convert all *text types to use default null setting
846 } else if (preg_match('/^#IfTextNullFixNeeded/', $line)) {
847 $items_to_convert = sqlStatement(
848 "SELECT col.`table_name`, col.`column_name`, col.`data_type`, col.`column_comment`
849 FROM `information_schema`.`columns` col INNER JOIN `information_schema`.`tables` tab
850 ON tab.TABLE_CATALOG=col.TABLE_CATALOG AND tab.table_schema=col.table_schema AND tab.table_name=col.table_name
851 WHERE col.`data_type` IN ('tinytext', 'text', 'mediumtext', 'longtext')
852 AND col.is_nullable='NO' AND col.table_schema=database() AND tab.table_type='BASE TABLE'"
854 if (sqlNumRows($items_to_convert) == 0) {
858 echo '<font color="black">Starting conversion of *TEXT types to use default NULL.</font><br />',"\n";
859 while ($item = sqlFetchArray($items_to_convert)) {
860 if (!empty($item['column_comment'])) {
861 $res = sqlStatement("ALTER TABLE `" . add_escape_custom($item['table_name']) . "` MODIFY `" . add_escape_custom($item['column_name']) . "` " . add_escape_custom($item['data_type']) . " COMMENT '" . add_escape_custom($item['column_comment']) . "'");
863 $res = sqlStatement("ALTER TABLE `" . add_escape_custom($item['table_name']) . "` MODIFY `" . add_escape_custom($item['column_name']) . "` " . add_escape_custom($item['data_type']));
866 // If above query didn't work, then error will be outputted via the sqlStatement function.
867 echo "<font color='green'>" . text($item['table_name']) . "." . text($item['column_name']) . " sql column was successfully converted to " . text($item['data_type']) . " with default NULL setting.</font><br />\n";
872 echo "<font color='green'>Skipping section $line</font><br />\n";
874 } else if (preg_match('/^#IfTableEngine\s+(\S+)\s+(MyISAM|InnoDB)/', $line, $matches)) {
875 // perform special actions if table has specific engine
876 $skipping = !tableHasEngine($matches[1], $matches[2]);
878 echo "<font color='green'>Skipping section $line</font><br />\n";
880 } else if (preg_match('/^#IfInnoDBMigrationNeeded/', $line)) {
881 // find MyISAM tables and attempt to convert them
882 //tables that need to skip InnoDB migration (stay at MyISAM for now)
883 $tables_skip_migration = array('form_eye_mag');
885 $tables_list = getTablesList(array('engine'=>'MyISAM'));
886 if (count($tables_list)==0) {
890 echo '<font color="black">Starting migration to InnoDB, please wait.</font><br />',"\n";
891 foreach ($tables_list as $k => $t) {
892 if (in_array($t, $tables_skip_migration)) {
893 printf('<font color="green">Table %s was purposefully skipped and NOT migrated to InnoDB.</font><br />', $t);
897 $res = MigrateTableEngine($t, 'InnoDB');
899 printf('<font color="green">Table %s migrated to InnoDB.</font><br />', $t);
901 printf('<font color="red">Error migrating table %s to InnoDB</font><br />', $t);
902 error_log(sprintf('Error migrating table %s to InnoDB', errorLogEscape($t)));
908 echo "<font color='green'>Skipping section $line</font><br />\n";
910 } else if (preg_match('/^#ConvertLayoutProperties/', $line)) {
912 echo "<font color='green'>Skipping section $line</font><br />\n";
914 echo "Converting layout properties ...<br />\n";
915 convertLayoutProperties();
917 } else if (preg_match('/^#EndIf/', $line)) {
921 if (preg_match('/^\s*#/', $line)) {
929 $query = $query . $line;
930 if (substr($query, -1) == ';') {
931 $query = rtrim($query, ';');
932 echo "$query<br />\n";
933 if (!sqlStatement($query)) {
934 echo "<font color='red'>The above statement failed: " .
935 getSqlLastError() . "<br />Upgrading will continue.<br /></font>\n";