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

Source for file sqlite.php

Documentation is available at sqlite.php

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP versions 4 and 5                                                 |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox,                 |
  6. // | Stig. S. Bakken, Lukas Smith                                         |
  7. // | All rights reserved.                                                 |
  8. // +----------------------------------------------------------------------+
  9. // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB  |
  10. // | API as well as database abstraction for PHP applications.            |
  11. // | This LICENSE is in the BSD license style.                            |
  12. // |                                                                      |
  13. // | Redistribution and use in source and binary forms, with or without   |
  14. // | modification, are permitted provided that the following conditions   |
  15. // | are met:                                                             |
  16. // |                                                                      |
  17. // | Redistributions of source code must retain the above copyright       |
  18. // | notice, this list of conditions and the following disclaimer.        |
  19. // |                                                                      |
  20. // | Redistributions in binary form must reproduce the above copyright    |
  21. // | notice, this list of conditions and the following disclaimer in the  |
  22. // | documentation and/or other materials provided with the distribution. |
  23. // |                                                                      |
  24. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  25. // | Lukas Smith nor the names of his contributors may be used to endorse |
  26. // | or promote products derived from this software without specific prior|
  27. // | written permission.                                                  |
  28. // |                                                                      |
  29. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  30. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  31. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  32. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  33. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  34. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  35. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  36. // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  37. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  38. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  39. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  40. // | POSSIBILITY OF SUCH DAMAGE.                                          |
  41. // +----------------------------------------------------------------------+
  42. // | Author: Lukas Smith <smith@pooteeweet.org>                           |
  43. // +----------------------------------------------------------------------+
  44. //
  45. // $Id: sqlite.php,v 1.58 2006/08/21 16:39:37 lsmith Exp $
  46. //
  47.  
  48. require_once 'MDB2/Driver/Manager/Common.php';
  49.  
  50. /**
  51.  * MDB2 SQLite driver for the management modules
  52.  *
  53.  * @package MDB2
  54.  * @category Database
  55.  * @author  Lukas Smith <smith@pooteeweet.org>
  56.  */
  57. class MDB2_Driver_Manager_sqlite extends MDB2_Driver_Manager_Common
  58. {
  59.     // {{{ createDatabase()
  60.  
  61.     /**
  62.      * create a new database
  63.      *
  64.      * @param string $name name of the database that should be created
  65.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  66.      * @access public
  67.      */
  68.     function createDatabase($name)
  69.     {
  70.         $db =$this->getDBInstance();
  71.         if (PEAR::isError($db)) {
  72.             return $db;
  73.         }
  74.  
  75.         $database_file $db->_getDatabaseFile($name);
  76.         if (file_exists($database_file)) {
  77.             return $db->raiseError(MDB2_ERROR_ALREADY_EXISTSnullnull,
  78.                 'database already exists'__FUNCTION__);
  79.         }
  80.         $php_errormsg '';
  81.         $handle @sqlite_open($database_file$db->dsn['mode']$php_errormsg);
  82.         if (!$handle{
  83.             return $db->raiseError(MDB2_ERROR_CANNOT_CREATEnullnull,
  84.                 (isset($php_errormsg$php_errormsg 'could not create the database file')__FUNCTION__);
  85.         }
  86.         @sqlite_close($handle);
  87.         return MDB2_OK;
  88.     }
  89.  
  90.     // }}}
  91.     // {{{ dropDatabase()
  92.  
  93.     /**
  94.      * drop an existing database
  95.      *
  96.      * @param string $name name of the database that should be dropped
  97.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  98.      * @access public
  99.      */
  100.     function dropDatabase($name)
  101.     {
  102.         $db =$this->getDBInstance();
  103.         if (PEAR::isError($db)) {
  104.             return $db;
  105.         }
  106.  
  107.         $database_file $db->_getDatabaseFile($name);
  108.         if (!@file_exists($database_file)) {
  109.             return $db->raiseError(MDB2_ERROR_CANNOT_DROPnullnull,
  110.                 'database does not exist'__FUNCTION__);
  111.         }
  112.         $result @unlink($database_file);
  113.         if (!$result{
  114.             return $db->raiseError(MDB2_ERROR_CANNOT_DROPnullnull,
  115.                 (isset($php_errormsg$php_errormsg 'could not remove the database file')__FUNCTION__);
  116.         }
  117.         return MDB2_OK;
  118.     }
  119.  
  120.     // }}}
  121.     // {{{ alterTable()
  122.  
  123.     /**
  124.      * alter an existing table
  125.      *
  126.      * @param string $name         name of the table that is intended to be changed.
  127.      * @param array $changes     associative array that contains the details of each type
  128.      *                              of change that is intended to be performed. The types of
  129.      *                              changes that are currently supported are defined as follows:
  130.      *
  131.      *                              name
  132.      *
  133.      *                                 New name for the table.
  134.      *
  135.      *                             add
  136.      *
  137.      *                                 Associative array with the names of fields to be added as
  138.      *                                  indexes of the array. The value of each entry of the array
  139.      *                                  should be set to another associative array with the properties
  140.      *                                  of the fields to be added. The properties of the fields should
  141.      *                                  be the same as defined by the Metabase parser.
  142.      *
  143.      *
  144.      *                             remove
  145.      *
  146.      *                                 Associative array with the names of fields to be removed as indexes
  147.      *                                  of the array. Currently the values assigned to each entry are ignored.
  148.      *                                  An empty array should be used for future compatibility.
  149.      *
  150.      *                             rename
  151.      *
  152.      *                                 Associative array with the names of fields to be renamed as indexes
  153.      *                                  of the array. The value of each entry of the array should be set to
  154.      *                                  another associative array with the entry named name with the new
  155.      *                                  field name and the entry named Declaration that is expected to contain
  156.      *                                  the portion of the field declaration already in DBMS specific SQL code
  157.      *                                  as it is used in the CREATE TABLE statement.
  158.      *
  159.      *                             change
  160.      *
  161.      *                                 Associative array with the names of the fields to be changed as indexes
  162.      *                                  of the array. Keep in mind that if it is intended to change either the
  163.      *                                  name of a field and any other properties, the change array entries
  164.      *                                  should have the new names of the fields as array indexes.
  165.      *
  166.      *                                 The value of each entry of the array should be set to another associative
  167.      *                                  array with the properties of the fields to that are meant to be changed as
  168.      *                                  array entries. These entries should be assigned to the new values of the
  169.      *                                  respective properties. The properties of the fields should be the same
  170.      *                                  as defined by the Metabase parser.
  171.      *
  172.      *                             Example
  173.      *                                 array(
  174.      *                                     'name' => 'userlist',
  175.      *                                     'add' => array(
  176.      *                                         'quota' => array(
  177.      *                                             'type' => 'integer',
  178.      *                                             'unsigned' => 1
  179.      *                                         )
  180.      *                                     ),
  181.      *                                     'remove' => array(
  182.      *                                         'file_limit' => array(),
  183.      *                                         'time_limit' => array()
  184.      *                                     ),
  185.      *                                     'change' => array(
  186.      *                                         'name' => array(
  187.      *                                             'length' => '20',
  188.      *                                             'definition' => array(
  189.      *                                                 'type' => 'text',
  190.      *                                                 'length' => 20,
  191.      *                                             ),
  192.      *                                         )
  193.      *                                     ),
  194.      *                                     'rename' => array(
  195.      *                                         'sex' => array(
  196.      *                                             'name' => 'gender',
  197.      *                                             'definition' => array(
  198.      *                                                 'type' => 'text',
  199.      *                                                 'length' => 1,
  200.      *                                                 'default' => 'M',
  201.      *                                             ),
  202.      *                                         )
  203.      *                                     )
  204.      *                                 )
  205.      *
  206.      * @param boolean $check     indicates whether the function should just check if the DBMS driver
  207.      *                              can perform the requested table alterations if the value is true or
  208.      *                              actually perform them otherwise.
  209.      * @access public
  210.      *
  211.       * @return mixed MDB2_OK on success, a MDB2 error on failure
  212.      */
  213.     function alterTable($name$changes$check$options = array())
  214.     {
  215.         $db =$this->getDBInstance();
  216.         if (PEAR::isError($db)) {
  217.             return $db;
  218.         }
  219.  
  220.         foreach ($changes as $change_name => $change{
  221.             switch ($change_name{
  222.             case 'add':
  223.             case 'remove':
  224.             case 'change':
  225.             case 'name':
  226.             case 'rename':
  227.                 break;
  228.             default:
  229.                 return $db->raiseError(MDB2_ERROR_CANNOT_ALTERnullnull,
  230.                     'change type "'.$change_name.'" not yet supported'__FUNCTION__);
  231.             }
  232.         }
  233.  
  234.         if ($check{
  235.             return MDB2_OK;
  236.         }
  237.  
  238.         $db->loadModule('Reverse'nulltrue);
  239.  
  240.         // actually sqlite 2.x supports no ALTER TABLE at all .. so we emulate it
  241.         $fields $db->manager->listTableFields($name);
  242.         if (PEAR::isError($fields)) {
  243.             return $fields;
  244.         }
  245.  
  246.         $fields array_flip($fields);
  247.         foreach ($fields as $field => $value{
  248.             $definition $db->reverse->getTableFieldDefinition($name$field);
  249.             if (PEAR::isError($definition)) {
  250.                 return $definition;
  251.             }
  252.             $fields[$field$definition[0];
  253.         }
  254.  
  255.         $indexes $db->manager->listTableIndexes($name);
  256.         if (PEAR::isError($indexes)) {
  257.             return $indexes;
  258.         }
  259.  
  260.         $indexes array_flip($indexes);
  261.         foreach ($indexes as $index => $value{
  262.             $definition $db->reverse->getTableIndexDefinition($name$index);
  263.             if (PEAR::isError($definition)) {
  264.                 return $definition;
  265.             }
  266.             $indexes[$index$definition;
  267.         }
  268.  
  269.         $constraints $db->manager->listTableConstraints($name);
  270.         if (PEAR::isError($constraints)) {
  271.             return $constraints;
  272.         }
  273.  
  274.         $constraints array_flip($constraints);
  275.         foreach ($constraints as $constraint => $value{
  276.             if (!empty($definition['primary'])) {
  277.                 if (!array_key_exists('primary'$options)) {
  278.                     $options['primary'$definition['fields'];
  279.                 }
  280.             else {
  281.                 $definition $db->reverse->getTableConstraintDefinition($name$constraint);
  282.                 if (PEAR::isError($definition)) {
  283.                     return $definition;
  284.                 }
  285.                 $constraints[$constraint$definition;
  286.             }
  287.         }
  288.  
  289.         $name_new $name;
  290.         $create_order $select_fields array_keys($fields);
  291.         foreach ($changes as $change_name => $change{
  292.             switch ($change_name{
  293.             case 'add':
  294.                 foreach ($change as $field_name => $field{
  295.                     $fields[$field_name$field;
  296.                     $create_order[$field_name;
  297.                 }
  298.                 break;
  299.             case 'remove':
  300.                 foreach ($change as $field_name => $field{
  301.                     unset($fields[$field_name]);
  302.                     $select_fields array_diff($select_fieldsarray($field_name));
  303.                     $create_order array_diff($create_orderarray($field_name));
  304.                 }
  305.                 break;
  306.             case 'change':
  307.                 foreach ($change as $field_name => $field{
  308.                     $fields[$field_name$field['definition'];
  309.                 }
  310.                 break;
  311.             case 'name':
  312.                 $name_new $change;
  313.                 break;
  314.             case 'rename':
  315.                 foreach ($change as $field_name => $field{
  316.                     unset($fields[$field_name]);
  317.                     $fields[$field['name']] $field['definition'];
  318.                     $create_order[array_search($field_name$create_order)$field['name'];
  319.                 }
  320.                 break;
  321.             default:
  322.                 return $db->raiseError(MDB2_ERROR_CANNOT_ALTERnullnull,
  323.                     'change type "'.$change_name.'" not yet supported'__FUNCTION__);
  324.             }
  325.         }
  326.  
  327.         $data = null;
  328.         if (!empty($select_fields)) {
  329.             $query 'SELECT '.implode(', '$select_fields).' FROM '.$db->quoteIdentifier($nametrue);
  330.             $data $db->queryAll($querynullMDB2_FETCHMODE_ORDERED);
  331.         }
  332.  
  333.         $result $this->dropTable($name);
  334.         if (PEAR::isError($result)) {
  335.             return $result;
  336.         }
  337.  
  338.         $result $this->createTable($name_new$fields$options);
  339.         if (PEAR::isError($result)) {
  340.             return $result;
  341.         }
  342.  
  343.         foreach ($indexes as $index => $definition{
  344.             $this->createIndex($name_new$index$definition);
  345.         }
  346.  
  347.         foreach ($constraints as $constraint => $definition{
  348.             $this->createConstraint($name_new$constraint$definition);
  349.         }
  350.  
  351.         if (!empty($select_fields&& !empty($data)) {
  352.             $query 'INSERT INTO '.$db->quoteIdentifier($name_newtrue);
  353.             $query.= '('.implode(', 'array_slice(array_keys($fields)0count($select_fields))).')';
  354.             $query.=' VALUES (?'.str_repeat(', ?'(count($select_fields- 1)).')';
  355.             $stmt =$db->prepare($querynullMDB2_PREPARE_MANIP);
  356.             if (PEAR::isError($stmt)) {
  357.                 return $stmt;
  358.             }
  359.             foreach ($data as $row{
  360.                 $result $stmt->execute($row);
  361.                 if (PEAR::isError($result)) {
  362.                     return $result;
  363.                 }
  364.             }
  365.         }
  366.         return MDB2_OK;
  367.     }
  368.  
  369.     // }}}
  370.     // {{{ listDatabases()
  371.  
  372.     /**
  373.      * list all databases
  374.      *
  375.      * @return mixed data array on success, a MDB2 error on failure
  376.      * @access public
  377.      */
  378.     function listDatabases()
  379.     {
  380.         $db =$this->getDBInstance();
  381.         if (PEAR::isError($db)) {
  382.             return $db;
  383.         }
  384.  
  385.         return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  386.             'list databases is not supported'__FUNCTION__);
  387.     }
  388.  
  389.     // }}}
  390.     // {{{ listUsers()
  391.  
  392.     /**
  393.      * list all users
  394.      *
  395.      * @return mixed data array on success, a MDB2 error on failure
  396.      * @access public
  397.      */
  398.     function listUsers()
  399.     {
  400.         $db =$this->getDBInstance();
  401.         if (PEAR::isError($db)) {
  402.             return $db;
  403.         }
  404.  
  405.         return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  406.             'list databases is not supported'__FUNCTION__);
  407.     }
  408.  
  409.     // }}}
  410.     // {{{ listTables()
  411.  
  412.     /**
  413.      * list all tables in the current database
  414.      *
  415.      * @return mixed data array on success, a MDB2 error on failure
  416.      * @access public
  417.      */
  418.     function listTables()
  419.     {
  420.         $db =$this->getDBInstance();
  421.         if (PEAR::isError($db)) {
  422.             return $db;
  423.         }
  424.  
  425.         $query "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name";
  426.         $table_names $db->queryCol($query);
  427.         if (PEAR::isError($table_names)) {
  428.             return $table_names;
  429.         }
  430.         $result = array();
  431.         foreach ($table_names as $table_name{
  432.             if (!$this->_fixSequenceName($table_nametrue)) {
  433.                 $result[$table_name;
  434.             }
  435.         }
  436.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  437.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  438.         }
  439.         return $result;
  440.     }
  441.  
  442.     // }}}
  443.     // {{{ listTableFields()
  444.  
  445.     /**
  446.      * list all fields in a tables in the current database
  447.      *
  448.      * @param string $table name of table that should be used in method
  449.      * @return mixed data array on success, a MDB2 error on failure
  450.      * @access public
  451.      */
  452.     function listTableFields($table)
  453.     {
  454.         $db =$this->getDBInstance();
  455.         if (PEAR::isError($db)) {
  456.             return $db;
  457.         }
  458.  
  459.         $result $db->loadModule('Reverse'nulltrue);
  460.         if (PEAR::isError($result)) {
  461.             return $result;
  462.         }
  463.         $query "SELECT sql FROM sqlite_master WHERE type='table' AND ";
  464.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  465.             $query.= 'LOWER(name)='.$db->quote(strtolower($table)'text');
  466.         else {
  467.             $query.= 'name='.$db->quote($table'text');
  468.         }
  469.         $sql $db->queryOne($query);
  470.         if (PEAR::isError($sql)) {
  471.             return $sql;
  472.         }
  473.         $columns $db->reverse->_getTableColumns($sql);
  474.         $fields = array();
  475.         foreach ($columns as $column{
  476.             if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  477.                 if ($db->options['field_case'== CASE_LOWER{
  478.                     $column['name'strtolower($column['name']);
  479.                 else {
  480.                     $column['name'strtoupper($column['name']);
  481.                 }
  482.             else {
  483.                 $column array_change_key_case($column$db->options['field_case']);
  484.             }
  485.             $fields[$column['name'];
  486.         }
  487.         return $fields;
  488.     }
  489.  
  490.     // }}}
  491.     // {{{ createIndex()
  492.  
  493.     /**
  494.      * Get the stucture of a field into an array
  495.      *
  496.      * @param string    $table         name of the table on which the index is to be created
  497.      * @param string    $name         name of the index to be created
  498.      * @param array     $definition        associative array that defines properties of the index to be created.
  499.      *                                  Currently, only one property named FIELDS is supported. This property
  500.      *                                  is also an associative with the names of the index fields as array
  501.      *                                  indexes. Each entry of this array is set to another type of associative
  502.      *                                  array that specifies properties of the index that are specific to
  503.      *                                  each field.
  504.      *
  505.      *                                 Currently, only the sorting property is supported. It should be used
  506.      *                                  to define the sorting direction of the index. It may be set to either
  507.      *                                  ascending or descending.
  508.      *
  509.      *                                 Not all DBMS support index sorting direction configuration. The DBMS
  510.      *                                  drivers of those that do not support it ignore this property. Use the
  511.      *                                  function support() to determine whether the DBMS driver can manage indexes.
  512.  
  513.      *                                  Example
  514.      *                                     array(
  515.      *                                         'fields' => array(
  516.      *                                             'user_name' => array(
  517.      *                                                 'sorting' => 'ascending'
  518.      *                                             ),
  519.      *                                             'last_login' => array()
  520.      *                                         )
  521.      *                                     )
  522.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  523.      * @access public
  524.      */
  525.     function createIndex($table$name$definition)
  526.     {
  527.         $db =$this->getDBInstance();
  528.         if (PEAR::isError($db)) {
  529.             return $db;
  530.         }
  531.  
  532.         $table $db->quoteIdentifier($tabletrue);
  533.         $name  $db->getIndexName($name);
  534.         $query = "CREATE INDEX $name ON $table";
  535.         $fields = array();
  536.         foreach ($definition['fields'as $field_name => $field{
  537.             $field_string $field_name;
  538.             if (!empty($field['sorting'])) {
  539.                 switch ($field['sorting']{
  540.                 case 'ascending':
  541.                     $field_string.= ' ASC';
  542.                     break;
  543.                 case 'descending':
  544.                     $field_string.= ' DESC';
  545.                     break;
  546.                 }
  547.             }
  548.             $fields[$field_string;
  549.         }
  550.         $query .= ' ('.implode(', '$fields')';
  551.         return $db->exec($query);
  552.     }
  553.  
  554.     // }}}
  555.     // {{{ dropIndex()
  556.  
  557.     /**
  558.      * drop existing index
  559.      *
  560.      * @param string    $table         name of table that should be used in method
  561.      * @param string    $name         name of the index to be dropped
  562.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  563.      * @access public
  564.      */
  565.     function dropIndex($table$name)
  566.     {
  567.         $db =$this->getDBInstance();
  568.         if (PEAR::isError($db)) {
  569.             return $db;
  570.         }
  571.  
  572.         $name $db->getIndexName($name);
  573.         return $db->exec("DROP INDEX $name");
  574.     }
  575.  
  576.     // }}}
  577.     // {{{ listTableIndexes()
  578.  
  579.     /**
  580.      * list all indexes in a table
  581.      *
  582.      * @param string    $table      name of table that should be used in method
  583.      * @return mixed data array on success, a MDB2 error on failure
  584.      * @access public
  585.      */
  586.     function listTableIndexes($table)
  587.     {
  588.         $db =$this->getDBInstance();
  589.         if (PEAR::isError($db)) {
  590.             return $db;
  591.         }
  592.  
  593.         $table $db->quote($table'text');
  594.         $query "SELECT sql FROM sqlite_master WHERE type='index' AND ";
  595.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  596.             $query.= 'LOWER(tbl_name)='.strtolower($table);
  597.         else {
  598.             $query.= "tbl_name=$table";
  599.         }
  600.         $query.= " AND sql NOT NULL ORDER BY name";
  601.         $indexes $db->queryCol($query'text');
  602.         if (PEAR::isError($indexes)) {
  603.             return $indexes;
  604.         }
  605.  
  606.         $result = array();
  607.         foreach ($indexes as $sql{
  608.             if (preg_match("/^create index ([^ ]+) on /i"$sql$tmp)) {
  609.                 $index $this->_fixIndexName($tmp[1]);
  610.                 if (!empty($index)) {
  611.                     $result[$index= true;
  612.                 }
  613.             }
  614.         }
  615.  
  616.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  617.             $result array_change_key_case($result$db->options['field_case']);
  618.         }
  619.         return array_keys($result);
  620.     }
  621.  
  622.     // }}}
  623.     // {{{ createConstraint()
  624.  
  625.     /**
  626.      * create a constraint on a table
  627.      *
  628.      * @param string    $table         name of the table on which the constraint is to be created
  629.      * @param string    $name         name of the constraint to be created
  630.      * @param array     $definition        associative array that defines properties of the constraint to be created.
  631.      *                                  Currently, only one property named FIELDS is supported. This property
  632.      *                                  is also an associative with the names of the constraint fields as array
  633.      *                                  constraints. Each entry of this array is set to another type of associative
  634.      *                                  array that specifies properties of the constraint that are specific to
  635.      *                                  each field.
  636.      *
  637.      *                                  Example
  638.      *                                     array(
  639.      *                                         'fields' => array(
  640.      *                                             'user_name' => array(),
  641.      *                                             'last_login' => array()
  642.      *                                         )
  643.      *                                     )
  644.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  645.      * @access public
  646.      */
  647.     function createConstraint($table$name$definition)
  648.     {
  649.         $db =$this->getDBInstance();
  650.         if (PEAR::isError($db)) {
  651.             return $db;
  652.         }
  653.  
  654.         if (!empty($definition['primary'])) {
  655.             return $db->alterTable($tablearray()falsearray('primary' => $definition['fields']));
  656.         }
  657.  
  658.         $table $db->quoteIdentifier($tabletrue);
  659.         $name  $db->getIndexName($name);
  660.         $query = "CREATE UNIQUE INDEX $name ON $table";
  661.         $fields = array();
  662.         foreach ($definition['fields'as $field_name => $field{
  663.             $field_string $field_name;
  664.             if (!empty($field['sorting'])) {
  665.                 switch ($field['sorting']{
  666.                 case 'ascending':
  667.                     $field_string.= ' ASC';
  668.                     break;
  669.                 case 'descending':
  670.                     $field_string.= ' DESC';
  671.                     break;
  672.                 }
  673.             }
  674.             $fields[$field_string;
  675.         }
  676.         $query .= ' ('.implode(', '$fields')';
  677.         return $db->exec($query);
  678.     }
  679.  
  680.     // }}}
  681.     // {{{ dropConstraint()
  682.  
  683.     /**
  684.      * drop existing constraint
  685.      *
  686.      * @param string    $table        name of table that should be used in method
  687.      * @param string    $name         name of the constraint to be dropped
  688.      * @param string    $primary      hint if the constraint is primary
  689.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  690.      * @access public
  691.      */
  692.     function dropConstraint($table$name$primary = false)
  693.     {
  694.         $db =$this->getDBInstance();
  695.         if (PEAR::isError($db)) {
  696.             return $db;
  697.         }
  698.  
  699.         if ($primary || $name == 'PRIMARY'{
  700.             return $db->alterTable($tablearray()falsearray('primary' => null));
  701.         }
  702.  
  703.         $name $db->getIndexName($name);
  704.         return $db->exec("DROP INDEX $name");
  705.     }
  706.  
  707.     // }}}
  708.     // {{{ listTableConstraints()
  709.  
  710.     /**
  711.      * list all constraints in a table
  712.      *
  713.      * @param string    $table      name of table that should be used in method
  714.      * @return mixed data array on success, a MDB2 error on failure
  715.      * @access public
  716.      */
  717.     function listTableConstraints($table)
  718.     {
  719.         $db =$this->getDBInstance();
  720.         if (PEAR::isError($db)) {
  721.             return $db;
  722.         }
  723.  
  724.         $table $db->quote($table'text');
  725.         $query "SELECT sql FROM sqlite_master WHERE type='index' AND ";
  726.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  727.             $query.= 'LOWER(tbl_name)='.strtolower($table);
  728.         else {
  729.             $query.= "tbl_name=$table";
  730.         }
  731.         $query.= " AND sql NOT NULL ORDER BY name";
  732.         $indexes $db->queryCol($query'text');
  733.         if (PEAR::isError($indexes)) {
  734.             return $indexes;
  735.         }
  736.  
  737.         $result = array();
  738.         foreach ($indexes as $sql{
  739.             if (preg_match("/^create unique index ([^ ]+) on /i"$sql$tmp)) {
  740.                 $index $this->_fixIndexName($tmp[1]);
  741.                 if (!empty($index)) {
  742.                     $result[$index= true;
  743.                 }
  744.             }
  745.         }
  746.  
  747.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  748.             $result array_change_key_case($result$db->options['field_case']);
  749.         }
  750.         return array_keys($result);
  751.     }
  752.  
  753.     // }}}
  754.     // {{{ createSequence()
  755.  
  756.     /**
  757.      * create sequence
  758.      *
  759.      * @param string    $seq_name     name of the sequence to be created
  760.      * @param string    $start         start value of the sequence; default is 1
  761.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  762.      * @access public
  763.      */
  764.     function createSequence($seq_name$start = 1)
  765.     {
  766.         $db =$this->getDBInstance();
  767.         if (PEAR::isError($db)) {
  768.             return $db;
  769.         }
  770.  
  771.         $sequence_name $db->quoteIdentifier($db->getSequenceName($seq_name)true);
  772.         $seqcol_name $db->quoteIdentifier($db->options['seqcol_name']true);
  773.         $query = "CREATE TABLE $sequence_name ($seqcol_name INTEGER PRIMARY KEY DEFAULT 0 NOT NULL)";
  774.         $res $db->exec($query);
  775.         if (PEAR::isError($res)) {
  776.             return $res;
  777.         }
  778.         if ($start == 1{
  779.             return MDB2_OK;
  780.         }
  781.         $res $db->exec("INSERT INTO $sequence_name ($seqcol_name) VALUES (".($start-1).')');
  782.         if (!PEAR::isError($res)) {
  783.             return MDB2_OK;
  784.         }
  785.         // Handle error
  786.         $result $db->exec("DROP TABLE $sequence_name");
  787.         if (PEAR::isError($result)) {
  788.             return $db->raiseError($resultnullnull,
  789.                 'could not drop inconsistent sequence table'__FUNCTION__);
  790.         }
  791.         return $db->raiseError($resnullnull,
  792.             'could not create sequence table'__FUNCTION__);
  793.     }
  794.  
  795.     // }}}
  796.     // {{{ dropSequence()
  797.  
  798.     /**
  799.      * drop existing sequence
  800.      *
  801.      * @param string    $seq_name     name of the sequence to be dropped
  802.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  803.      * @access public
  804.      */
  805.     function dropSequence($seq_name)
  806.     {
  807.         $db =$this->getDBInstance();
  808.         if (PEAR::isError($db)) {
  809.             return $db;
  810.         }
  811.  
  812.         $sequence_name $db->quoteIdentifier($db->getSequenceName($seq_name)true);
  813.         return $db->exec("DROP TABLE $sequence_name");
  814.     }
  815.  
  816.     // }}}
  817.     // {{{ listSequences()
  818.  
  819.     /**
  820.      * list all sequences in the current database
  821.      *
  822.      * @return mixed data array on success, a MDB2 error on failure
  823.      * @access public
  824.      */
  825.     function listSequences()
  826.     {
  827.         $db =$this->getDBInstance();
  828.         if (PEAR::isError($db)) {
  829.             return $db;
  830.         }
  831.  
  832.         $query "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name";
  833.         $table_names $db->queryCol($query);
  834.         if (PEAR::isError($table_names)) {
  835.             return $table_names;
  836.         }
  837.         $result = array();
  838.         foreach ($table_names as $table_name{
  839.             if ($sqn $this->_fixSequenceName($table_nametrue)) {
  840.                 $result[$sqn;
  841.             }
  842.         }
  843.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE{
  844.             $result array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$result);
  845.         }
  846.         return $result;
  847.     }
  848.  
  849.     // }}}
  850. }
  851. ?>

Documentation generated on Mon, 11 Mar 2019 14:43:21 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.