Location: PHPKode > scripts > SQL Data > buildClass.php
<?php
/**
 * @author Dick Munroe <hide@address.com>
 * @copyright copyright @ Dick Munroe, 2004-2006, All rights reserved.
 * @license http://www.csworks.com/publications/ModifiedNetBSD.html
 */

//
// Construct a class interface to a mySQL table using the SQLData
// class and the underlying DB class both available from phpclasses.org.
//
// My thanks to Chris Sands, the Director of IT at the Florida Democratic
// Party, for permission to submit this program for general use.
//
//	$Author: dickmunroe $
//	$Date: 2007/12/26 15:41:56 $
//
// Edit History:
//
//  Dick Munroe hide@address.com 21-Oct-2004
//      Initial Version Created
//
//  Dick Munroe hide@address.com 06-Nov-2004
//	Update the print_r function to use dump_object.
//
//  Dick Munroe hide@address.com 09-Nov-2004
//	For tables with autoincrement fields, generate a default selector
//  	and an insert method that gets the value of the generated number.
//	For tables with unique keys, generate a default selector from any
//	of the keys that might be in the table at run time.
//	For tables with multiple value keys, generate an and of all the
//	values with a limit of 1 as a best guess.
//
//  Dick Munroe hide@address.com 13-Nov-2004
//	Tweak to get return value from constructed insert right.
//
//  Dick Munroe hide@address.com 16-Nov-2004
//	Generate an "un_set" function for every data field.
//
//  Dick Murnoe hide@address.com 05-Dec-2004
// 	Generate an is_set function for every data field.
//
//  Dick Munroe hide@address.com 12-Dec-2004
//	Redesign to work with the output of the show keys query.
//
//  Dick Munroe hide@address.com 13-Dec-2004
//	is_set didn't return a value.
//
//  Dick Munroe hide@address.com 01-May-2005
//	Switch to use the released version of the Structured Data Dumper.
//	Switch to requiring the user of the build* routines to put
//	the Structured data dumper and the SQLData classes into their
//	php include path.
//	Get the help text right given the limitations of getopt.
//
//  Dick Munroe hide@address.com 03-May-2005
//	Write files.
//
//  Dick Munroe hide@address.com 13-Nov-2005
//      tablename in class got lost somehow.
//
//  Dick Munroe hide@address.com 14-Mar-2006
//	    Change licensing, reorganize includes.
//
//  Dick Munroe (hide@address.com) 13-Oct-2006
//      Use database independent interface, generate MySQL structures.
//
//  Dick Munroe (hide@address.com) 02-Nov-2006
//      Minor tweak for better php5 compatibility.
//

include_once('dm.DB/class.factory.DB.php') ;
include_once('ISLayout/class.IS_Layout.php') ;
include_once('SDD/class.SDD.php') ;
include_once('SQLData/options.php') ;

$theOptions = getopt("h:p:u:d:") ;

