<?php
namespace Jackbooted\DB;
/**
* @copyright Confidential and copyright (c) 2016 Jackbooted Software. All rights reserved.
*
* Written by Brett Dutton of Jackbooted Software
* brett at brettdutton dot com
*
* This software is written and distributed under the GNU General Public
* License which means that its source code is freely-distributed and
* available to the general public.
*/
class DBMaintenance extends \Jackbooted\Util\JB {
public static function dbNextNumber ( $dbh, $tName ) {
// Loop max of 10 times to get the correc next number (optimistic locking)
for ( $i=0; $i<10; $i++ ) {
$qry = 'SELECT fldNext,fldFormat FROM tblNextNumber WHERE fldTable=?';
$row = DB::oneRow ( $dbh, $qry, $tName, DB::FETCH_ASSOC );
if ( $row === false ) {
self::addTableToNextNumber ( $tName, 'XX000000', 'Auto Inserted by dbNextNumber' );
$row = DB::oneRow ( $dbh, $qry, $tName, DB::FETCH_ASSOC );
if ( $row === false ) return false;
}
$nextNumberS = $row['fldNext'];
$nextNumber = intval ( $nextNumberS );
$format = $row['fldFormat'];
$updatedNumber = $nextNumber + 1;
$qry = 'UPDATE tblNextNumber SET fldNext=? WHERE fldTable=? AND fldNext=?';
$rowsAffected = DB::exec ( $dbh, $qry, [ $updatedNumber, $tName, $nextNumberS ] );
if ( $rowsAffected == 1 ) break;
}
// Apply the format to the number. This will be stored in the database
return substr ( $format, 0, strlen ( $format ) - strlen ( $nextNumberS ) ). $nextNumberS;
}
public static function getTableList() {
$qry = ( DB::driver( ) == DB::SQLITE ) ? "SELECT name FROM sqlite_master WHERE type='table'" : 'SHOW TABLES';
return DBTable::factory ( DB::DEF, $qry, null, DB::FETCH_NUM )->getColumn ( 0 );
}
public static function addTableToNextNumber ( $tName, $fmt, $comment="" ) {
// See if the table has been created
$tableExists = DB::oneValue ( DB::DEF, 'SELECT count(fldNextNumberID) FROM tblNextNumber WHERE fldTable=?', $tName );
if ( $tableExists != 0 ) return false;
$key = self::dbNextNumber ( DB::DEF, 'tblNextNumber' );
$lines = DB::exec ( DB::DEF, "INSERT INTO tblNextNumber VALUES (?,?,1,?,?,? )",
[ $key, $tName, $fmt, $comment, self::getTableChecksum ( $tName ) ] );
return ( $lines > 0 );
}
public static function updateTableChecksum ( $tableName ) {
$checksum = self::getTableChecksum ( $tableName );
DB::exec ( DB::DEF, 'UPDATE tblNextNumber SET fldTableChecksum=? WHERE fldTable=?',
[ $checksum, $tableName ] );
}
public static function getTableChecksum ( $tableName ) {
$createSyntax = self::getTableSyntax ( $tableName );
return md5 ( $createSyntax );
}
public static function getTableComments ( $tableName ) {
$attributes = [];
$createSyntax = self::getTableSyntax ( $tableName );
$p = strpos ( $createSyntax, "COMMENT=" );
if ( $p ) {
$comments = substr ( $createSyntax, $p + 9 );
$comments = substr ( $comments, 0, strlen ( $comments ) - 1 );
foreach ( explode ( ';', $comments ) as $attrib ) {
list ( $key, $val ) = explode ( '=', $attrib );
$attributes[$key] = $val;
}
}
return $attributes;
}
public static function addTableComments ( $tableName, $attributes ) {
$allComments = array_merge ( self::getTableComments ( $tableName ), $attributes );
self::setTableComments ( $allComments );
}
public static function setTableComments ( $tableName, $attributes ) {
$tempArray = [];
foreach ( $attributes as $key => $val ) $tempArray[] = $key . '=' . $val;
$comments = join ( ';', $tempArray );
$sql = "ALTER TABLE {$tableName} COMMENT ?";
DB::exec ( DB::DEF, $sql , $comments );
}
private static function getTableSyntax ( $tableName ) {
if ( DB::driver() == DB::SQLITE ) {
return DB::oneValue( DB::DEF, "SELECT sql FROM sqlite_master where type='table' and tbl_name='$tableName'" );
}
else {
$createTable = new DBTable ( DB::DEF, 'SHOW CREATE TABLE ' . $tableName );
return $createTable->getValue ( 1, 0 );
}
}
}
|