EDB
[ class tree: EDB ] [ index: EDB ] [ all elements ]

Source for file EDB_SQLRELAY.php

Documentation is available at EDB_SQLRELAY.php

  1. <?php
  2. /**
  3.  * Project: EDB_SQLRELAY :: SQLRELAY abstraction layer
  4.  * File:    EDB/EDB_SQLRELAY.php
  5.  *
  6.  * The EDB_SQLRELAY class is SQLRelay abstraction layer that used internally
  7.  * on EDB class.
  8.  *
  9.  * @category    Database
  10.  * @package     EDB
  11.  * @subpackage  EDB_ABSTRACT
  12.  * @author      JoungKyun.Kim <http://oops.org>
  13.  * @copyright   (c) 2018, JoungKyun.Kim
  14.  * @license     BSD License
  15.  * @version     $Id$
  16.  * @link        http://pear.oops.org/package/EDB
  17.  * @filesource
  18.  */
  19.  
  20. /**
  21.  * SQLRELAY engine for EDB API
  22.  *
  23.  * This class support abstracttion DB layer for SQLRELAY Engine
  24.  *
  25.  * @package     EDB
  26.  */
  27. Class EDB_SQLRELAY extends EDB_Common {
  28.     // {{{ properties
  29.     /**#@+
  30.      * @access private
  31.      */
  32.     /**
  33.      * db handler of EDB_SQLRELAY class
  34.      * @var    object 
  35.      */
  36.     private $db;
  37.     /**
  38.      * The number of query parameter
  39.      * @var    integer 
  40.      */
  41.     private $pno 0;
  42.     /**
  43.      * The current offset of result rows
  44.      * @var    integer 
  45.      */
  46.     private $rowid;
  47.     /**
  48.      * The last rownums of result rows
  49.      * @var    integer 
  50.      */
  51.     private $rownum;
  52.     /**#@-*/
  53.     // }}}
  54.  
  55.     // {{{ (object) EDB_SQLRELAY::__construct ($host, $user, $pass)
  56.     /** 
  57.      * Instantiates an EDB_SQLRELAY object and opens an SQLRELAY database
  58.      *
  59.      * For examples:
  60.      * <code>
  61.      * $db = new EDB_SQLRELAY ('sqlrelay://localhost', 'user', 'host');
  62.      * $db = new EDB_SQLRELAY ('sqlrelay://localhost:9000', 'user', 'host');
  63.      * $db = new EDB_SQLRELAY ('sqlrelay://localhost:/path/sock', 'user', 'host');
  64.      * </code>
  65.      *
  66.      * If you add prefix 'p~' before host, you can connect with persistent
  67.      * connection.
  68.      *
  69.      * For Examples:
  70.      * <code>
  71.      * $db = new EDB_SQLRELAY ('sqlrelay://p~localhost', 'user', 'host', 'database');
  72.      * </code>
  73.      *
  74.      * @access public
  75.      * @return EDB_SQLRELAY 
  76.      * @param  string  $hostname SQLRELAY host
  77.      * @param  string  $user     SQLRELAY user
  78.      * @param  string  $password SQLRELAY password
  79.      * @param  string  $database SQLRELAY database
  80.      */
  81.     function __construct ({
  82.         $_argv func_get_args ();
  83.         $argv is_array ($_argv[0]$_argv[0$_argv;;
  84.  
  85.         if extension_loaded ('sql_relay') )
  86.             throw new myException ('SQLRELAY extension is not loaded on PHP!'E_USER_ERROR);
  87.  
  88.         $o = (object) array (
  89.             'host' => preg_replace ('!^sqlrelay://!'''$argv[0]),
  90.             'user' => $argv[1],
  91.             'pass' => $argv[2],
  92.         );
  93.  
  94.         if preg_match ('/([^:]+):(.*)/'$o->host$matches) ) {
  95.             $o->host $matches[1];
  96.             $o->port $matches[2];
  97.         else
  98.             $o->port 9000;
  99.  
  100.         if is_numeric ($o->port) ) {
  101.             $o->sock $o->port;
  102.             $o->port 9000;
  103.         else
  104.             $o->sock null;
  105.  
  106.         try {
  107.             $this->db sqlrcon_alloc ($o->host$o->port$o->sock$o->user$o->pass01);
  108.             $this->result  = sqlrcur_alloc ($this->db);
  109.  
  110.             if sqlrcon_ping ($this->db) )
  111.                 throw new myException (sqlrcur_errorMessage ($this->db)E_USER_ERROR);
  112.         catch Exception $e {
  113.             throw new myException ($e->getMessage ()$e->getCode()$e);
  114.         }
  115.     }
  116.     // }}}
  117.  
  118.     // {{{ (string) EDB_SQLRELAY::get_charset (void)
  119.     /** 
  120.      * Get character set of current database
  121.      *
  122.      * SQLRELAY extension don't support this function
  123.      *
  124.      * @access public
  125.      * @return string Current character set name on DB
  126.      */
  127.     function get_charset ({
  128.         return 'Unsupport';
  129.     }
  130.     // }}}
  131.  
  132.     // {{{ (bool) EDB_SQLRELAY::set_charset ($charset)
  133.     /** 
  134.      * Set character set of current database
  135.      *
  136.      * This method is always returned true because SQLRELAY don't support
  137.      * charset settings.
  138.      *
  139.      * @access public
  140.      * @return bool    always return true
  141.      * @param  string  name of character set that supported from database
  142.      */
  143.     function set_charset ($char{
  144.         return true;
  145.     }
  146.     // }}}
  147.  
  148.     // {{{ (string) EDB_SQLRELAY::escape ($string)
  149.     /** 
  150.      * Escape special characters in a string for use in an SQL statement
  151.      *
  152.      * Attention! This method always returns original string.
  153.      *
  154.      * @access public
  155.      * @return string 
  156.      * @param  string  The string that is to be escaped.
  157.      */
  158.     function escape ($string{
  159.         return $string;
  160.     }
  161.     // }}}
  162.  
  163.     // {{{ (int) EDB_SQLRELAY::query ($query, $param_type, $param1, $param2 ...)
  164.     /** 
  165.      * Performs a query on the database
  166.      *
  167.      * @access public
  168.      * @return integer The number of affected rows or false
  169.      * @param  string  $query The query strings
  170.      * @param  string  $type  (optional) Bind parameter type. See also
  171.      *  <code>
  172.      *  i => integer
  173.      *  d => double
  174.      *  s => string
  175.      *  b => blob
  176.      *  </code>
  177.      * @param  mixed   $param1 (optional) Bind parameter 1
  178.      * @param  mixed   $param2,... (optional) Bind parameter 2 ..
  179.      */
  180.     function query ({
  181.         $_argv func_get_args ();
  182.         $argv is_array ($_argv[0]$_argv[0$_argv;;
  183.  
  184.         $this->error null;
  185.  
  186.         try {
  187.             $sql array_shift ($argv);
  188.             $this->pno count ($argv$this->get_param_number ($sql'sqlrelay'0;
  189.  
  190.             if $this->free )
  191.                 $this->free_result ();
  192.  
  193.             // store query in log variable
  194.             $this->queryLog[$sql;
  195.  
  196.             // 얼마나 많은 라인을 받을 것인지.. 0은 무제한
  197.             //sqlrcur_setResultSetBufferSize ($this->result, 0);
  198.  
  199.             if $this->pno++ == // no bind query
  200.                 $this->no_bind_query ($sql);
  201.             else // bind query
  202.                 $this->bind_query ($sql$argv);
  203.  
  204.             $this->rowid0;
  205.  
  206.             if preg_match ('/^(update|insert|delete|replace)/i'trim ($sql)) ) {
  207.                 /* Insert or update, or delete query */
  208.                 $this->rownum sqlrcur_affectedRows ($this->result);
  209.                 return $this->rownum;
  210.             else if preg_match ('/create|drop/i'trim ($sql)) ) {
  211.                 $this->rownum 1;
  212.                 return $this->rownum;
  213.             }
  214.  
  215.             $this->rownum sqlrcur_rowCount ($this->result);
  216.             return $this->rownum;
  217.         catch Exception $e {
  218.             throw new myException ($e->getMessage ()$e->getCode()$e);
  219.             return false;
  220.         }
  221.     }
  222.     // }}}
  223.  
  224.     // {{{ (int) EDB::SQLRELAY::lastId (void)
  225.     /**
  226.      * 가장 마지막 입력 row ID를 반환한다.
  227.      *
  228.      * @since  2.0.4
  229.      * @access public
  230.      * @return int|false
  231.      */
  232.     function lastId ({
  233.         return sqlrcon_getLastInsertId ($this->db);
  234.     }
  235.     // }}}
  236.  
  237.     // {{{ (bool) EDB_SQLRELAY::seek ($offset)
  238.     /**
  239.      * Move the cursor in the result
  240.      *
  241.      * @access public
  242.      * @return boolean 
  243.      * @param  Number of units you want to move the cursor.
  244.      */
  245.     function seek ($offset{
  246.         $this->rowid $offset;
  247.         return 0;
  248.     }
  249.     // }}}
  250.  
  251.     // {{{ (object) EDB_SQLRELAY::fetch (void)
  252.     /**
  253.      * Fetch a result row as an associative object
  254.      *
  255.      * @access public
  256.      * @return object|falseThe object of fetched a result row or false
  257.      * @param  boolean (optional) fetch 수행 후 result를 free한다.
  258.      *                  (기본값: false) EDB >= 2.0.3
  259.      */
  260.     function fetch ($free false{
  261.         try {
  262.             $r sqlrcur_getRowAssoc ($this->result$this->rowid++);
  263.  
  264.             if $free )
  265.                 $this->free_result ();
  266.  
  267.             return $r ? (object) $r false;
  268.         catch Exception $e {
  269.             throw new myException ($e->getMessage ()$e->getCode()$e);
  270.             return false;
  271.         }
  272.     }
  273.     // }}}
  274.  
  275.     // {{{ (array) EDB_SQLRELAY::fetch_all ($free = true)
  276.     /**
  277.      * Fetch all result rows as an associative object
  278.      *
  279.      * @access public
  280.      * @return array The fetched object result rows
  281.      * @param  boolean (optional) free result set after fetch.
  282.      *                  Defaluts is true.
  283.      */
  284.     function fetch_all ($free true{
  285.         $row array ();
  286.  
  287.         $start $this->rowid;
  288.         for $i=$start$i<$this->rownum$i++ {
  289.             $row[$this->fetch ();
  290.         }
  291.  
  292.         if $free )
  293.             $this->free_result ();
  294.  
  295.         return $row;
  296.     }
  297.     // }}}
  298.  
  299.     // {{{ (bool) EDB_SQLRELAY::free_result (void)
  300.     /**
  301.      * Frees stored result memory for the given statement handle
  302.      *
  303.      * @access public
  304.      * @return boolean 
  305.      * @param  void 
  306.      */
  307.     function free_result ({
  308.         if $this->free return true;
  309.         $this->free = false;
  310.  
  311.         try {
  312.             if is_resource ($this->result) )
  313.                 return true;
  314.  
  315.             $this->rowid 0;
  316.  
  317.             // until current version (0.46)
  318.             // missing sqlrcur_closeResultSet api on sqlrelay php api.
  319.             // If you wnat to use this api, see also php-sqlrelay package
  320.             // on AnNyung LInux 2.
  321.             if function_exists ('sqlrcur_closeResultSet') )
  322.                 return sqlrcur_closeResultSet ($this->result);
  323.  
  324.             unset ($this->result);
  325.             return true;
  326.         catch Exception $e {
  327.             throw new myException ($e->getMessage ()$e->getCode()$e);
  328.             return false;
  329.         }
  330.     }
  331.     // }}}
  332.  
  333.     // {{{ (string) EDB_SQLRELAY::field_name ($index)
  334.     /**
  335.      * Return the name of the specified field index
  336.      *
  337.      * @access public
  338.      * @return string|false
  339.      * @param  integer The numerical field offset. The field_offset starts
  340.      *                  at 0. If field_offset does not exist, return false
  341.      *                  and an error of level E_WARNING is also issued.
  342.      */
  343.     function field_name ($index{
  344.         try {
  345.             if is_resource ($this->result) )
  346.                 return false;
  347.             return sqlrcur_getColumnName ($this->result$index);
  348.         catch Exception $e {
  349.             throw new myException ($e->getMessage ()$e->getCode()$e);
  350.             return false;
  351.         }
  352.     }
  353.     // }}}
  354.  
  355.     // {{{ (string) EDB_SQLRELAY::field_type ($index)
  356.     /**
  357.      * Get the type of the specified field in a result
  358.      *
  359.      * @access public
  360.      * @return string|false
  361.      * @param  integer The numerical field offset. The field_offset starts
  362.      *                  at 0. If field_offset does not exist, return false
  363.      *                  and an error of level E_WARNING is also issued.
  364.      */
  365.     function field_type ($index{
  366.         try {
  367.             if is_resource ($this->result) )
  368.                 return false;
  369.  
  370.             return sqlrcur_getColumnType ($this->result$index);
  371.         catch Exception $e {
  372.             throw new myException ($e->getMessage ()$e->getCode()$e);
  373.             return false;
  374.         }
  375.     }
  376.     // }}}
  377.  
  378.     // {{{ (int) EDB_SQLRELAY::num_fields (void)
  379.     /**
  380.      * Return the number of columns in the result set
  381.      *
  382.      * @access public
  383.      * @return integer|falsereturn -1 if SQL sentence is not SELECT.
  384.      */
  385.     function num_fields ({
  386.         try {
  387.             if is_resource ($this->result) )
  388.                 return false;
  389.             return sqlrcur_colCount ($this->result);
  390.         catch Exception $e {
  391.             throw new myException ($e->getMessage ()$e->getCode()$e);
  392.             return false;
  393.         }
  394.     }
  395.     // }}}
  396.  
  397.     // {{{ (void) EDB_SQLRELAY::trstart (void)
  398.     /**
  399.      * DB transaction 을 시작한다.
  400.      *
  401.      * @access public
  402.      * @return void 
  403.      */
  404.     function trstart ({
  405.         sqlrcon_autoCommitOff ($this->db);
  406.     }
  407.     // }}}
  408.  
  409.     // {{{ (void) EDB_SQLRELAY::trend ($v)
  410.     /**
  411.      * DB transaction 을 종료한다.
  412.      *
  413.      * @access public
  414.      * @return void 
  415.      * @param bool false일경우 rollback을 수행한다.
  416.      */
  417.     function trend ($v true{
  418.         if $v === false )
  419.             sqlrcon_rollback ($this->db);
  420.         else
  421.             sqlrcon_commit ($this->db);
  422.  
  423.         sqlrcon_autoCommitOn ($this->db);
  424.     }
  425.     // }}}
  426.  
  427.     // {{{ (void) EDB_SQLRELAY::close (void)
  428.     /**
  429.      * Close the db handle
  430.      *
  431.      * @access public
  432.      * @return void 
  433.      * @param  void 
  434.      */
  435.     function close ({
  436.         if is_resource ($this->result) ) {
  437.             sqlrcon_free ($this->result);
  438.             unset ($this->result);
  439.         }
  440.  
  441.         if is_resource ($this->db) ) {
  442.             sqlrcon_free ($this->db);
  443.             unset ($this->db);
  444.         }
  445.     }
  446.     // }}}
  447.  
  448.     /*
  449.      * Priavte functions
  450.      */
  451.     // {{{ private (int) EDB_SQLRELAY::no_bind_query ($sql)
  452.     /** 
  453.      * Performs a query on the database
  454.      *
  455.      * @access private
  456.      * @return integer The number of affected rows or false
  457.      * @param  string  The query strings
  458.      */
  459.     private function no_bind_query ($sql{
  460.         try {
  461.             if sqlrcur_sendQuery ($this->result$sql) ) {
  462.                 throw new myException (sqlrcur_errorMessage ($this->result)E_USER_WARNING);
  463.                 return false;
  464.             }
  465.             sqlrcon_endSession ($this->db);
  466.         catch Exception $e {
  467.             $this->free = false;
  468.             throw new myException ($e->getMessage ()$e->getCode()$e);
  469.             return false;
  470.         }
  471.  
  472.         $this->switch_freemark ();
  473.     }
  474.     // }}}
  475.  
  476.     // {{{ private (int) EDB_SQLRELAY::bind_query ($sql, $parameters)
  477.     /** 
  478.      * Performs a bind query on the database
  479.      *
  480.      * @access private
  481.      * @return integer The number of affected rows or false
  482.      * @param  string  The query strings
  483.      * @param  array   (optional) Bind parameter type
  484.      */
  485.     private function bind_query ($sql$params{
  486.         if $this->pno != count ($params|| $this->check_param ($params=== false {
  487.             throw new myException (
  488.                 'Number of elements in query doesn\'t match number of bind variables',
  489.                 E_USER_WARNING
  490.             );
  491.             return false;
  492.         }
  493.  
  494.         try {
  495.             sqlrcur_prepareQuery ($this->result$sql);
  496.  
  497.             for $i=1$i<$this->pno$i++ {
  498.                 switch ($params[0][$i-1]{
  499.                     case 'b' :
  500.                     case 'c' :
  501.                         // is strlen binary safe?
  502.                         if is_object ($params[$i]) ) {
  503.                             $buf $params[$i];
  504.                             unset ($params[$i]);
  505.  
  506.                             $params[$i]->data $buf;
  507.                             $params[$i]->len  strlen ($buf);
  508.                         }
  509.  
  510.                         $func $params[0][$i-1== 'b'?
  511.                                 'sqlrcur_inputBindBlob' 'sqlrcur_inputBindClob';
  512.  
  513.                         $func (
  514.                             $this->result,
  515.                             'param' $i,
  516.                             $params[$i]->data,
  517.                             $params[$i]->len
  518.                         );
  519.                         break;
  520.                     default :
  521.                         sqlrcur_inputBind ($this->result$i$params[$i]);
  522.                 }
  523.             }
  524.  
  525.             if sqlrcur_executeQuery ($this->result) ) {
  526.                 sqlrcur_clearBinds ($this->result);
  527.                 sqlrcon_endSession ($this->db);
  528.                 throw new myException (sqlrcur_errorMessage ($this->result)E_USER_WARNING);
  529.                 return false;
  530.             }
  531.  
  532.             sqlrcur_clearBinds ($this->result);
  533.             sqlrcon_endSession ($this->db);
  534.  
  535.             $this->switch_freemark ();
  536.         catch Exception $e {
  537.             throw new myException ($e->getMessage ()$e->getCode()$e);
  538.             return false;
  539.         }
  540.     }
  541.     // }}}
  542.  
  543.     function __destruct ({
  544.         try {
  545.             $this->free_result ();
  546.             $this->close ();
  547.         catch Exception $e }
  548.     }
  549. }
  550.  
  551. /*
  552.  * Local variables:
  553.  * tab-width: 4
  554.  * c-basic-offset: 4
  555.  * End:
  556.  * vim: set filetype=php noet sw=4 ts=4 fdm=marker:
  557.  * vim600: noet sw=4 ts=4 fdm=marker
  558.  * vim<600: noet sw=4 ts=4
  559.  */
  560. ?>

Documentation generated on Tue, 14 May 2019 01:59:58 +0900 by phpDocumentor 1.4.4