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

Source for file EDB_MSSQL.php

Documentation is available at EDB_MSSQL.php

  1. <?php
  2. /**
  3.  * Project: EDB_MSSQL :: MSSQL abstraction layer
  4.  * File:    EDB/EDB_MSSQL.php
  5.  *
  6.  * The EDB_MSSQL class is MSSQL 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.  * MSSQL engine for EDB API
  22.  *
  23.  * This class support abstracttion DB layer for MSSQL Engine
  24.  *
  25.  * @package     EDB
  26.  */
  27. Class EDB_MSSQL extends EDB_Common {
  28.     // {{{ properties
  29.     /**#@+
  30.      * @access private
  31.      */
  32.     /**
  33.      * db handler of EDB_MSSQL 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.     // }}}
  44.  
  45.     // {{{ (object) EDB_MSSQL::__construct ($host, $user, $pass, $db)
  46.     /** 
  47.      * Instantiates an EDB_MSSQL object and opens an MSSQL database
  48.      *
  49.      * For examples:
  50.      * <code>
  51.      * $db = new EDB_MSSQL ('mssql://localhost', 'user', 'host', 'database');
  52.      * $db = new EDB_MSSQL ('mssql://localhost:33000', 'user', 'host', 'database');
  53.      * $db = new EDB_MSSQL ('mssql://localhost:33000?autocommit=false', 'user', 'host', 'database');
  54.      * </code>
  55.      *
  56.      * If you add prefix 'p~' before host, you can connect with persistent
  57.      * connection.
  58.      *
  59.      * For Examples:
  60.      * <code>
  61.      * $db = new EDB_MSSQL ('mssql://p~localhost', 'user', 'host', 'database');
  62.      * </code>
  63.      *
  64.      * @access public
  65.      * @return EDB_MSSQL 
  66.      * @param  string  $hostname MSSQL host
  67.      * @param  string  $user     MSSQL user
  68.      * @param  string  $password MSSQL password
  69.      * @param  string  $database MSSQL database
  70.      */
  71.     function __construct ({
  72.         $_argv func_get_args ();
  73.         $argv is_array ($_argv[0]$_argv[0$_argv;;
  74.  
  75.         $iniset function_exists ('___ini_set''___ini_set' 'ini_set';
  76.         $iniset ('magic_quotes_sybase''Off');
  77.  
  78.         if extension_loaded ('mssql') )
  79.             throw new myException ('MSSQL extension is not loaded on PHP!'E_USER_ERROR);
  80.  
  81.         $o = (object) array (
  82.             'host' => preg_replace ('!^mssql://!'''$argv[0]),
  83.             'user' => $argv[1],
  84.             'pass' => $argv[2],
  85.             'db'   => $argv[3]
  86.         );
  87.  
  88.         if preg_match ('/^p~/'$o->host) ) {
  89.             $func 'mssql_pconnect';
  90.             $o->host preg_replace ('/^p~/'''$o->host);
  91.         else
  92.             $func 'mssql_connect';
  93.  
  94.         try {
  95.             $this->db $func ($o->host$o->user$o->pass);
  96.             mssql_select_db ($o->db$this->db);
  97.         catch Exception $e {
  98.             throw new myException ($e->getMessage ()$e->getCode()$e);
  99.         }
  100.     }
  101.     // }}}
  102.  
  103.     // {{{ (string) EDB_MSSQL::get_charset (void)
  104.     /** 
  105.      * Get character set of current database
  106.      *
  107.      * MSSQL extension don't support this function
  108.      *
  109.      * @access public
  110.      * @return string Current character set name on DB
  111.      */
  112.     function get_charset ({
  113.         return 'Unsupport';
  114.     }
  115.     // }}}
  116.  
  117.     // {{{ (bool) EDB_MSSQL::set_charset ($charset)
  118.     /** 
  119.      * Set character set of current database
  120.      *
  121.      * This method is always returned true because MSSQL don't support
  122.      * charset settings.
  123.      *
  124.      * @access public
  125.      * @return bool    always return true
  126.      * @param  string  name of character set that supported from database
  127.      */
  128.     function set_charset ($char{
  129.         return true;
  130.     }
  131.     // }}}
  132.  
  133.     // {{{ (string) EDB_MSSQL::escape ($string)
  134.     /** 
  135.      * Escape special characters in a string for use in an SQL statement
  136.      *
  137.      * @access public
  138.      * @return string 
  139.      * @param  string  The string that is to be escaped.
  140.      */
  141.     function escape ($string{
  142.         return preg_replace ('/[\']/''\'\''$string);
  143.     }
  144.     // }}}
  145.  
  146.     // {{{ (int) EDB_MSSQL::query ($query, $param_type, $param1, $param2 ...)
  147.     /** 
  148.      * Performs a query on the database
  149.      *
  150.      * @access public
  151.      * @return integer The number of affected rows or false
  152.      * @param  string  $query The query strings
  153.      * @param  string  $type  (optional) Bind parameter type. See also
  154.      *  <code>
  155.      *  i => integer
  156.      *  d => double
  157.      *  s => string
  158.      *  b => blob
  159.      *  c => clob
  160.      *  n => null
  161.      *  </code>
  162.      * @param  mixed   $param1 (optional) Bind parameter 1
  163.      * @param  mixed   $param2,... (optional) Bind parameter 2 ..
  164.      */
  165.     function query ({
  166.         $_argv func_get_args ();
  167.         $argv is_array ($_argv[0]$_argv[0$_argv;;
  168.  
  169.         $this->error null;
  170.  
  171.         $sql array_shift ($argv);
  172.         $this->pno count ($argv$this->get_param_number ($sql0;
  173.  
  174.         if $this->free )
  175.             $this->free_result ();
  176.  
  177.         // store query in log variable
  178.         $this->queryLog[$sql;
  179.  
  180.         if $this->pno++ == // no bind query
  181.             $this->no_bind_query ($sql);
  182.         else // bind query
  183.             $this->bind_query ($sql$argv);
  184.  
  185.         if preg_match ('/^(update|insert|delete|replace)/i'trim ($sql)) ) {
  186.             /* Insert or update, or delete query */
  187.             return mssql_rows_affected ($this->db);
  188.         else if preg_match ('/create|drop/i'trim ($sql)) ) {
  189.             return 1;
  190.         }
  191.  
  192.         return mssql_num_rows ($this->result);
  193.     }
  194.     // }}}
  195.  
  196.     // {{{ (string) EDB_MSSQL::lastId (void)
  197.     /**
  198.      * 가장 마지막 입력 row의 OID를 반환한다.
  199.      *
  200.      * @since  2.0.4
  201.      * @access public
  202.      * @return string|false
  203.      */
  204.     function lastId ({
  205.         $id 0;
  206.         if ( ($r @mssql_query ('SELECT @@identity AS id')) === false )
  207.             return 0;
  208.  
  209.         if $row mssql_fetch_object ($r) )
  210.             $id $row->id;
  211.  
  212.         return $id;
  213.     }
  214.     // }}}
  215.  
  216.     // {{{ (bool) EDB_MSSQL::seek ($offset)
  217.     /**
  218.      * Move the cursor in the result
  219.      *
  220.      * @access public
  221.      * @return boolean 
  222.      * @param  Number of units you want to move the cursor.
  223.      */
  224.     function seek ($offset{
  225.         if is_resource ($this->result) )
  226.             return false;
  227.  
  228.         try {
  229.             return mssql_data_seek ($this->result$offset);
  230.         catch Exception $e {
  231.             throw new myException ($e->getMessage ()$e->getCode()$e);
  232.             return false;
  233.         }
  234.     }
  235.     // }}}
  236.  
  237.     // {{{ (object) EDB_MSSQL::fetch (void)
  238.     /**
  239.      * Fetch a result row as an associative object
  240.      *
  241.      * @access public
  242.      * @return object|falseThe object of fetched a result row or false
  243.      * @param  boolean (optional) 수행 후 result를 free 한다. 기본값: false
  244.      *                  EDB >= 2.0.3
  245.      */
  246.     function fetch ($free false{
  247.         try {
  248.             $r mssql_fetch_object ($this->result);
  249.             if $free )
  250.                 $this->free_result ();
  251.             return $r;
  252.         catch Exception $e {
  253.             throw new myException ($e->getMessage ()$e->getCode()$e);
  254.             return false;
  255.         }
  256.     }
  257.     // }}}
  258.  
  259.     // {{{ (array) EDB_MSSQL::fetch_all ($free = true)
  260.     /**
  261.      * Fetch all result rows as an associative object
  262.      *
  263.      * @access public
  264.      * @return array The fetched object result rows
  265.      * @param  boolean (optional) free result set after fetch.
  266.      *                  Defaluts is true.
  267.      */
  268.     function fetch_all ($free true{
  269.         $row array ();
  270.  
  271.         while ( ($r $this->fetch ()) !== false )
  272.             $row[$r;
  273.  
  274.         if $free )
  275.             $this->free_result ();
  276.  
  277.         return $row;
  278.     }
  279.     // }}}
  280.  
  281.     // {{{ (bool) EDB_MSSQL::free_result (void)
  282.     /**
  283.      * Frees stored result memory for the given statement handle
  284.      *
  285.      * @access public
  286.      * @return boolean 
  287.      * @param  void 
  288.      */
  289.     function free_result ({
  290.         if $this->free return true;
  291.         $this->free = false;
  292.  
  293.         try {
  294.             if is_resource ($this->result) )
  295.                 return true;
  296.  
  297.             return mssql_free_result ($this->result);
  298.         catch Exception $e {
  299.             throw new myException ($e->getMessage ()$e->getCode()$e);
  300.             return false;
  301.         }
  302.     }
  303.     // }}}
  304.  
  305.     // {{{ (string) EDB_MSSQL::field_name ($index)
  306.     /**
  307.      * Return the name of the specified field index
  308.      *
  309.      * @access public
  310.      * @return string|false
  311.      * @param  integer The numerical field offset. The field_offset starts
  312.      *                  at 0. If field_offset does not exist, return false
  313.      *                  and an error of level E_WARNING is also issued.
  314.      */
  315.     function field_name ($index{
  316.         try {
  317.             if is_resource ($this->result) )
  318.                 return false;
  319.             return mssql_field_name ($this->result$index);
  320.         catch Exception $e {
  321.             throw new myException ($e->getMessage ()$e->getCode()$e);
  322.             return false;
  323.         }
  324.     }
  325.     // }}}
  326.  
  327.     // {{{ (string) EDB_MSSQL::field_type ($index)
  328.     /**
  329.      * Get the type of the specified field in a result
  330.      *
  331.      * @access public
  332.      * @return string|false
  333.      * @param  integer The numerical field offset. The field_offset starts
  334.      *                  at 0. If field_offset does not exist, return false
  335.      *                  and an error of level E_WARNING is also issued.
  336.      */
  337.     function field_type ($index{
  338.         try {
  339.             if is_resource ($this->result) )
  340.                 return false;
  341.  
  342.             return mssql_field_type ($this->result$index);
  343.         catch Exception $e {
  344.             throw new myException ($e->getMessage ()$e->getCode()$e);
  345.             return false;
  346.         }
  347.     }
  348.     // }}}
  349.  
  350.     // {{{ (int) EDB_MSSQL::num_fields (void)
  351.     /**
  352.      * Return the number of columns in the result set
  353.      *
  354.      * @access public
  355.      * @return integer|falsereturn -1 if SQL sentence is not SELECT.
  356.      */
  357.     function num_fields ({
  358.         try {
  359.             if is_resource ($this->result) )
  360.                 return false;
  361.             return mssql_num_fields ($this->result);
  362.         catch Exception $e {
  363.             throw new myException ($e->getMessage ()$e->getCode()$e);
  364.             return false;
  365.         }
  366.     }
  367.     // }}}
  368.  
  369.     // {{{ (void) EDB_MSSQL::trstart (void)
  370.     /**
  371.      * DB transaction 을 시작한다.
  372.      *
  373.      * @access public
  374.      * @return void 
  375.      */
  376.     function trstart ({
  377.         $this->db->query ('BEGIN TRANSACTION');
  378.     }
  379.     // }}}
  380.  
  381.     // {{{ (void) EDB_MSSQL::trend ($v)
  382.     /**
  383.      * DB transaction 을 종료한다.
  384.      *
  385.      * @access public
  386.      * @return void 
  387.      * @param bool false일경우 rollback을 수행한다.
  388.      */
  389.     function trend ($v true{
  390.         $sql ($v === false'ROLLBACK' 'COMMIT';
  391.         $this->db->query ($sql ' TRANSACTION');
  392.     }
  393.     // }}}
  394.  
  395.     // {{{ (void) EDB_MSSQL::close (void)
  396.     /**
  397.      * Close the db handle
  398.      *
  399.      * @access public
  400.      * @return void 
  401.      * @param  void 
  402.      */
  403.     function close ({
  404.         if is_resource ($this->db) ) {
  405.             mssql_close ($this->db);
  406.             unset ($this->db);
  407.         }
  408.     }
  409.     // }}}
  410.  
  411.     /*
  412.      * Priavte functions
  413.      */
  414.     // {{{ private (int) EDB_MSSQL::no_bind_query ($sql)
  415.     /** 
  416.      * Performs a query on the database
  417.      *
  418.      * @access private
  419.      * @return integer The number of affected rows or false
  420.      * @param  string  The query strings
  421.      */
  422.     private function no_bind_query ($sql{
  423.         try {
  424.             if ( ($this->result = mssql_query ($sql$this->db)) === false {
  425.                 $this->free = false;
  426.                 throw new myException (mssql_get_last_message ()E_USER_WARNING);
  427.                 return false;
  428.             }
  429.         catch Exception $e {
  430.             $this->free = false;
  431.             throw new myException ($e->getMessage ()$e->getCode()$e);
  432.             return false;
  433.         }
  434.  
  435.         $this->switch_freemark ();
  436.     }
  437.     // }}}
  438.  
  439.     // {{{ private (int) EDB_MSSQL::bind_query ($sql, $parameters)
  440.     /** 
  441.      * Performs a bind query on the database
  442.      *
  443.      * mssql_bind api is supported stored procedure, so EDB
  444.      * package is supported by self bind method of EDB
  445.      *
  446.      * @access private
  447.      * @return integer The number of affected rows or false
  448.      * @param  string  The query strings
  449.      * @param  array   (optional) Bind parameter type
  450.      */
  451.     private function bind_query ($sql$params{
  452.         if $this->pno != count ($params|| $this->check_param ($params=== false {
  453.             throw new myException (
  454.                 'Number of elements in query doesn\'t match number of bind variables',
  455.                 E_USER_WARNING
  456.             );
  457.             return false;
  458.         }
  459.  
  460.         $parano strlen ($params[0]);
  461.         for $i=0$j=1$i<$parano$i++$j++ {
  462.             switch ($params[0][$i]{
  463.                 case 'b' :
  464.                     if is_object ($params[$j]) )
  465.                         $params[$j$params[$j]->data;
  466.                     $params[$j'unquote:' $this->escape_bin ($params[$j]);
  467.                     break;
  468.                 case 'c' :
  469.                     $params[0][$i's';
  470.                     break;
  471.             }
  472.         }
  473.  
  474.         $query $this->bind_param ($sql$params);
  475.         return $this->no_bind_query ($query);
  476.     }
  477.     // }}}
  478.  
  479.     // {{{ priavet (string) EDB_MSSQL::binary_escape ($string)
  480.     /** 
  481.      * Escape special characters in a string for use in an SQL statement
  482.      *
  483.      * @access public
  484.      * @return string 
  485.      * @param  string  The string that is to be escaped.
  486.      */
  487.     private function escape_bin ($bin{
  488.         return '0x' bin2hex ($bin);
  489.     }
  490.     // }}}
  491.  
  492.     function __destruct ({
  493.         try {
  494.             $this->free_result ();
  495.             $this->close ();
  496.         catch Exception $e }
  497.     }
  498. }
  499.  
  500. /*
  501.  * Local variables:
  502.  * tab-width: 4
  503.  * c-basic-offset: 4
  504.  * End:
  505.  * vim: set filetype=php noet sw=4 ts=4 fdm=marker:
  506.  * vim600: noet sw=4 ts=4 fdm=marker
  507.  * vim<600: noet sw=4 ts=4
  508.  */
  509. ?>

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