Add to the schema class and adjust the db connection obect in the domains class

This commit is contained in:
Mark Crane
2014-07-15 07:58:01 +00:00
parent c0f16be420
commit c7abde93dd
2 changed files with 662 additions and 9 deletions

View File

@@ -27,10 +27,11 @@ include "root.php";
//define the schema class
class schema {
public $db;
public $apps;
public $db_type;
public $result;
//define variables
public $db;
public $apps;
public $db_type;
public $result;
//get the list of installed apps from the core and mod directories
public function __construct() {
@@ -193,7 +194,659 @@ include "root.php";
$prep_statement->execute();
return $prep_statement->fetchAll(PDO::FETCH_ASSOC);
}
}
//database table exists alternate
private function db_table_exists_alternate ($db, $db_type, $table_name) {
$sql = "select count(*) from $table_name ";
$result = $db->query($sql);
if ($result > 0) {
return true; //table exists
}
else {
return false; //table doesn't exist
}
}
//database table exists
private function db_table_exists ($db, $db_type, $db_name, $table_name) {
$sql = "";
if ($db_type == "sqlite") {
$sql .= "SELECT * FROM sqlite_master WHERE type='table' and name='$table_name' ";
}
if ($db_type == "pgsql") {
$sql .= "select * from pg_tables where schemaname='public' and tablename = '$table_name' ";
}
if ($db_type == "mysql") {
$sql .= "SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = '$db_name' and TABLE_NAME = '$table_name' ";
}
$prep_statement = $db->prepare(check_sql($sql));
$prep_statement->execute();
$result = $prep_statement->fetchAll(PDO::FETCH_NAMED);
if (count($result) > 0) {
return true; //table exists
}
else {
return false; //table doesn't exist
}
}
//database table information
private function db_table_info($db, $db_name, $db_type, $table_name) {
if (strlen($table_name) == 0) { return false; }
if ($db_type == "sqlite") {
$sql = "PRAGMA table_info(".$table_name.");";
}
if ($db_type == "pgsql") {
$sql = "SELECT ordinal_position, ";
$sql .= "column_name, ";
$sql .= "data_type, ";
$sql .= "column_default, ";
$sql .= "is_nullable, ";
$sql .= "character_maximum_length, ";
$sql .= "numeric_precision ";
$sql .= "FROM information_schema.columns ";
$sql .= "WHERE table_name = '".$table_name."' ";
$sql .= "and table_catalog = '".$db_name."' ";
$sql .= "ORDER BY ordinal_position; ";
}
if ($db_type == "mysql") {
$sql = "describe ".$table_name.";";
}
$prep_statement = $db->prepare($sql);
$prep_statement->execute();
return $prep_statement->fetchAll(PDO::FETCH_ASSOC);
}
//database type
private function db_data_type($db_type, $table_info, $column_name) {
if ($db_type == "sqlite") {
foreach ($table_info as $key => &$row) {
if ($row['name'] == $column_name) {
return $row['type'];
}
}
}
if ($db_type == "pgsql") {
foreach ($table_info as $key => &$row) {
if ($row['column_name'] == $column_name) {
return $row['data_type'];
}
}
}
if ($db_type == "mysql") {
foreach ($table_info as $key => &$row) {
if ($row['Field'] == $column_name) {
return $row['Type'];
}
}
}
}
//sqlite column exists
private function db_sqlite_column_exists($table_info, $column_name) {
foreach ($table_info as $key => &$row) {
if ($row['name'] == $column_name) {
return true;
}
}
return $false;
}
//database column exists
private function db_column_exists ($db, $db_type, $db_name, $table_name, $column_name) {
global $display_type;
if ($db_type == "sqlite") {
$table_info = $this->db_table_info($db, $db_name, $db_type, $table_name);
if ($this->db_sqlite_column_exists($table_info, $column_name)) {
return true;
}
else {
return false;
}
}
if ($db_type == "pgsql") {
$sql = "SELECT attname FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '$table_name') AND attname = '$column_name'; ";
}
if ($db_type == "mysql") {
//$sql .= "SELECT * FROM information_schema.COLUMNS where TABLE_SCHEMA = '$db_name' and TABLE_NAME = '$table_name' and COLUMN_NAME = '$column_name' ";
$sql = "show columns from $table_name where field = '$column_name' ";
}
if ($sql) {
$prep_statement = $db->prepare(check_sql($sql));
$prep_statement->execute();
$result = $prep_statement->fetchAll(PDO::FETCH_NAMED);
if (!$result) {
return false;
}
if (count($result) > 0) {
return true;
}
else {
return false;
}
unset ($prep_statement);
}
}
//database column data type
private function db_column_data_type ($db, $db_type, $db_name, $table_name, $column_name) {
$table_info = $this->db_table_info($db, $db_name, $db_type, $table_name);
return $this->db_data_type($db_type, $table_info, $column_name);
}
//database create table
private function db_create_table ($apps, $db_type, $table) {
foreach ($apps as $x => &$app) {
foreach ($app['db'] as $y => $row) {
if ($row['table'] == $table) {
$sql = "CREATE TABLE " . $row['table'] . " (\n";
$field_count = 0;
foreach ($row['fields'] as $field) {
if ($field['deprecated'] == "true") {
//skip this row
}
else {
if ($field_count > 0 ) { $sql .= ",\n"; }
if (is_array($field['name'])) {
$sql .= $field['name']['text'] . " ";
}
else {
$sql .= $field['name'] . " ";
}
if (is_array($field['type'])) {
$sql .= $field['type'][$db_type];
}
else {
$sql .= $field['type'];
}
if ($field['key']['type'] == "primary") {
$sql .= " PRIMARY KEY";
}
$field_count++;
}
}
$sql .= ");\n\n";
return $sql;
}
}
}
}
//database insert
private function db_insert_into ($apps, $db_type, $table) {
global $db, $db_name;
foreach ($apps as $x => &$app) {
foreach ($app['db'] as $y => $row) {
if ($row['table'] == $table) {
$sql = "INSERT INTO " . $row['table'] . " (";
$field_count = 0;
foreach ($row['fields'] as $field) {
if ($field['deprecated'] == "true") {
//skip this field
}
else {
if ($field_count > 0 ) { $sql .= ","; }
if (is_array($field['name'])) {
$sql .= $field['name']['text'];
}
else {
$sql .= $field['name'];
}
$field_count++;
}
}
$sql .= ")\n";
$sql .= "SELECT ";
$field_count = 0;
foreach ($row['fields'] as $field) {
if ($field['deprecated'] == "true") {
//skip this field
}
else {
if ($field_count > 0 ) { $sql .= ","; }
if (is_array($field['name'])) {
if ($field['exists'] == "false") {
if (is_array($field['name']['deprecated'])) {
$found = false;
foreach ($field['name']['deprecated'] as $row) {
if ($this->db_column_exists ($db, $db_type, $db_name, 'tmp_'.$table, $row)) {
$sql .= $row;
$found = true;
break;
}
}
if (!$found) { $sql .= "''"; }
}
else {
if ($this->db_column_exists ($db, $db_type, $db_name, 'tmp_'.$table, $field['name']['deprecated'])) {
$sql .= $field['name']['deprecated'];
}
else {
$sql .= "''";
}
}
}
else {
$sql .= $field['name']['text'];
}
}
else {
$sql .= $field['name'];
}
$field_count++;
}
}
$sql .= " FROM tmp_".$table.";\n\n";
return $sql;
}
}
}
}
//datatase schema
public function schema ($db, $db_type, $db_name, $response_output) {
global $db;
global $text; // pulls in language variable array
global $response_format;
global $upgrade_data_types;
//PHP PDO check if table or column exists
//check if table exists
// SELECT * FROM sqlite_master WHERE type='table' AND name='v_cdr'
//check if column exists
// SELECT * FROM sqlite_master WHERE type='table' AND name='v_cdr' AND sql LIKE '%caller_id_name TEXT,%'
//aditional information
// http://www.sqlite.org/faq.html#q9
//postgresql
//list all tables in the database
// SELECT table_name FROM pg_tables WHERE schemaname='public';
//check if table exists
// SELECT * FROM pg_tables WHERE schemaname='public' AND table_name = 'v_groups'
//check if column exists
// SELECT attname FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'v_cdr') AND attname = 'caller_id_name';
//mysql
//list all tables in the database
// SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'fusionpbx'
//check if table exists
// SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'fusionpbx' AND TABLE_NAME = 'v_groups'
//check if column exists
// SELECT * FROM information_schema.COLUMNS where TABLE_SCHEMA = 'fusionpbx' AND TABLE_NAME = 'v_cdr' AND COLUMN_NAME = 'context'
//oracle
//check if table exists
// SELECT TABLE_NAME FROM ALL_TABLES
//get the $apps array from the installed apps from the core and mod directories
$config_list = glob($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . "/*/*/app_config.php");
$x=0;
foreach ($config_list as &$config_path) {
include($config_path);
$x++;
}
//update the app db array add exists true or false
$sql = '';
foreach ($apps as $x => &$app) {
foreach ($app['db'] as $y => &$row) {
if (is_array($row['table'])) {
$table_name = $row['table']['text'];
}
else {
$table_name = $row['table'];
}
if (strlen($table_name) > 0) {
//check if the table exists
if ($this->db_table_exists($db, $db_type, $db_name, $table_name)) {
$apps[$x]['db'][$y]['exists'] = 'true';
}
else {
$apps[$x]['db'][$y]['exists'] = 'false';
}
//check if the column exists
foreach ($row['fields'] as $z => $field) {
if ($field['deprecated'] == "true") {
//skip this field
}
else {
if (is_array($field['name'])) {
$field_name = $field['name']['text'];
}
else {
$field_name = $field['name'];
}
if (strlen(field_name) > 0) {
if ($this->db_column_exists ($db, $db_type, $db_name, $table_name, $field_name)) {
//found
$apps[$x]['db'][$y]['fields'][$z]['exists'] = 'true';
}
else {
//not found
$apps[$x]['db'][$y]['fields'][$z]['exists'] = 'false';
}
}
unset($field_name);
}
}
unset($table_name);
}
}
}
//prepare the variables
$sql_update = '';
$var_uuid = $_GET["id"];
//add missing tables and fields
foreach ($apps as $x => &$app) {
foreach ($app['db'] as $y => &$row) {
if (is_array($row['table'])) {
$table_name = $row['table']['text'];
if (!$this->db_table_exists($db, $db_type, $db_name, $row['table']['text'])) {
$row['exists'] = "true"; //testing
//if (db_table_exists($db, $db_type, $db_name, $row['table']['deprecated'])) {
if ($db_type == "pgsql") {
$sql_update .= "ALTER TABLE ".$row['table']['deprecated']." RENAME TO ".$row['table']['text'].";\n";
}
if ($db_type == "mysql") {
$sql_update .= "RENAME TABLE ".$row['table']['deprecated']." TO ".$row['table']['text'].";\n";
}
if ($db_type == "sqlite") {
$sql_update .= "ALTER TABLE ".$row['table']['deprecated']." RENAME TO ".$row['table']['text'].";\n";
}
//}
}
}
else {
$table_name = $row['table'];
}
//check if the table exists
if ($row['exists'] == "true") {
if (count($row['fields']) > 0) {
foreach ($row['fields'] as $z => $field) {
if ($field['deprecated'] == "true") {
//skip this field
}
else {
//get the data type
if (is_array($field['type'])) {
$field_type = $field['type'][$db_type];
}
else {
$field_type = $field['type'];
}
//get the field name
if (is_array($field['name'])) {
$field_name = $field['name']['text'];
}
else {
$field_name = $field['name'];
}
//find missing fields and add them
if ($field['deprecated'] == "true") {
//skip this row
}
else {
if (!is_array($field['name'])) {
if ($field['exists'] == "false") {
$sql_update .= "ALTER TABLE ".$table_name." ADD ".$field['name']." ".$field_type.";\n";
}
}
}
//rename fields where the name has changed
if (is_array($field['name'])) {
if ($this->db_column_exists ($db, $db_type, $db_name, $table_name, $field['name']['deprecated'])) {
if ($db_type == "pgsql") {
$sql_update .= "ALTER TABLE ".$table_name." RENAME COLUMN ".$field['name']['deprecated']." to ".$field['name']['text'].";\n";
}
if ($db_type == "mysql") {
$field_type = str_replace("AUTO_INCREMENT PRIMARY KEY", "", $field_type);
$sql_update .= "ALTER TABLE ".$table_name." CHANGE ".$field['name']['deprecated']." ".$field['name']['text']." ".$field_type.";\n";
}
if ($db_type == "sqlite") {
//a change has been made to the field name
$apps[$x]['db'][$y]['rebuild'] = 'true';
}
}
}
//change the data type if it has been changed
//if the data type in the app db array is different than the type in the database then change the data type
if ($upgrade_data_types) {
$db_field_type = $this->db_column_data_type ($db, $db_type, $db_name, $table_name, $field_name);
$field_type_array = explode("(", $field_type);
$field_type = $field_type_array[0];
if (trim($db_field_type) != trim($field_type) && strlen($db_field_type) > 0) {
if ($db_type == "pgsql") {
if (strtolower($field_type) == "uuid") {
$sql_update .= "ALTER TABLE ".$table_name." ALTER COLUMN ".$field_name." TYPE uuid USING\n";
$sql_update .= "CAST(regexp_replace(".$field_name.", '([A-Z0-9]{4})([A-Z0-9]{12})', E'\\1-\\2')\n";
$sql_update .= "AS uuid);\n";
}
else {
if ($db_field_type = "integer" && strtolower($field_type) == "serial") {
//field type has not changed
} elseif ($db_field_type = "timestamp without time zone" && strtolower($field_type) == "timestamp") {
//field type has not changed
} elseif ($db_field_type = "timestamp without time zone" && strtolower($field_type) == "datetime") {
//field type has not changed
} elseif ($db_field_type = "integer" && strtolower($field_type) == "numeric") {
//field type has not changed
} elseif ($db_field_type = "character" && strtolower($field_type) == "char") {
//field type has not changed
}
else {
//$sql_update .= "-- $db_type, $db_name, $table_name, $field_name ".db_column_data_type ($db, $db_type, $db_name, $table_name, $field_name)."<br>";
$sql_update .= "ALTER TABLE ".$table_name." ALTER COLUMN ".$field_name." TYPE ".$field_type.";\n";
}
}
}
if ($db_type == "mysql") {
$type = explode("(", $db_field_type);
if ($type[0] == $field_type) {
//do nothing
}
elseif ($field_type == "numeric" && $type[0] == "decimal") {
//do nothing
}
else {
$sql_update .= "ALTER TABLE ".$table_name." modify ".$field_name." ".$field_type.";\n";
}
unset($type);
}
if ($db_type == "sqlite") {
//a change has been made to the field type
$apps[$x]['db'][$y]['rebuild'] = 'true';
}
}
}
}
}
unset($column_array);
}
}
else {
//create table
if (!is_array($row['table'])) {
$sql_update .= $this->db_create_table($apps, $db_type, $row['table']);
}
}
}
}
//rebuild and populate the table
foreach ($apps as $x => &$app) {
foreach ($app['db'] as $y => &$row) {
if (is_array($row['table'])) {
$table_name = $row['table']['text'];
}
else {
$table_name = $row['table'];
}
if ($row['rebuild'] == "true") {
if ($db_type == "sqlite") {
//start the transaction
//$sql_update .= "BEGIN TRANSACTION;\n";
//rename the table
$sql_update .= "ALTER TABLE ".$table_name." RENAME TO tmp_".$table_name.";\n";
//create the table
$sql_update .= $this->db_create_table($apps, $db_type, $table_name);
//insert the data into the new table
$sql_update .= $this->db_insert_into($apps, $db_type, $table_name);
//drop the old table
$sql_update .= "DROP TABLE tmp_".$table_name.";\n";
//commit the transaction
//$sql_update .= "COMMIT;\n";
}
}
}
}
// initialize response variable
$response = '';
//display results as html
if ($response_output != '' && $response_format == "html") {
//show the database type
$response .= "<strong>".$text['header-database_type'].": ".$db_type. "</strong><br /><br />";
//start the table
$response .= "<table width='100%' border='0' cellpadding='20' cellspacing='0'>\n";
//show the changes
if (strlen($sql_update) > 0) {
$response .= "<tr>\n";
$response .= "<td class='row_style1' colspan='3'>\n";
$response .= "<br />\n";
$response .= "<strong>".$text['label-sql_changes'].":</strong><br />\n";
$response .= "<pre>\n";
$response .= $sql_update;
$response .= "</pre>\n";
$response .= "<br />\n";
$response .= "</td>\n";
$response .= "</tr>\n";
}
//list all tables
$response .= "<tr>\n";
$response .= "<th>".$text['label-table']."</th>\n";
$response .= "<th>".$text['label-exists']."</th>\n";
$response .= "<th>".$text['label-details']."</th>\n";
$response .= "<tr>\n";
//build the html while looping through the app db array
$sql = '';
foreach ($apps as &$app) {
foreach ($app['db'] as $row) {
if (is_array($row['table'])) {
$table_name = $row['table']['text'];
}
else {
$table_name = $row['table'];
}
$response .= "<tr>\n";
//check if the table exists
if ($row['exists'] == "true") {
$response .= "<td valign='top' class='row_style1'>".$table_name."</td>\n";
$response .= "<td valign='top' class='vncell' style='padding-top: 3px;'>".$text['option-true']."</td>\n";
if (count($row['fields']) > 0) {
$response .= "<td class='row_style1'>\n";
//show the list of columns
$response .= "<table border='0' cellpadding='10' cellspacing='0'>\n";
$response .= "<tr>\n";
$response .= "<th>".$text['label-name']."</th>\n";
$response .= "<th>".$text['label-type']."</th>\n";
$response .= "<th>".$text['label-exists']."</th>\n";
$response .= "</tr>\n";
foreach ($row['fields'] as $field) {
if ($field['deprecated'] == "true") {
//skip this field
}
else {
if (is_array($field['name'])) {
$field_name = $field['name']['text'];
}
else {
$field_name = $field['name'];
}
if (is_array($field['type'])) {
$field_type = $field['type'][$db_type];
}
else {
$field_type = $field['type'];
}
$response .= "<tr>\n";
$response .= "<td class='row_style1' width='200'>".$field_name."</td>\n";
$response .= "<td class='row_style1'>".$field_type."</td>\n";
if ($field['exists'] == "true") {
$response .= "<td class='row_style0' style=''>".$text['option-true']."</td>\n";
$response .= "<td>&nbsp;</td>\n";
}
else {
$response .= "<td class='row_style1' style='background-color:#444444;color:#CCCCCC;'>".$text['option-false']."</td>\n";
$response .= "<td>&nbsp;</td>\n";
}
$response .= "</tr>\n";
}
}
unset($column_array);
$response .= " </table>\n";
$response .= "</td>\n";
}
}
else {
$response .= "<td valign='top' class='row_style1'>$table_name</td>\n";
$response .= "<td valign='top' class='row_style1' style='background-color:#444444;color:#CCCCCC;'><strong>".$text['label-exists']."</strong><br />".$text['option-false']."</td>\n";
$response .= "<td valign='top' class='row_style1'>&nbsp;</td>\n";
}
$response .= "</tr>\n";
}
}
unset ($prep_statement);
//end the list of tables
$response .= "</table>\n";
$response .= "<br />\n";
}
//loop line by line through all the lines of sql code
$x = 0;
if (strlen($sql_update) == 0 && $response_format == "text") {
$response .= " ".$text['label-schema'].": ".$text['label-no_change']."\n";
}
else {
if ($response_format == "text") {
$response .= " ".$text['label-schema'].":\n";
}
//$db->beginTransaction();
$update_array = explode(";", $sql_update);
foreach($update_array as $sql) {
if (strlen(trim($sql))) {
try {
$db->query(trim($sql));
if ($response_format == "text") {
$response .= " $sql\n";
}
}
catch (PDOException $error) {
if ($response_output != '') {
$response .= " error: " . $error->getMessage() . " sql: $sql<br/>";
}
}
}
}
//$db->commit();
$response .= "\n";
unset ($file_contents, $sql_update, $sql);
}
//handle response
if ($response_output == "echo") {
echo $response;
}
else if ($response_output == "return") {
return $response;
}
} //end function
}
//example use
//require_once "resources/classes/schema.php";