conn = mysql_connect($hostname.":".$port, $user, $password, true); mysql_set_charset('utf8',$this->conn); mysql_query("SET character_set_results = 'utf8', character_set_client = 'utf8', character_set_connection = 'utf8', character_set_database = 'utf8', character_set_server = 'utf8'", $this->conn); if($this->conn !== false) return true; return false; } function __destruct() { } function load_schema($schema_type) { $this->schema = false; $structure = simplexml_load_file(dirname(__FILE__)."/../../lib/conf.d/bases_structure.xml"); if($structure !== false) { if($schema_type === 'application_box') $this->schema = $structure->appbox; if($schema_type === 'data_box') $this->schema = $structure->databox; } return $this->schema !== false ? true : false ; } function createDb($dbname) { if($this->schema) { $sql = 'CREATE DATABASE `'.mysql_real_escape_string($dbname,$this->conn).'` CHARACTER SET utf8 COLLATE utf8_unicode_ci'; if(mysql_query($sql,$this->conn) || mysql_select_db($dbname,$this->conn)) { mysql_select_db($dbname,$this->conn); foreach($this->schema->tables->table as $table) { $this->createTable($table); } $this->dbname = $dbname; if(defined('GV_version')) $this->setVersion(GV_version); return true; } else return false; } return false; } private function createTable($table) { $field_stmt = $defaults_stmt = array(); $create_stmt = "CREATE TABLE `".mysql_real_escape_string($table['name'],$this->conn)."` ("; foreach($table->fields->field as $field){ $isnull=trim($field->null)==""?"NOT NULL":"NULL"; if(trim($field->default) != "" && trim($field->default)!="CURRENT_TIMESTAMP") $is_default = " default '".$field->default."'"; elseif(trim($field->default)=="CURRENT_TIMESTAMP") $is_default = " default ".$field->default; else $is_default = ''; $character_set = ''; if(in_array(strtolower((string)$field->type),array('text','longtext','mediumtext','tinytext')) || substr(strtolower((string)$field->type), 0, 7) == 'varchar' || in_array(substr(strtolower((string)$field->type), 0, 4), array('char','enum'))) { $collation = trim((string)$field->collation) != '' ? trim((string)$field->collation) : 'utf8_unicode_ci'; $code = array_pop(array_reverse(explode('_',$collation))); $character_set = ' CHARACTER SET '.$code.' COLLATE ' . $collation ; } $field_stmt[] = " `".mysql_real_escape_string($field->name,$this->conn)."` ".$field->type." ".$field->extra." ".$character_set." ".$is_default." ".$isnull.""; } if($table->indexes){ foreach($table->indexes->index as $index){ switch($index->type){ case "PRIMARY":{ $primary_fields = array(); foreach($index->fields->field as $field){ $primary_fields[] = "`".mysql_real_escape_string($field,$this->conn)."`"; } $field_stmt[] = 'PRIMARY KEY ('.implode(',' , $primary_fields).')'; };break; case "UNIQUE":{ $unique_fields = array(); foreach($index->fields->field as $field){ $unique_fields[] = "`".mysql_real_escape_string($field,$this->conn)."`"; } $field_stmt[] = 'UNIQUE KEY `'.mysql_real_escape_string($index->name,$this->conn).'` ('.implode(',',$unique_fields).')'; };break; case "INDEX":{ $index_fields = array(); foreach($index->fields->field as $field){ $index_fields[] = "`".mysql_real_escape_string($field,$this->conn)."`"; } $field_stmt[] = 'KEY `'.mysql_real_escape_string($index->name,$this->conn).'` ('.implode(',',$index_fields).')'; };break; } } } if($table->defaults){ foreach($table->defaults->default as $default) { $k = $v = array(); foreach($default->data as $data) { $k[] = mysql_real_escape_string($data['key'],$this->conn); if($k === 'usr_password') $data = hash('sha256',$data); $v[] = mysql_real_escape_string(trim(str_replace(array("\r\n","\r","\n","\t"),'',$data)),$this->conn); } $k = implode(',',$k); $v = str_ireplace(array('"NOW()"','"null"'),array('NOW()','null'),'"'.implode('","',$v).'"'); $defaults_stmt[] = 'INSERT INTO '.mysql_real_escape_string($table['name'],$this->conn).' ('.$k.') VALUES ('.$v.') '; } } $engine = mb_strtolower(trim($table->engine)); $engine = in_array($engine,array('innodb','myisam')) ? $engine : 'innodb'; $create_stmt .= implode(',' , $field_stmt); $create_stmt .= ") ENGINE=".$engine." CHARACTER SET utf8 COLLATE utf8_unicode_ci;"; mysql_query($create_stmt,$this->conn); foreach($defaults_stmt as $def) { mysql_query($def,$this->conn); } } private function upgradeTable($table) { $correct_table = array('fields'=>array(), 'indexes'=>array(), 'collation'=>array()); $alter = $alter_pre = array(); if($table) { foreach($table->fields->field as $field) { $expr = trim((string)$field->type); $_extra = trim((string)$field->extra); if($_extra) $expr .= ' ' . $_extra; $collation = trim((string)$field->collation) != '' ? trim((string)$field->collation) : 'utf8_unicode_ci'; if(in_array(strtolower((string)$field->type),array('text','longtext','mediumtext','tinytext')) || substr(strtolower((string)$field->type), 0, 7) == 'varchar' || in_array(substr(strtolower((string)$field->type), 0, 4), array('char','enum'))) { $code = array_pop(array_reverse(explode('_',$collation))); $collation = ' CHARACTER SET '.$code.' COLLATE ' . $collation ; $correct_table['collation'][trim((string)$field->name)] = $collation ; $expr .= $collation; } $_null = mb_strtolower(trim((string)$field->null)); if(!$_null || $_null=='no') $expr .= ' NOT NULL'; $_default = (string)$field->default; if($_default && $_default != 'CURRENT_TIMESTAMP') $expr .= ' DEFAULT \'' . $_default . '\''; elseif($_default == 'CURRENT_TIMESTAMP') $expr .= ' DEFAULT ' . $_default . ''; $correct_table['fields'][trim((string)$field->name)] = $expr; } if($table->indexes) { foreach($table->indexes->index as $index) { $i_name = (string)$index->name; $expr = array(); foreach($index->fields->field as $field) $expr[] = '`'.trim((string)$field).'`'; $expr = implode(', ',$expr); switch((string)$index->type) { case "PRIMARY": $correct_table['indexes']['PRIMARY'] = 'PRIMARY KEY (' . $expr . ')'; break; case "UNIQUE": $correct_table['indexes'][$i_name] = 'UNIQUE KEY `' . $i_name . '` (' . $expr . ')'; break; case "INDEX": $correct_table['indexes'][$i_name] = 'KEY `' . $i_name . '` (' . $expr . ')'; break; } } } $sql = "SHOW FULL FIELDS FROM `".$table['name']."`"; if($rs2 = mysql_query($sql,$this->conn)) { while( $row2 = mysql_fetch_assoc($rs2) ) { $f_name = $row2['Field']; $expr_found = trim($row2['Type']); $_extra = $row2['Extra']; if($_extra) $expr_found .= ' ' . $_extra; $_collation = $row2['Collation']; $current_collation = ''; if($_collation) { $_collation = explode('_',$row2['Collation']); $expr_found .= $current_collation = ' CHARACTER SET ' . $_collation[0] . ' COLLATE ' . implode('_', $_collation); } $_null = mb_strtolower(trim($row2['Null'])); if(!$_null || $_null=='no') $expr_found .= ' NOT NULL'; $_default = $row2['Default']; if($_default) { if(trim($row2['Type'])=='timestamp' && $_default=='CURRENT_TIMESTAMP') $expr_found .= ' DEFAULT CURRENT_TIMESTAMP'; else $expr_found .= ' DEFAULT \'' . $_default . '\''; } if(isset($correct_table['fields'][$f_name])) { if(isset($correct_table['collation'][$f_name]) && $correct_table['collation'][$f_name] != $current_collation) { $old_type = mb_strtolower(trim($row2['Type'])); $new_type = false; switch($old_type) { case 'text': $new_type = 'blob'; break; case 'longtext': $new_type = 'longblob'; break; case 'mediumtext': $new_type = 'mediumblob'; break; case 'tinytext': $new_type = 'tinyblob'; break; default: if(substr($old_type, 0, 4) == 'char') $new_type = 'varbinary(255)'; if(substr($old_type, 0, 7) == 'varchar') $new_type = 'varbinary(767)'; break; } if($new_type) { $alter_pre[] = "ALTER TABLE `".$table['name']."` CHANGE `$f_name` `$f_name` ".$new_type.""; } } if(strtolower($expr_found) !== strtolower($correct_table['fields'][$f_name])) { $alter[] = "ALTER TABLE `".$table['name']."` CHANGE `$f_name` `$f_name` " . $correct_table['fields'][$f_name] ; } unset($correct_table['fields'][$f_name]); } // else // { // $alter[] = "ALTER TABLE `".$table['name']."` DROP `$f_name`"; // } } foreach($correct_table['fields'] as $f_name=>$expr) { $alter[] = "ALTER TABLE `".$table['name']."` ADD `$f_name` " . $correct_table['fields'][$f_name]; } mysql_free_result($rs2); } $tIndex = array(); $sql = "SHOW INDEXES FROM `".$table['name']."`"; if($rs2 = mysql_query($sql,$this->conn)) { while( $row2 = mysql_fetch_assoc($rs2) ) { if(!isset($tIndex[$row2['Key_name']])) $tIndex[$row2['Key_name']] = array('unique'=>((int)($row2['Non_unique'])==0), 'columns'=>array()); $tIndex[$row2['Key_name']]['columns'][(int)($row2['Seq_in_index'])] = $row2['Column_name']; } mysql_free_result($rs2); foreach($tIndex as $kIndex=>$vIndex) { $strColumns = array(); foreach($vIndex['columns'] as $column) $strColumns[] = '`'.$column.'`'; $strColumns = '('.implode(', ',$strColumns).')'; if($kIndex=='PRIMARY') $expr_found = 'PRIMARY KEY '.$strColumns; else { if($vIndex['unique']) $expr_found = 'UNIQUE KEY `' . $kIndex . '` ' .$strColumns; else $expr_found = 'KEY `' . $kIndex . '` ' .$strColumns; } $full_name_index = ($kIndex=='PRIMARY') ? 'PRIMARY KEY' : ('INDEX `'.$kIndex.'`'); if( isset($correct_table['indexes'][$kIndex]) ) { if(mb_strtolower($expr_found) !== mb_strtolower($correct_table['indexes'][$kIndex])) { $alter[] = 'ALTER TABLE `'.$table['name'].'` DROP ' . $full_name_index . ', ADD ' . $correct_table['indexes'][$kIndex]; } unset($correct_table['indexes'][$kIndex]); } // else // $alter[] = 'ALTER TABLE `'.$table['name'].'` DROP ' . $full_name_index; } } foreach($correct_table['indexes'] as $kIndex=>$expr) $alter[] = 'ALTER TABLE `'.$table['name'].'` ADD ' . $expr; } $return = true; foreach($alter_pre as $a) { if(!mysql_query($a, $this->conn)) $return = false; } foreach($alter as $a) { if(!mysql_query($a, $this->conn)) { if(GV_debug) { echo $a,' -- ',mysql_error($this->conn),'
'; } $return = false; } } return $return; } function upgradeDb() { require_once dirname( __FILE__ ) . '/../version.inc'; if($this->schema && $this->dbname) { $allTables = array(); foreach($this->schema->tables->table as $table) $allTables[(string)$table['name']] = $table; $sql = "SHOW TABLE STATUS"; if($rs = mysql_query($sql,$this->conn)) { while( $row = mysql_fetch_assoc($rs) ) { $tname = $row["Name"]; if(isset($allTables[$tname])) { $engine = strtolower(trim($allTables[$tname]->engine)); $ref_engine = strtolower($row['Engine']); if($engine != $ref_engine && in_array($engine,array('innodb','myisam'))) { $sql = 'ALTER TABLE `'.$tname.'` ENGINE = '.$engine; mysql_query($sql,$this->conn); } self::upgradeTable($allTables[$tname]); unset($allTables[$tname]); } } mysql_free_result($rs); } foreach($allTables as $tname=>$table) { $this->createTable($table); } } $current_version = self::getVersion(); if(self::apply_patches($current_version,GV_version)) self::setVersion(GV_version); return true; } function apply_patches($from,$to) { if(version_compare($from,$to,'=')) return true; $list_patches = array(); $iterator = new DirectoryIterator(GV_RootPath.'lib/classes/patch/'); foreach ($iterator as $fileinfo) { if (!$fileinfo->isDot()) { if(substr($fileinfo->getFilename(),0,1) == '.') continue; $classname = 'patch_'.array_pop(array_reverse(explode('.',$fileinfo->getFilename()))); $patch = new $classname(); if(!in_array($this->type, $patch->concern())) continue; if(!version_compare($patch->get_release(), $from, '>') || !version_compare($patch->get_release(), $to, '<=')) { continue; } $list_patches[$patch->get_release()][] = $patch; } } ksort($list_patches); $success = true; foreach($list_patches as $v=>$patches) { foreach($patches as $patch) { if(!$patch->apply($this->id)) $success = false; } } return $success; } function upgradeAvalaible() { if($this->type == 'application_box') $sql = 'SELECT version FROM sitepreff'; if($this->type == 'data_box') $sql = 'SELECT value AS version FROM pref WHERE prop="version" LIMIT 1;'; if($sql !== '') { if($rs = mysql_query($sql,$this->conn)) { if($row = mysql_fetch_assoc($rs)) $version = $row['version']; } } if(isset($version)) return version_compare(GV_version,$version,'>'); else return true; } private function setVersion($version) { $sql = ''; if($this->type == 'application_box') $sql = 'UPDATE sitepreff SET version = "'.$version.'"'; if($this->type == 'data_box') { $sql = 'DELETE FROM pref WHERE prop="version" AND locale IS NULL'; mysql_query($sql,$this->conn); $sql = 'REPLACE INTO pref (id, prop, value,locale, updated_on) VALUES (null, "version", "'.$version.'","", NOW())'; } if($sql !== '') { if(mysql_query($sql,$this->conn)) return true; } return false; } public function getVersion() { $sql = ''; if($this->type == 'application_box') $sql = 'SELECT version FROM sitepreff'; if($this->type == 'data_box') { $sql = 'DELETE FROM pref WHERE prop="version" AND locale IS NULL'; mysql_query($sql,$this->conn); $sql = 'SELECT value AS version FROM pref WHERE prop="version" LIMIT 1;'; } if($sql !== '') { if($rs = mysql_query($sql,$this->conn)) { if($row = mysql_fetch_assoc($rs)) { return $row['version']; } } } return '0.0.0'; } }