php 实现 ruby on rails active recorder

作者: 李锋
发布时间:2015-07-13 11:31:26

<?php

define('FIND_PARTTERN','/^find_(.+)(_and_.+)*(_by_)?(.+)?(_and_.+)*(_or_.+)*$/');
define('UPDATE_PARTTERN','/^update_(.+)(_and_.+)*(_by_)?(.+)?(_and_.+)*(_or_.+)*$/');
define('DELETE_PARTTERN','/^delete_by_(.+)(_and_.+)*(_or_.+)*$/');
define('SQL_CACHE','../_/_____.php');


include('../configs/config.php');
include(SQL_CACHE);

function get_key_words()
{
    
return array('all'=>'*','_or_'=>'or','_by_'=>'where','find_'=>'select','_and_'=>'and','delete'=>'delete','update_'=>'update');
}

function get_key_part_words()
{
    
return array('_or','_by','fin','_an','upd','del','find','_and','upda','dele','updat','delet','update');
}

class DB
{
    
private $conn=null;
    
private $conn_state=null;
    
    
public function open()
    {
        
$all_db_conf = get_all_db_conf();
        
$conf = $all_db_conf[get_class($this)];
        
$this->conn = mysql_connect($conf[0],$conf[1],$conf[2]);
        
$names=$this->get_names();
        
mysql_query("SET NAMES $names", $this->conn);
        
mysql_select_db($conf[3]);
        
$this->conn_state='opened';
    }

    
public function get_names()
    {
        
return 'utf8';
    }
    
    
public function query_rows($sqls)
    {
        
if($this->conn_state!='opened')
        {
            
$this->open();
            
$auto_close=true;
        }
        
        
$array=array();
        
$result = mysql_query($sqls,$this->conn);
        
while($row = mysql_fetch_assoc($result))
        {
            
$array[] = $row;
        }
        
        
mysql_free_result($result);
        
        
if($auto_close)
            
$this->close();
        
        
return $array;
    }
    
    
public function execute_non_query($sqls)
    {
        
if($this->conn_state!='opened')
        {
            
$this->open();
            
$auto_close=true;
        }
        
        
$result = mysql_query($sqls);
        
if($auto_close)
            
$this->close();
            
        
return $result;
    }
    
    
public function close()
    {
        
mysql_close($this->conn);
        
$this->conn_state='closed';
    }  
}

abstract class Table
{
    
private $table_name = null;
    
private $db = null;
    
    
public function __construct()
    {
        
$this->table_name = get_class($this);
        
$this->db = $this->get_db();
    }
    
    
protected abstract function get_db();
    
    
public function query_rows($sqls)
    {
        
return $this->db->query_rows($sqls);
    }
    
    
public function execute_non_query($sqls)
    {
        
return $this->db->execute_non_query($sqls);    
    }
    
    
public function append($single_row_to_append)
    {
        
$sqls = "insert into $this->table_name ( ";
        
$values = '';
        
$has_item = false;
        
        
foreach($single_row as $k => $v)
        {
            
if($has_item)
            {
                
$sqls.=',';
                
$values.=',';
            }
            
            
$sqls.=$k;
            
$values.="'$v'";
            
$has_item = true;
        }
        
        
return $this->db->execute_non_query("$sqls ) values $values )");
    }
    
    
public function delete_by_condition($condition)
    {
        
return $this->db->execute_non_query("delete from $this->table_name where $condition");
    }
    
    
public function find_all()
    {
        
return $this->db->query_rows("select * from $this->table_name");
    }
    
    
public function find_all_by_condition($condition)
    {
        
return $this->db->query_rows("select * from $this->table_name where $condition");
    }

    
public function __call($name,$arguments)
    {
        
$v = get_class($this->get_db()).'_'.$this->table_name.'_'.$name;

        
global $$v;
        
$u = $$v;

        
if(isset($u))
        {
            
return $this->execute_query_or_non(vsprintf($u,$arguments));
        }


        
$sqls = $this->parse_sql_from_name($name,$arguments);

        
if($sqls=='syntax error')
        {
            
echo $sqls;
            
return;
        }

        
$this->write_parsed_sqls("\$$v=\"$sqls\";");

        
return $this->execute_query_or_non(vsprintf($sqls,$arguments));
    }

    
//////////////////////////////////////////////////////////////////

    
private function write_parsed_sqls($message)
    {
        
$fp=fopen(SQL_CACHE,'a');
        
fwrite($fp,"<?php $message ?>\r\n");
        
fclose($fp);
    }

    
private function parse_sql_from_name($name,$arguments)
    {
        
$key_words= get_key_words();
        
$key_part_words= get_key_part_words();
        
$length = strlen($name);
        
$s='';
        
$tokens=array();
        
$verb='';
        
        
if(preg_match(UPDATE_PARTTERN,$name))
            
$verb='update';
        
else if(preg_match(FIND_PARTTERN,$name))
            
$verb = 'select';
        
else if(preg_match(DELETE_PARTTERN,$name))
            
$verb = 'delete';
        
else
            
return 'syntax error';
        
        
$after_where = false;
        
        
for($i=0;$i<$length;)
        {
            
for($j=3;$j<=7;$j++)
            {
                
$token = substr($name,$i,$j);
                
if(array_key_exists($token,$key_words))
                {
                    
if($s!='')
                    {
                        
if($after_where && $s!='condition')
                            
$tokens[]="$s='%s'";
                        
else if($s=='condition')
                                
$tokens[]='%s';
                        
else
                        {
                            
if($verb=='update')
                                
$tokens[]="$s='%s'";
                            
else
                                
$tokens[]=$s;
                        }
                        
                        
$s='';
                    }
                    
                    
if($token=='_by_')
                        
$after_where = true;
                    
                    
if(!$after_where && $token=='_and_')
                        
$tokens[]=',';
                    
else
                        
$tokens[]=$key_words[$token];
                    
                    
$i+=$j;
                    
                    
break;
                }
                
else if(in_array($token,$key_part_words))
                {
                    
continue;
                }
                
else
                {
                    
$s.= $name[$i];
                    
$i++;
                    
break;
                }
            }
        }
        
        
if($s!='')
        {
            
if($s=='condition')
                
$tokens[]='%s';
            
else if($after_where && $s!='condition')
                    
$tokens[]="$s='%s'";
            
else
            {
                
if($verb=='update')
                    
$tokens[]="$s='%s'";
                
else
                    
$tokens[]=$s;
            }
        }
        
        
switch($verb)
        {
            
case 'select':
                
$where_index = array_search('where',$tokens);
                
if($where_index)
                    
$tokens[$where_index= "from $this->table_name where";
   &

来源:http://www.cnblogs.com/suicide/archive/2009/06/17/1505244.ht

推荐: