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

Source for file mssql.php

Documentation is available at mssql.php

  1. <?php
  2. // vim: set et ts=4 sw=4 fdm=marker:
  3. // +----------------------------------------------------------------------+
  4. // | PHP versions 4 and 5                                                 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox,                 |
  7. // | Stig. S. Bakken, Lukas Smith                                         |
  8. // | All rights reserved.                                                 |
  9. // +----------------------------------------------------------------------+
  10. // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB  |
  11. // | API as well as database abstraction for PHP applications.            |
  12. // | This LICENSE is in the BSD license style.                            |
  13. // |                                                                      |
  14. // | Redistribution and use in source and binary forms, with or without   |
  15. // | modification, are permitted provided that the following conditions   |
  16. // | are met:                                                             |
  17. // |                                                                      |
  18. // | Redistributions of source code must retain the above copyright       |
  19. // | notice, this list of conditions and the following disclaimer.        |
  20. // |                                                                      |
  21. // | Redistributions in binary form must reproduce the above copyright    |
  22. // | notice, this list of conditions and the following disclaimer in the  |
  23. // | documentation and/or other materials provided with the distribution. |
  24. // |                                                                      |
  25. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  26. // | Lukas Smith nor the names of his contributors may be used to endorse |
  27. // | or promote products derived from this software without specific prior|
  28. // | written permission.                                                  |
  29. // |                                                                      |
  30. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  31. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  32. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  33. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  34. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  35. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  36. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  37. // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  38. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  39. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  40. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  41. // | POSSIBILITY OF SUCH DAMAGE.                                          |
  42. // +----------------------------------------------------------------------+
  43. // | Authors: Lukas Smith <smith@pooteeweet.org>                          |
  44. // |          Daniel Convissor <danielc@php.net>                          |
  45. // +----------------------------------------------------------------------+
  46. //
  47. // $Id: mssql.php 327310 2012-08-27 15:16:18Z danielc $
  48. //
  49.  
  50. require_once 'MDB2/Driver/Datatype/Common.php';
  51.  
  52. /**
  53.  * MDB2 MS SQL driver
  54.  *
  55.  * @package MDB2
  56.  * @category Database
  57.  * @author  Lukas Smith <smith@pooteeweet.org>
  58.  */
  59. class MDB2_Driver_Datatype_mssql extends MDB2_Driver_Datatype_Common
  60. {
  61.     // {{{ _baseConvertResult()
  62.  
  63.     /**
  64.      * general type conversion method
  65.      *
  66.      * @param mixed   $value refernce to a value to be converted
  67.      * @param string  $type  specifies which type to convert to
  68.      * @param boolean $rtrim [optional] when TRUE [default], apply rtrim() to text
  69.      * @return object MDB2 error on failure
  70.      * @access protected
  71.      */
  72.     function _baseConvertResult($value$type$rtrim = true)
  73.     {
  74.         if (null === $value{
  75.             return null;
  76.         }
  77.         switch ($type{
  78.         case 'boolean':
  79.             return ($value === 0)? false : !empty($value);
  80.         case 'date':
  81.             if (strlen($value> 10{
  82.                 $value substr($value,0,10);
  83.             }
  84.             return $value;
  85.         case 'time':
  86.             if (strlen($value> 8{
  87.                 $value substr($value,11,8);
  88.             }
  89.             return $value;
  90.         }
  91.         return parent::_baseConvertResult($value$type$rtrim);
  92.     }
  93.  
  94.     // }}}
  95.     // {{{ _getCollationFieldDeclaration()
  96.  
  97.     /**
  98.      * Obtain DBMS specific SQL code portion needed to set the COLLATION
  99.      * of a field declaration to be used in statements like CREATE TABLE.
  100.      *
  101.      * @param string $collation name of the collation
  102.      *
  103.      * @return string DBMS specific SQL code portion needed to set the COLLATION
  104.      *                 of a field declaration.
  105.      */
  106.     function _getCollationFieldDeclaration($collation)
  107.     {
  108.         return 'COLLATE '.$collation;
  109.     }
  110.  
  111.     // }}}
  112.     // {{{ getTypeDeclaration()
  113.  
  114.     /**
  115.      * Obtain DBMS specific SQL code portion needed to declare an text type
  116.      * field to be used in statements like CREATE TABLE.
  117.      *
  118.      * @param array $field  associative array with the name of the properties
  119.      *       of the field being declared as array indexes. Currently, the types
  120.      *       of supported field properties are as follows:
  121.      *
  122.      *       length
  123.      *           Integer value that determines the maximum length of the text
  124.      *           field. If this argument is missing the field should be
  125.      *           declared to have the longest length allowed by the DBMS.
  126.      *
  127.      *       default
  128.      *           Text value to be used as default for this field.
  129.      *
  130.      *       notnull
  131.      *           Boolean flag that indicates whether this field is constrained
  132.      *           to not be set to null.
  133.      * @return string  DBMS specific SQL code portion that should be used to
  134.      *       declare the specified field.
  135.      * @access public
  136.      */
  137.     function getTypeDeclaration($field)
  138.     {
  139.         $db $this->getDBInstance();
  140.         if (MDB2::isError($db)) {
  141.             return $db;
  142.         }
  143.  
  144.         switch ($field['type']{
  145.         case 'text':
  146.             $length !empty($field['length'])
  147.                 ? $field['length': false;
  148.             $fixed !empty($field['fixed']$field['fixed': false;
  149.             return $fixed ($length 'CHAR('.$length.')' 'CHAR('.$db->options['default_text_field_length'].')')
  150.                 : ($length 'VARCHAR('.$length.')' 'TEXT');
  151.         case 'clob':
  152.             if (!empty($field['length'])) {
  153.                 $length $field['length'];
  154.                 if ($length <= 8000{
  155.                     return 'VARCHAR('.$length.')';
  156.                 }
  157.              }
  158.              return 'TEXT';
  159.         case 'blob':
  160.             if (!empty($field['length'])) {
  161.                 $length $field['length'];
  162.                 if ($length <= 8000{
  163.                     return "VARBINARY($length)";
  164.                 }
  165.             }
  166.             return 'IMAGE';
  167.         case 'integer':
  168.             return 'INT';
  169.         case 'boolean':
  170.             return 'BIT';
  171.         case 'date':
  172.             return 'CHAR ('.strlen('YYYY-MM-DD').')';
  173.         case 'time':
  174.             return 'CHAR ('.strlen('HH:MM:SS').')';
  175.         case 'timestamp':
  176.             return 'CHAR ('.strlen('YYYY-MM-DD HH:MM:SS').')';
  177.         case 'float':
  178.             return 'FLOAT';
  179.         case 'decimal':
  180.             $length !empty($field['length']$field['length': 18;
  181.             $scale !empty($field['scale']$field['scale'$db->options['decimal_places'];
  182.             return 'DECIMAL('.$length.','.$scale.')';
  183.         }
  184.         return '';
  185.     }
  186.  
  187.     // }}}
  188.     // {{{ _getIntegerDeclaration()
  189.  
  190.     /**
  191.      * Obtain DBMS specific SQL code portion needed to declare an integer type
  192.      * field to be used in statements like CREATE TABLE.
  193.      *
  194.      * @param string  $name   name the field to be declared.
  195.      * @param string  $field  associative array with the name of the properties
  196.      *                         of the field being declared as array indexes.
  197.      *                         Currently, the types of supported field
  198.      *                         properties are as follows:
  199.      *
  200.      *                        unsigned
  201.      *                         Boolean flag that indicates whether the field
  202.      *                         should be declared as unsigned integer if
  203.      *                         possible.
  204.      *
  205.      *                        default
  206.      *                         Integer value to be used as default for this
  207.      *                         field.
  208.      *
  209.      *                        notnull
  210.      *                         Boolean flag that indicates whether this field is
  211.      *                         constrained to not be set to null.
  212.      * @return string  DBMS specific SQL code portion that should be used to
  213.      *                  declare the specified field.
  214.      * @access protected
  215.      */
  216.     function _getIntegerDeclaration($name$field)
  217.     {
  218.         $db $this->getDBInstance();
  219.         if (MDB2::isError($db)) {
  220.             return $db;
  221.         }
  222.  
  223.         $notnull = empty($field['notnull']' NULL' ' NOT NULL';
  224.         $default $autoinc '';
  225.         if (!empty($field['autoincrement'])) {
  226.             $autoinc ' IDENTITY PRIMARY KEY';
  227.         elseif (array_key_exists('default'$field)) {
  228.             if ($field['default'=== ''{
  229.                 $field['default'= 0;
  230.             }
  231.             if (null === $field['default']{
  232.                 $default ' DEFAULT (null)';
  233.             else {
  234.                 $default ' DEFAULT (' $this->quote($field['default']'integer'')';
  235.             }
  236.         }
  237.  
  238.         if (!empty($field['unsigned'])) {
  239.             $db->warnings[= "unsigned integer field \"$name\" is being declared as signed integer";
  240.         }
  241.  
  242.         $name $db->quoteIdentifier($nametrue);
  243.         return $name.' '.$this->getTypeDeclaration($field).$notnull.$default.$autoinc;
  244.     }
  245.  
  246.     // }}}
  247.     // {{{ _getCLOBDeclaration()
  248.  
  249.     /**
  250.      * Obtain DBMS specific SQL code portion needed to declare an character
  251.      * large object type field to be used in statements like CREATE TABLE.
  252.      *
  253.      * @param string $name name the field to be declared.
  254.      * @param array $field associative array with the name of the properties
  255.      *         of the field being declared as array indexes. Currently, the types
  256.      *         of supported field properties are as follows:
  257.      *
  258.      *         length
  259.      *             Integer value that determines the maximum length of the large
  260.      *             object field. If this argument is missing the field should be
  261.      *             declared to have the longest length allowed by the DBMS.
  262.      *
  263.      *         notnull
  264.      *             Boolean flag that indicates whether this field is constrained
  265.      *             to not be set to null.
  266.      * @return string DBMS specific SQL code portion that should be used to
  267.      *         declare the specified field.
  268.      * @access public
  269.      */
  270.     function _getCLOBDeclaration($name$field)
  271.     {
  272.         $db $this->getDBInstance();
  273.         if (MDB2::isError($db)) {
  274.             return $db;
  275.         }
  276.  
  277.         $notnull = empty($field['notnull']' NULL' ' NOT NULL';
  278.         $name $db->quoteIdentifier($nametrue);
  279.         return $name.' '.$this->getTypeDeclaration($field).$notnull;
  280.     }
  281.  
  282.     // }}}
  283.     // {{{ _getBLOBDeclaration()
  284.  
  285.     /**
  286.      * Obtain DBMS specific SQL code portion needed to declare an binary large
  287.      * object type field to be used in statements like CREATE TABLE.
  288.      *
  289.      * @param string $name name the field to be declared.
  290.      * @param array $field associative array with the name of the properties
  291.      *         of the field being declared as array indexes. Currently, the types
  292.      *         of supported field properties are as follows:
  293.      *
  294.      *         length
  295.      *             Integer value that determines the maximum length of the large
  296.      *             object field. If this argument is missing the field should be
  297.      *             declared to have the longest length allowed by the DBMS.
  298.      *
  299.      *         notnull
  300.      *             Boolean flag that indicates whether this field is constrained
  301.      *             to not be set to null.
  302.      * @return string DBMS specific SQL code portion that should be used to
  303.      *         declare the specified field.
  304.      * @access protected
  305.      */
  306.     function _getBLOBDeclaration($name$field)
  307.     {
  308.         $db $this->getDBInstance();
  309.         if (MDB2::isError($db)) {
  310.             return $db;
  311.         }
  312.  
  313.         $notnull = empty($field['notnull']' NULL' ' NOT NULL';
  314.         $name $db->quoteIdentifier($nametrue);
  315.         return $name.' '.$this->getTypeDeclaration($field).$notnull;
  316.     }
  317.  
  318.     // }}}
  319.     // {{{ _quoteBLOB()
  320.  
  321.     /**
  322.      * Convert a text value into a DBMS specific format that is suitable to
  323.      * compose query statements.
  324.      *
  325.      * @param string $value text string value that is intended to be converted.
  326.      * @param bool $quote determines if the value should be quoted and escaped
  327.      * @param bool $escape_wildcards if to escape escape wildcards
  328.      * @return string  text string that represents the given argument value in
  329.      *                  a DBMS specific format.
  330.      * @access protected
  331.      */
  332.     function _quoteBLOB($value$quote$escape_wildcards)
  333.     {
  334.         if (!$quote{
  335.             return $value;
  336.         }
  337.         $value '0x'.bin2hex($this->_readFile($value));
  338.         return $value;
  339.     }
  340.  
  341.     // }}}
  342.     // {{{ matchPattern()
  343.  
  344.     /**
  345.      * build a pattern matching string
  346.      *
  347.      * @access public
  348.      *
  349.      * @param array $pattern even keys are strings, odd are patterns (% and _)
  350.      * @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
  351.      * @param string $field optional field name that is being matched against
  352.      *                   (might be required when emulating ILIKE)
  353.      *
  354.      * @return string SQL pattern
  355.      */
  356.     function matchPattern($pattern$operator = null$field = null)
  357.     {
  358.         $db $this->getDBInstance();
  359.         if (MDB2::isError($db)) {
  360.             return $db;
  361.         }
  362.  
  363.         $match '';
  364.         if (null !== $operator{
  365.             $field (null === $field'' $field.' ';
  366.             $operator strtoupper($operator);
  367.             switch ($operator{
  368.             // case insensitive
  369.             case 'ILIKE':
  370.                 $match $field.'LIKE ';
  371.                 break;
  372.             case 'NOT ILIKE':
  373.                 $match $field.'NOT LIKE ';
  374.                 break;
  375.             // case sensitive
  376.             case 'LIKE':
  377.                 $match $field.'LIKE ';
  378.                 break;
  379.             case 'NOT LIKE':
  380.                 $match $field.'NOT LIKE ';
  381.                 break;
  382.             default:
  383.                 return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  384.                     'not a supported operator type:'$operator__FUNCTION__);
  385.             }
  386.         }
  387.         $match.= "'";
  388.         foreach ($pattern as $key => $value{
  389.             if ($key % 2{
  390.                 $match.= $value;
  391.             else {
  392.                 $match.= $db->escapePattern($db->escape($value));
  393.             }
  394.         }
  395.         $match.= "'";
  396.         $match.= $this->patternEscapeString();
  397.         return $match;
  398.     }
  399.  
  400.     // }}}
  401.     // {{{ _mapNativeDatatype()
  402.  
  403.     /**
  404.      * Maps a native array description of a field to a MDB2 datatype and length
  405.      *
  406.      * @param array  $field native field description
  407.      * @return array containing the various possible types, length, sign, fixed
  408.      * @access public
  409.      */
  410.     function _mapNativeDatatype($field)
  411.     {
  412.         // todo: handle length of various int variations
  413.         $db_type preg_replace('/\d/'''strtolower($field['type']));
  414.         $length $field['length'];
  415.         $type = array();
  416.         // todo: unsigned handling seems to be missing
  417.         $unsigned $fixed = null;
  418.         switch ($db_type{
  419.         case 'bit':
  420.             $type[0'boolean';
  421.             break;
  422.         case 'tinyint':
  423.             $type[0'integer';
  424.             $length = 1;
  425.             break;
  426.         case 'smallint':
  427.             $type[0'integer';
  428.             $length = 2;
  429.             break;
  430.         case 'int':
  431.             $type[0'integer';
  432.             $length = 4;
  433.             break;
  434.         case 'bigint':
  435.             $type[0'integer';
  436.             $length = 8;
  437.             break;
  438.         case 'smalldatetime':
  439.         case 'datetime':
  440.             $type[0'timestamp';
  441.             break;
  442.         case 'float':
  443.         case 'real':
  444.         case 'numeric':
  445.             $type[0'float';
  446.             break;
  447.         case 'decimal':
  448.         case 'money':
  449.             $type[0'decimal';
  450.             $length $field['numeric_precision'].','.$field['numeric_scale'];
  451.             break;
  452.         case 'text':
  453.         case 'ntext':
  454.         case 'varchar':
  455.         case 'nvarchar':
  456.             $fixed = false;
  457.         case 'char':
  458.         case 'nchar':
  459.             $type[0'text';
  460.             if ($length == '1'{
  461.                 $type['boolean';
  462.                 if (preg_match('/^(is|has)/'$field['name'])) {
  463.                     $type array_reverse($type);
  464.                 }
  465.             elseif (strstr($db_type'text')) {
  466.                 $type['clob';
  467.                 $type array_reverse($type);
  468.             }
  469.             if ($fixed !== false{
  470.                 $fixed = true;
  471.             }
  472.             break;
  473.         case 'image':
  474.         case 'varbinary':
  475.         case 'timestamp':
  476.             $type['blob';
  477.             $length = null;
  478.             break;
  479.         default:
  480.             $db $this->getDBInstance();
  481.             if (MDB2::isError($db)) {
  482.                 return $db;
  483.             }
  484.             return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  485.                 'unknown database attribute type: '.$db_type__FUNCTION__);
  486.         }
  487.  
  488.         if ((int)$length <= 0{
  489.             $length = null;
  490.         }
  491.  
  492.         return array($type$length$unsigned$fixed);
  493.     }
  494.     // }}}
  495. }
  496.  
  497. ?>

Documentation generated on Mon, 11 Mar 2019 15:51:10 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.