TimeTrex Community Edition v16.2.0
This commit is contained in:
319
classes/modules/install/InstallSchema_Base.class.php
Normal file
319
classes/modules/install/InstallSchema_Base.class.php
Normal file
@@ -0,0 +1,319 @@
|
||||
<?php
|
||||
/*********************************************************************************
|
||||
*
|
||||
* TimeTrex is a Workforce Management program developed by
|
||||
* TimeTrex Software Inc. Copyright (C) 2003 - 2021 TimeTrex Software Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by
|
||||
* the Free Software Foundation with the addition of the following permission
|
||||
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
|
||||
* WORK IN WHICH THE COPYRIGHT IS OWNED BY TIMETREX, TIMETREX DISCLAIMS THE
|
||||
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program; if not, see http://www.gnu.org/licenses or write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA.
|
||||
*
|
||||
*
|
||||
* You can contact TimeTrex headquarters at Unit 22 - 2475 Dobbin Rd. Suite
|
||||
* #292 West Kelowna, BC V4T 2E9, Canada or at email address info@timetrex.com.
|
||||
*
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License
|
||||
* version 3, these Appropriate Legal Notices must retain the display of the
|
||||
* "Powered by TimeTrex" logo. If the display of the logo is not reasonably
|
||||
* feasible for technical reasons, the Appropriate Legal Notices must display
|
||||
* the words "Powered by TimeTrex".
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* @package Modules\Install
|
||||
*/
|
||||
class InstallSchema_Base {
|
||||
|
||||
protected $schema_sql_file_name = null;
|
||||
protected $version = null;
|
||||
protected $db = null;
|
||||
protected $is_upgrade = false;
|
||||
protected $install_obj = false;
|
||||
|
||||
/**
|
||||
* InstallSchema_Base constructor.
|
||||
* @param bool $install_obj
|
||||
*/
|
||||
function __construct( $install_obj = false ) {
|
||||
if ( is_object( $install_obj ) ) {
|
||||
$this->install_obj = $install_obj;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $db
|
||||
*/
|
||||
function setDatabaseConnection( $db ) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
function getDatabaseConnection() {
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $val
|
||||
*/
|
||||
function setIsUpgrade( $val ) {
|
||||
$this->is_upgrade = (bool)$val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function getIsUpgrade() {
|
||||
return $this->is_upgrade;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
function setVersion( $value ) {
|
||||
$this->version = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
function getVersion() {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $file_name
|
||||
*/
|
||||
function setSchemaSQLFilename( $file_name ) {
|
||||
$this->schema_sql_file_name = $file_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
function getSchemaSQLFilename() {
|
||||
return $this->schema_sql_file_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getSchemaGroup() {
|
||||
$schema_group = substr( $this->getVersion(), -1, 1 );
|
||||
Debug::text( 'Schema: ' . $this->getVersion() . ' Group: ' . $schema_group, __FILE__, __LINE__, __METHOD__, 9 );
|
||||
|
||||
return strtoupper( $schema_group );
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from Install class.
|
||||
* @param $table_name
|
||||
* @return bool
|
||||
*/
|
||||
function checkTableExists( $table_name ) {
|
||||
Debug::text( 'Table Name: ' . $table_name, __FILE__, __LINE__, __METHOD__, 9 );
|
||||
$db_conn = $this->getDatabaseConnection();
|
||||
|
||||
if ( $db_conn == false ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$table_arr = $db_conn->MetaTables();
|
||||
|
||||
if ( in_array( $table_name, $table_arr ) ) {
|
||||
Debug::text( 'Exists - Table Name: ' . $table_name, __FILE__, __LINE__, __METHOD__, 9 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Debug::text( 'Does not Exist - Table Name: ' . $table_name, __FILE__, __LINE__, __METHOD__, 9 );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* load Schema file data
|
||||
* @return bool|string
|
||||
*/
|
||||
function getSchemaSQLFileData() {
|
||||
//Read SQL data into memory
|
||||
if ( is_readable( $this->getSchemaSQLFilename() ) ) {
|
||||
Debug::text( 'Schema SQL File is readable: ' . $this->getSchemaSQLFilename(), __FILE__, __LINE__, __METHOD__, 9 );
|
||||
$contents = file_get_contents( $this->getSchemaSQLFilename() );
|
||||
|
||||
Debug::Arr( $contents, 'SQL File Data: ', __FILE__, __LINE__, __METHOD__, 9 );
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
Debug::text( 'Schema SQL File is NOT readable, or is empty!', __FILE__, __LINE__, __METHOD__, 9 );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sql
|
||||
* @return string
|
||||
*/
|
||||
function removeSchemaSQLFileComments( $sql ) {
|
||||
$retval = '';
|
||||
|
||||
$split_sql = explode( "\n", $sql );
|
||||
if ( is_array( $split_sql ) ) {
|
||||
foreach ( $split_sql as $sql_line ) {
|
||||
if ( substr( trim( $sql_line ), 0, 2 ) != '--' ) {
|
||||
$retval .= $sql_line . "\n"; //Make sure the newlines are put back in the proper place, otherwise it can other SQL parse errors.
|
||||
} else {
|
||||
Debug::text( 'Skipping SQL Comment: ' . $sql_line, __FILE__, __LINE__, __METHOD__, 9 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add support for custom variables in SQL files so we can access PHP variables in SQL and keep SQL schema files across database systems similar.
|
||||
* @param $sql
|
||||
* @return mixed
|
||||
*/
|
||||
function replaceSQLVariables( $sql ) {
|
||||
if ( $this->getVersion() != '1000A' ) { //Don't replace any variables on first schema version, as TTUUID requires a registration key, which itself requires the system_settings table.
|
||||
$uuid_prefix = TTUUID::getConversionPrefix(); //Conversion prefix can't be used until at least after 1000A is done and system_setting table exists. Preferrably not until after a registration key has also been created.
|
||||
$search_arr = [ '#UUID_PREFIX#' ];
|
||||
$replace_arr = [ $uuid_prefix ];
|
||||
|
||||
$retval = str_ireplace( $search_arr, $replace_arr, $sql );
|
||||
|
||||
return $retval;
|
||||
} else {
|
||||
Debug::text( 'Skipping SQL variable replace, as this is the first schema version: 1000A...', __FILE__, __LINE__, __METHOD__, 9 );
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws DBError
|
||||
*/
|
||||
private function _InstallSchema() {
|
||||
//Run the actual SQL queries here
|
||||
|
||||
$sql = $this->removeSchemaSQLFileComments( $this->getSchemaSQLFileData() );
|
||||
if ( $sql == false ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $sql !== false && strlen( $sql ) > 0 ) {
|
||||
//Handle variable replacements on the entire schema version file at once to avoid having initialize the search/replace variables for every line.
|
||||
$sql = $this->replaceSQLVariables( $sql );
|
||||
|
||||
Debug::text( 'Schema SQL has data, executing commands! Version: ' . $this->getVersion(), __FILE__, __LINE__, __METHOD__, 9 );
|
||||
|
||||
$i = 0;
|
||||
|
||||
//Split into individual SQL queries in case more than one is on the same line, so we can better differentiate between actual queries.
|
||||
$split_sql = explode( ';', $sql );
|
||||
if ( is_array( $split_sql ) ) {
|
||||
$total_sql_queries = count( $split_sql );
|
||||
foreach ( $split_sql as $sql_line ) {
|
||||
//Debug::text('SQL Line: '. trim($sql_line), __FILE__, __LINE__, __METHOD__, 9);
|
||||
if ( trim( $sql_line ) != '' && substr( trim( $sql_line ), 0, 2 ) != '--' ) {
|
||||
try {
|
||||
Debug::text( ' Executing SQL command: ' . $i . ' of: ' . $total_sql_queries, __FILE__, __LINE__, __METHOD__, 10 );
|
||||
$this->getDatabaseConnection()->Execute( $sql_line );
|
||||
} catch ( Exception $e ) {
|
||||
Debug::text( 'SQL Command failed on line: ' . $i . ' of: ' . $this->getVersion(), __FILE__, __LINE__, __METHOD__, 9 );
|
||||
throw new DBError( $e );
|
||||
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
Debug::text( 'Schema upgrade succeeded, last line: ' . $i . ' of: ' . $this->getVersion(), __FILE__, __LINE__, __METHOD__, 9 );
|
||||
} else {
|
||||
Debug::text( 'Schema SQL does not have data, not executing commands, continuing...', __FILE__, __LINE__, __METHOD__, 9 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function _postPostInstall() {
|
||||
Debug::text( 'Modify Schema version in system settings table!', __FILE__, __LINE__, __METHOD__, 9 );
|
||||
//Modify schema version in system_settings table.
|
||||
|
||||
Debug::text( 'Setting Schema Version to: ' . $this->getVersion() . ' Group: ' . $this->getSchemaGroup(), __FILE__, __LINE__, __METHOD__, 9 );
|
||||
|
||||
//Clear the ADODB GETINSERTSQL static cache, which is required when the schema changes specifically for the SystemSetting/SystemLog tables after the cache has been populated. ie: pre-UUID to post-UUID.
|
||||
global $ADODB_GETINSERTSQL_CLEAR_CACHE;
|
||||
$ADODB_GETINSERTSQL_CLEAR_CACHE = true;
|
||||
|
||||
$retval = SystemSettingFactory::setSystemSetting( 'schema_version_group_' . $this->getSchemaGroup(), $this->getVersion() );
|
||||
|
||||
$ADODB_GETINSERTSQL_CLEAR_CACHE = false;
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function InstallSchema() {
|
||||
$this->getDatabaseConnection()->StartTrans();
|
||||
|
||||
Debug::text( 'Installing Schema Version: ' . $this->getVersion(), __FILE__, __LINE__, __METHOD__, 9 );
|
||||
if ( $this->preInstall() == true ) {
|
||||
if ( $this->_InstallSchema() == true ) {
|
||||
if ( $this->postInstall() == true ) {
|
||||
$retval = $this->_postPostInstall();
|
||||
if ( $retval == true ) {
|
||||
$this->getDatabaseConnection()->CompleteTrans();
|
||||
|
||||
return $retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->getDatabaseConnection()->FailTrans();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
Reference in New Issue
Block a user