<?php

/**

1.3 전역상수 사용 금지, 대신 $pdoconfig 전역변수이용

1.2 17-9-25
 prepare / execute이용하도록함
  
1.1 
 query numAffected 정확하게 얻도록함
 
PDO database warpping 모듈 1.0

사용방법:

기본
opendb();
$rows = query("select * from table");

복잡 (멀티플 쿼리)
$db->opendb();
$db->query('set @rownum := 0'); 
$rows = $db->query($"
			select *, @rownum := @rownum+1 rank
				
			from site b, terminal a
			where (a.서비스코드=b.서비스코드)
				and (
					fwrevision = 2777 
					or lasterror <> ''
				);			
		");
		
연속 쿼리를 하면 이전 쿼리값이 유지됨. 

@module pdodb

*/

$pdodb_caches = array();

class PDOWrap
{
	var $pdo = null;
	function __construct($pdo)
	{
		$this->pdo = $pdo;
	}
	function __destruct()
	{
		$this->pdo = null;
	}
/*
function exec($q) // php는 바깥쪽 변수 쓰기가 불편해서 callback 방식이 좋지 않다
	{
		$db = $this->pdo;
		$result = array();
		$stmt = $db->prepare($q);
		if ($stmt->execute() ===false)
			throw "쿼리실패";
		$result[numAffected] = $stmt->rowCount();
		$result[insertId] = $db->lastInsertId();			
		$result[stmt] = $stmt;
		
		return $result;
	}
	function exec($q) // php는 바깥쪽 변수 쓰기가 불편해서 callback 방식이 좋지 않다
	{
		$db = $this->pdo;
		
		$result = array();
		$result[numAffected] = $db->exec($q);
		$result[insertId] = $db->lastInsertId();
		$result[lastInsertId] = $db->lastInsertId();
		return $result;
	}
*/
	function exec($q, $params=null) // php는 바깥쪽 변수 쓰기가 불편해서 callback 방식이 좋지 않다
	{
		$db = $this->pdo;
		
		$sth = $db->prepare($q);
		// $params = $this->build_pdo_params($params);
		if ($params) {
			$params = $this->bind_params($sth, $q, $params);
		}		
		$sth->execute();
		
		$result = array();
		$result[numAffected] = $sth->rowCount();
		$result[insertId] = $db->lastInsertId();
		$result[lastInsertId] = $db->lastInsertId();
		return $result;
	}
	
	/*
	function query($q) 
	{
		if (stripos($q, 'select ') === false)
		{
			return $this->exec($q, $func);
		}
		$db = $this->pdo;
		$rows = $db->query($q);
		echo gettype($rows); die();
		$rows = $rows->fetchAll();
		return $rows;
	}
	*/
	function build_pdo_paramsX($params)
	{
		if (!$params)
			return $params;
		$result = array();
		foreach($params as $key=>$val) {
			if ($key[0] != ':') {
				$key = ':'.$key;
			}
			$result[$key] = $val;
		}
		//print_r($result);
		return $result;
	}
	function bind_params($sth, $q, $params)
	{
		//$result = array();
		preg_match_all('/:[a-zA-Z_][a-zA-Z0-9_]*/', $q, $matches);
		$keys = $matches[0];
		foreach($keys as $key) {
			$k = substr($key, 1, 9999);
			$val = $params[$k];
			if ($val === '') // 공백은 null로
				$val = null;
			$sth->bindValue($key, $val);
		}
		//return $result;
	}
	function query($q, $params=null) 
	{
		/*
		$db = $this->pdo;
		$sth = $db->prepare($q);
		if ($params) {
			$params = $this->bind_params($sth, $q, $params);
		}		
		try {
			$sth->execute();	
		} catch(Exception $e) {
			echo "$q";
			print_r($params);
			$sth->debugDumpParams();
			throw $e;
		}
		//$sth->debugDumpParams();
		*/
		$db = $this->pdo;
		$sth = $this->query_nofetch($q, $params);
		
		if ($sth->columnCount() > 0) { // query 문
			$result = $sth->fetchAll();
		} else {
			$result = array();
			$result[numAffected] = $sth->rowCount();
			$result[insertId] = $db->lastInsertId();
			$result[lastInsertId] = $db->lastInsertId();			
		}
//		echo 'row count:'.$sth->rowCount()."\n";
	//  echo 'column count:'.$sth->columnCount()."\n";
		return $result;
	}
	
	function query_nofetch($q, $params=null) 
	{
		$db = $this->pdo;
		$sth = $db->prepare($q);
		if ($params) {
			$params = $this->bind_params($sth, $q, $params);
		}		
		//try {
		$sth->execute();	
		/*} catch(Exception $e) {
			//echo "$q";
			//print_r($params);
			$sth->debugDumpParams();
			throw $e;
		}*/		
		return $sth;
	}
	
	function lastinsertid()
	{
		return $this->pdo->lastInsertId();
	}
}

function opendb($pdoconfig = null)
{
	$db = pdo($pdoconfig);
	return new PDOWrap($db);
}

function pdo($pdoconfig = null)
{
	global $pdodb_caches;
	
	if ($pdoconfig == null)
	{
		$pdoconfig = $GLOBALS[pdoconfig];
	}
	//print_r($pdoconfig);
	$c = $pdoconfig;
	$dsn = $c->dsn();
	$user = $c->user;
	$pw = $c->password;
	
	$dbh = $pdodb_caches[$dsn];
	if ($dbh != null)
		return $dbh;
	
	$dbh = new PDO($dsn, $user, $pw, array(/*PDO::MYSQL_ATTR_INIT_COMMAND*/1002 => "SET NAMES utf8mb4"));
	$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
	//$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
	
	$pdodb_caches[$dsn] = $dbh;
	
	return $dbh;
}

function query($q, $params = null)
{
	$db = opendb();
	return $db->query($q, $params);
}

/*
function lastinsertid()
{
	$db = opendb();
	return $db->lastInsertId();
}
*/

function query_nofetch($q, $params=null)
{
	$db = opendb();
	return $db->query_nofetch($q, $params);
}


/*
function pdo_old($pdoconfig = null)
{
	if ($pdoconfig == null)
	{
		$dbh = new PDO(DB_DSN,DB_USER,DB_PASSWORD, array(1002 => "SET NAMES utf8"));
	} else
	{
		$c = $pdoconfig;
		$dbh = new PDO($c->dsn(), $c->user, $c->password, array(1002 => "SET NAMES utf8"));
	}
	$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
	return $dbh;
}
*/

?>