GenerateModelクラス
やっていることは、MyGeneration版と全く同じです。
前の記事にあるCapsuleライブラリが必須なのであらかじめダウンロードしておいてください。
その後、以下のクラスをCapsuleディレクトリに配置してください。
<?php
/**
* モデルクラスの自動生成
* @author Daijiro Abe
* @date 2007.12.06
*/
require_once("adodb/adodb.inc.php");
class GenerateModels
{
var $dsn;
var $dir = "classes";
var $sep = "/";
function GenerateModels($dsn)
{
$this->dsn = $dsn;
}
/**
* 生成ディレクトリを返します
* @return 生成ディレクトリ名
*/
function getDirectory()
{
$dir = $this->dir;
if(substr($dir, strlen($dir)-1, 1) != $this->sep)
$dir .= $this->sep;
return $dir;
}
/**
* 生成ディレクトリを設定します
* @param $dir 生成ディレクトリ
*/
function setDirectory($dir)
{
$this->dir = $dir;
}
/**
* ディレクトリセパレータを返します
* @return ディレクトリセパレータ
*/
function getSeparator()
{
return $this->sep;
}
/**
* ディレクトリセパレータを設定します
* @param $sep ディレクトリセパレータ
*/
function setSeparator($sep)
{
$this->sep = $sep;
}
/**
* クラスファイルの生成
* @return 失敗時にfalse、それ以外でtrue
*/
function generate()
{
$conn = &ADONewConnection($this->dsn);
$date = date("Y/m/d");
$dsn = $this->dsn;
$fp = fopen($this->dir . $this->sep . "CommonDAO.php", "w");
if(!$fp)
return false;
$body = <<< PHP_END
<?php
/**
* @class CommonDAO
* @brief 共通DAOクラス
* @author Daijiro Abe
* @date {$date}
*/
require_once(dirname(__FILE__) . '/../lib/Capsule/AbstractDAO.php');
require_once(dirname(__FILE__) . '/../lib/Capsule/AbstractDTO.php');
require_once(dirname(__FILE__) . '/../lib/Capsule/Collection.php');
class CommonDAO extends AbstractDAO
{
function CommonDAO()
{
\$this->connect("{$dsn}");
}
}
PHP_END;
if(fwrite($fp, $body) === FALSE)
return false;
fclose($fp);
$tables = $conn->MetaTables("TABLES");
foreach($tables as $table)
{
$columns = $conn->MetaColumnNames($table, true);
$pkeys = $conn->MetaPrimaryKeys($table);
$class_name = ucfirst($table);
$dirpath = $this->dir . $this->sep . $class_name;
if(!file_exists($dirpath))
mkdir($dirpath);
$dirpath .= $this->sep;
// DTOクラスの生成
$dto_class = $class_name;
$dto_path = $dirpath . $dto_class . ".php";
$fp = fopen($dto_path, "w");
if(!$fp)
return false;
$body = <<< PHP_END
<?php
/**
* {$dto_class}クラス
* @author Daijiro Abe
* @date {$date}
*/
class {$dto_class} extends AbstractDTO
{
PHP_END;
foreach($columns as $column)
{
$column = strtolower($column);
$method = ucfirst($column);
$body .= "\tfunction get$method()\n";
$body .= "\t{\n";
$body .= "\t\treturn \$this->get(\"$column\");\n";
$body .= "\t}\n";
$body .= "\tfunction set$method(\$$column)\n";
$body .= "\t{\n";
$body .= "\t\t\$this->set(\"$column\", \$$column);\n";
$body .= "\t}\n";
}
$body .= "}\n";
if(fwrite($fp, $body) === FALSE)
return false;
fclose($fp);
// Collectionクラスの生成
$collection_class = $class_name . "Collection";
$collection_path = $dirpath . $collection_class . ".php";
$fp = fopen($collection_path, "w");
if(!$fp)
return false;
$body = <<< PHP_END
<?php
/**
* {$collection_class}クラス
* @author Daijiro Abe
* @date {$date}
*/
require_once(dirname(__FILE__) . "/{$class_name}.php");
class {$collection_class} extends Collection
{
function &makeObject(\$array)
{
\$obj = new {$class_name}(\$array);
return \$obj;
}
}
PHP_END;
if(fwrite($fp, $body) === FALSE)
return false;
fclose($fp);
// DAOクラスの生成
$dao_class = $class_name . "DAO";
$dao_path = $dirpath . $dao_class . ".php";
$fp = fopen($dao_path, "w");
if(!$fp)
return false;
$body = <<< PHP_END
<?php
/**
* {$dao_class}クラス
* @author Daijiro Abe
* @date {$date}
*/
require_once(dirname(__FILE__) . "/../CommonDAO.php");
require_once(dirname(__FILE__) . "/{$class_name}Collection.php");
class {$dao_class} extends CommonDAO
{
PHP_END;
if($pkeys)
{
$body .= "\tfunction &findByPrimaryKey(";
foreach($pkeys as $index => $pkey)
{
$pkey = strtolower($pkey);
if($index > 0)
$body .= ", ";
$body .= "$" . $pkey;
}
$body .= ")\n";
$body .= "\t{\n";
$body .= "\t\treturn \$this->queryOne(\"select * from $table where ";
foreach($pkeys as $index => $pkey)
{
$pkey = strtolower($pkey);
if($index > 0)
$body .= " AND ";
$body .= "$pkey = ?";
}
$body .= "\", array(";
foreach($pkeys as $index => $pkey)
{
$pkey = strtolower($pkey);
if($index > 0)
$body .= ", ";
$body .= "$" . $pkey;
}
$body .= "));\n";
$body .= "\t}\n";
}
$body .= "\tfunction &findAll()\n";
$body .= "\t{\n";
$body .= "\t\treturn \$this->query(\"select * from $table\");\n";
$body .= "\t}\n";
$body .= "\tfunction insert(\$".$table.")\n";
$body .= "\t{\n";
$body .= "\t\treturn \$this->doInsert(\"$table\", \$".$table."->get());\n";
$body .= "\t}\n";
if($pkeys)
{
$body .= "\tfunction update(\$$table)\n";
$body .= "\t{\n";
foreach($pkeys as $index => $pkey)
{
$pkey = strtolower($pkey);
$body .= "\t\t\$" . $pkey . " = \$this->qstr(\$" . $table . "->get(\"$pkey\"));\n";
}
$body .= "\t\treturn \$this->doUpdate(\"$table\", \$".$table."->get(), \"";
foreach($pkeys as $index => $pkey)
{
$pkey = strtolower($pkey);
if($index > 0)
$body .= " AND ";
$body .= "$pkey = \$".$pkey;
}
$body .= "\");\n";
$body .= "\t}\n";
}
$body .= "\tfunction &createCollection(\$result)\n";
$body .= "\t{\n";
$body .= "\t\t\$collection = new " . $collection_class . "(\$result);\n";
$body .= "\t\treturn \$collection;\n";
$body .= "\t}\n";
$body .= "}\n";
if(fwrite($fp, $body) === FALSE)
return false;
fclose($fp);
}
return true;
}
}
このクラスが、クラス生成を行います。
実際に実行させるコードは以下のような単純なものです。
<?php
require_once("lib/Capsule/GenerateModels.php");
require_once("define.php");
$generator = new GenerateModels(DATABASE_DSN);
if(!$generator->generate())
print "ERROR!\n";
else
print "SUCCESS!\n";
デフォルトで(上記サンプルのままで)、実行ディレクトリ下のclasses内にクラス群を生成します。
setDirectory()メソッドで変更が可能です。一応、setSeparator()メソッドでディレクトリの区切り文字を変更できますが、もしかしたらあんまり意味がないかも...。
追記
上記最後のソースで、define.phpをincludeしてますが、これはDATABASE_DSNという名前でデータベース接続のDSNをdefineしているだけです。
<?php
/**
* 共通定義ファイル
*/
define("DATABASE_DSN", "postgres://postgres:postgres@localhost/topics");
こんな感じです。