if (count($_SERVER['argv']) < 3)
{
    print("
buildClass [-h hostname] [-u username] [-p password] [-d DBType] tableName databaseName

    Due to limitations in the PHP's getopt implementation, the table and
    database names must appear last and are both required.  This writes files
    of the form \"class.tableName.php\".  These classes are included by
    forms generated by buildForm.php and form processors build by
    buildProcessForm.
") ;
    return 0 ;
}

//
// Unfortunately PHP doesn't do the argv reduction common to all
// other implementations of getopt, so I'm requiring that the
// table and database names be the first two arguments.
//

$theTableName = $_SERVER['argv'][count($_SERVER['argv']) - 2] ;
$theDatabaseName = $_SERVER['argv'][count($_SERVER['argv']) - 1] ;

if (empty($theTableName))
{
    die('A table name is needed') ;
}

if (empty($theDatabaseName))
{
    die('A database name is needed') ;
}

options($theOptions) ;

$theDB =
    FactoryDB::factory(
        $theOptions['u'],                               // Username
        $theOptions['p'],                               // Password
        $theDatabaseName,                               // Database
        $theOptions['h'],                               // Host
        $theOptions['d']) ;                             // Database Type

$theValidResults = array() ;

$theResultArray = $theDB->describeTable($theTableName) ;

foreach ($theResultArray as $xxx)
{
    $theValidResults[$xxx['Field']] = $xxx ;
}

$theKeyData = $theDB->showKeys($theTableName) ;

//
// Preserve the outfile, if one already exists.
//

$theFileName = sprintf("class.%s.php", ucfirst($theTableName)) ;
$theOldFileName = $theFileName . ".old" ;

if (file_exists($theFileName))
{
    if (is_file($theFileName))
    {
        if (!rename($theFileName, $theOldFileName))
        {
            exit(1) ;
        }
    }
    else
    {
        exit(2) ;
    }
}

if (!($theStream = @fopen($theFileName, 'w')))
{
    exit(3) ;
}

//
// Build the basic class interface
//

fwrite($theStream, '<?php

//
// Class: ' . ucfirst($theTableName) . '
// Table: ' . $theTableName . '
// Database: ' . $theDatabaseName . '
// Database Type: ' . $theOptions['d'] . '
// Generated by buildClass.php, written by Dick Munroe (hide@address.com)
//

include_once("' . sprintf('class.SQLData.%s.php', $theOptions['d']) . '") ;
include_once("SDD/class.SDD.php") ;

class ' . ucfirst($theTableName) . ' extends SQLData' . $theOptions['d'] . '
{
') ;

fwrite($theStream, sprintf('
    //
    // Private (or constant) varibles.
    //

    var $m__tableName = \'%s\' ;
',  $theTableName)) ;

fwrite($theStream, '
    //
    // Constructor
    //

    function ' . ucfirst($theTableName) . '($_dataBase,
                     $_host="localhost",
                     $_login="",
                     $_password="")
    {
        $this->SQLData' . $theOptions['d'] .'(
			$this->m__tableName,
			$_dataBase,
			$_host,
			$_login,
			$_password) ;
    }

    //
    // Accessor Functions
    //

') ;

foreach ($theValidResults as $theResultArray)
{
    fwrite($theStream, sprintf('    function set%s($theValue)
    {
        $this->set(\'%s\', $theValue) ;
    }

    function get%s()
    {
        return $this->get(\'%s\') ;
    }

    function init%s($theValue)
    {
        $this->init(\'%s\', $theValue) ;
    }

    function un_set%s()
    {
        $this->un_set(\'%s\') ;
    }

    function is_set%s()
    {
        return $this->is_set(\'%s\') ;
    }

',         ucfirst($theResultArray['Field']),
           $theResultArray['Field'],
           ucfirst($theResultArray['Field']),
           $theResultArray['Field'],
           ucfirst($theResultArray['Field']),
           $theResultArray['Field'],
           ucfirst($theResultArray['Field']),
           $theResultArray['Field'],
           ucfirst($theResultArray['Field']),
           $theResultArray['Field']
    )) ;
}

if (!empty($theKeyData))
{
    fwrite($theStream, '    //
    // Default update selector
    //

') ;

    $theUniqueKey = array() ;
    $theMultipleKey = array() ;

    foreach($theKeyData as $theKey)
    {
        switch($theKey['Non_unique'])
        {
            case 0:
            {
                $theUniqueKey[$theKey['Key_name']][] = $theKey ;
            }
            break ;

            default:
            {
                $theMultipleKey[$theKey['Key_name']][] = $theKey ;
            }
            break ;
        }
    }

    if (!empty($theUniqueKey))
    {
        fwrite($theStream, '    function needUpdateSelector()
    {
') ;

        foreach ($theUniqueKey as $theKeyName=>$theKeyArray)
        {
            $thePredicate = "" ;
            $theSelect = "where " ;

            foreach ($theKeyArray as $theKeyItem)
            {
                $thePredicate .= sprintf('($this->is_set%s()) && ', ucfirst($theKeyItem['Column_name'])) ;
                $theSelect .=
                    sprintf(
                        '%s = \'" . $this->escape_string($this->get%s()) . "\' and ',
                        addcslashes($theDB->quoteIdentifier($theKeyItem['Column_name']), '"'),
                        ucfirst($theKeyItem['Column_name'])) ;
            }

            $thePredicate = substr($thePredicate, 0, -4) ;
            $theSelect = substr($theSelect, 0, -5) ;

            fwrite(
                $theStream,
                sprintf(
                    '        if (%s)
           return "%s" ;

',		            $thePredicate,
                    $theSelect)) ;
        }

        fwrite($theStream, '        trigger_error("Internal Logic Error: No key data present", E_USER_ERROR) ;
    }

') ;
    }

    if ((!empty($theUniqueKey['PRIMARY'])) &&
        ($theValidResults[$theUniqueKey['PRIMARY'][0]['Column_name']]['Extra'] == 'auto_increment'))
    {
        fwrite(
            $theStream,
            sprintf('    //
    // Insert function
    //

    function insert()
    {
        $theReturnValue = parent::insert() ;
        if ($theReturnValue)
        {
            $this->init%s($this->fetchLastInsertId(%s)) ;
        }
        return $theReturnValue ;
    }

',	            ucfirst($theUniqueKey['PRIMARY'][0]['Column_name']),
                (empty($theUniqueKey['PRIMARY'][0]['Sequence']) ? '' : '"' . $theUniqueKey['PRIMARY'][0]['Sequence'] . '"'))) ;
    }
}


fwrite(
    $theStream,
    '    //
    // Debugging Functions
    //

    function print_r()
    {
      print(SDD::dump($this)) ;
    }
}

?>
') ;

fclose($theStream) ;

// Use $_SERVER['PATH_TRANSLATED']

$theDirectoryName = dirname($_SERVER['PATH_TRANSLATED']) ;

$theTemplateName = sprintf('%s/class.SQLData.template', $theDirectoryName) ;
$theFileName =
    sprintf(
        './class.SQLData.%s.php',
        $theOptions['d']) ;
$theOldFileName = $theFileName . ".old" ;

if (file_exists($theFileName))
{
    if (is_file($theFileName))
    {
        if (!rename($theFileName, $theOldFileName))
        {
            exit(1) ;
        }
    }
    else
    {
        exit(2) ;
    }
}

if (!($theStream = @fopen($theFileName, 'w')))
{
    exit(3) ;
}

$theLayout = new IS_Layout($theTemplateName) ;
$theLayout->replaceConstant(
    'DATABASE-SPECIALIZATION',
    $theOptions['d']) ;

fwrite($theStream, $theLayout->toRawHTML()) ;

fclose($theStream) ;

exit(0) ;
?>
Return current item: SQL Data