Source for file Sqlite.php

Documentation is available at Sqlite.php

  1. <?php
  2. /*
  3.  *  $Id: Sqlite.php 2288 2007-08-29 21:51:49Z Jonathan.Wage $
  4.  *
  5.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16.  *
  17.  * This software consists of voluntary contributions made by many individuals
  18.  * and is licensed under the LGPL. For more information, see
  19.  * <http://www.phpdoctrine.com>.
  20.  */
  21. Doctrine::autoload('Doctrine_Export');
  22. /**
  23.  * Doctrine_Export_Sqlite
  24.  *
  25.  * @package     Doctrine
  26.  * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
  27.  * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
  28.  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  29.  * @category    Object Relational Mapping
  30.  * @link        www.phpdoctrine.com
  31.  * @since       1.0
  32.  * @version     $Revision: 2288 $
  33.  */
  34. {
  35.     /**
  36.      * drop an existing database
  37.      *
  38.      * @param string $name                  name of the database that should be dropped
  39.      * @throws Doctrine_Export_Exception    if the database file does not exist
  40.      * @throws Doctrine_Export_Exception    if something failed during the removal of the database file
  41.      * @return void 
  42.      */
  43.     public function dropDatabase($name)
  44.     {
  45.         $databaseFile $this->conn->getDatabaseFile($name);
  46.         if (!@file_exists($databaseFile)) {
  47.             throw new Doctrine_Export_Exception('database does not exist');
  48.         }
  49.         $result @unlink($databaseFile);
  50.         if $result{
  51.             throw new Doctrine_Export_Exception('could not remove the database file');
  52.         }
  53.     }
  54.  
  55.     /**
  56.      * Get the stucture of a field into an array
  57.      *
  58.      * @param string    $table         name of the table on which the index is to be created
  59.      * @param string    $name         name of the index to be created
  60.      * @param array     $definition        associative array that defines properties of the index to be created.
  61.      *                                  Currently, only one property named FIELDS is supported. This property
  62.      *                                  is also an associative with the names of the index fields as array
  63.      *                                  indexes. Each entry of this array is set to another type of associative
  64.      *                                  array that specifies properties of the index that are specific to
  65.      *                                  each field.
  66.      *
  67.      *                                 Currently, only the sorting property is supported. It should be used
  68.      *                                  to define the sorting direction of the index. It may be set to either
  69.      *                                  ascending or descending.
  70.      *
  71.      *                                 Not all DBMS support index sorting direction configuration. The DBMS
  72.      *                                  drivers of those that do not support it ignore this property. Use the
  73.      *                                  function support() to determine whether the DBMS driver can manage indexes.
  74.  
  75.      *                                  Example
  76.      *                                     array(
  77.      *                                         'fields' => array(
  78.      *                                             'user_name' => array(
  79.      *                                                 'sorting' => 'ascending'
  80.      *                                             ),
  81.      *                                             'last_login' => array()
  82.      *                                         )
  83.      *                                     )
  84.      * @throws PDOException
  85.      * @return void 
  86.      */
  87.     public function createIndexSql($table$namearray $definition)
  88.     {
  89.         $table $this->conn->quoteIdentifier($tabletrue);
  90.         $name  $this->conn->formatter->getIndexName($name);
  91.         $query 'CREATE INDEX ' $name ' ON ' $table;
  92.         $query .= ' (' $this->getIndexFieldDeclarationList($definition['fields']')';
  93.  
  94.         return $query;
  95.     }
  96.     /**
  97.      * getIndexFieldDeclarationList
  98.      * Obtain DBMS specific SQL code portion needed to set an index
  99.      * declaration to be used in statements like CREATE TABLE.
  100.      *
  101.      * @return string 
  102.      */
  103.     public function getIndexFieldDeclarationList(array $fields)
  104.     {
  105.         $declFields array();
  106.  
  107.         foreach ($fields as $fieldName => $field{
  108.             $fieldString $fieldName;
  109.  
  110.             if (is_array($field)) {
  111.                 if (isset($field['sorting'])) {
  112.                     $sort strtoupper($field['sorting']);
  113.                     switch ($sort{
  114.                         case 'ASC':
  115.                         case 'DESC':
  116.                             $fieldString .= ' ' $sort;
  117.                             break;
  118.                         default:
  119.                             throw new Doctrine_Export_Exception('Unknown index sorting option given.');
  120.                     }
  121.                 }
  122.             else {
  123.                 $fieldString $field;
  124.             }
  125.             $declFields[$fieldString;
  126.         }
  127.         return implode(', '$declFields);
  128.     }
  129.     /**
  130.      * create a new table
  131.      *
  132.      * @param string $name   Name of the database that should be created
  133.      * @param array $fields  Associative array that contains the definition of each field of the new table
  134.      *                        The indexes of the array entries are the names of the fields of the table an
  135.      *                        the array entry values are associative arrays like those that are meant to be
  136.      *                        passed with the field definitions to get[Type]Declaration() functions.
  137.      *                           array(
  138.      *                               'id' => array(
  139.      *                                   'type' => 'integer',
  140.      *                                   'unsigned' => 1
  141.      *                                   'notnull' => 1
  142.      *                                   'default' => 0
  143.      *                               ),
  144.      *                               'name' => array(
  145.      *                                   'type' => 'text',
  146.      *                                   'length' => 12
  147.      *                               ),
  148.      *                               'password' => array(
  149.      *                                   'type' => 'text',
  150.      *                                   'length' => 12
  151.      *                               )
  152.      *                           );
  153.      * @param array $options  An associative array of table options:
  154.      *
  155.      * @return void 
  156.      */
  157.     public function createTableSql($namearray $fieldsarray $options array())
  158.     {
  159.         if $name{
  160.             throw new Doctrine_Export_Exception('no valid table name specified');
  161.         }
  162.         
  163.         if (empty($fields)) {
  164.             throw new Doctrine_Export_Exception('no fields specified for table '.$name);
  165.         }
  166.         $queryFields $this->getFieldDeclarationList($fields);
  167.         
  168.         $autoinc false;
  169.         foreach($fields as $field{
  170.             if(isset($field['autoincrement']&& $field['autoincrement'|| 
  171.               (isset($field['autoinc']&& $field['autoinc'])) {
  172.                 $autoinc true;
  173.                 break;
  174.             }
  175.         }
  176.  
  177.         if $autoinc && isset($options['primary']&& empty($options['primary'])) {
  178.             $queryFields.= ', PRIMARY KEY('.implode(', 'array_values($options['primary'])).')';
  179.         }
  180.  
  181.         $name  $this->conn->quoteIdentifier($nametrue);
  182.         $sql   'CREATE TABLE ' $name ' (' $queryFields;
  183.  
  184.         if ($check $this->getCheckDeclaration($fields)) {
  185.             $sql .= ', ' $check;
  186.         }
  187.  
  188.         if (isset($options['checks']&& $check $this->getCheckDeclaration($options['checks'])) {
  189.             $sql .= ', ' $check;
  190.         }
  191.  
  192.         $sql .= ')';
  193.  
  194.         $query[$sql;
  195.  
  196.         if (isset($options['indexes']&& empty($options['indexes'])) {
  197.             foreach ($options['indexes'as $index => $definition{
  198.                 $query[$this->createIndexSql($name$index$definition);
  199.             }
  200.         }
  201.         return $query;
  202.         
  203.         
  204.         /**
  205.         try {
  206.  
  207.             if ( ! empty($fk)) {
  208.                 $this->conn->beginTransaction();
  209.             }
  210.  
  211.             $ret   = $this->conn->exec($query);
  212.  
  213.             if ( ! empty($fk)) {
  214.                 foreach ($fk as $definition) {
  215.  
  216.                     $query = 'CREATE TRIGGER doctrine_' . $name . '_cscd_delete '
  217.                            . 'AFTER DELETE ON ' . $name . ' FOR EACH ROW '
  218.                            . 'BEGIN '
  219.                            . 'DELETE FROM ' . $definition['foreignTable'] . ' WHERE ';
  220.  
  221.                     $local = (array) $definition['local'];
  222.                     foreach((array) $definition['foreign'] as $k => $field) {
  223.                         $query .= $field . ' = old.' . $local[$k] . ';';
  224.                     }
  225.  
  226.                     $query .= 'END;';
  227.  
  228.                     $this->conn->exec($query);
  229.                 }
  230.  
  231.                 $this->conn->commit();
  232.             }
  233.  
  234.  
  235.         } catch(Doctrine_Exception $e) {
  236.  
  237.             $this->conn->rollback();
  238.  
  239.             throw $e;
  240.         }
  241.         */
  242.     }
  243.     /**
  244.      * getAdvancedForeignKeyOptions
  245.      * Return the FOREIGN KEY query section dealing with non-standard options
  246.      * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
  247.      *
  248.      * @param array $definition         foreign key definition
  249.      * @return string 
  250.      * @access protected
  251.      */
  252.     public function getAdvancedForeignKeyOptions(array $definition)
  253.     {
  254.         $query '';
  255.         if (isset($definition['match'])) {
  256.             $query .= ' MATCH ' $definition['match'];
  257.         }
  258.         if (isset($definition['onUpdate'])) {
  259.             $query .= ' ON UPDATE ' $definition['onUpdate'];
  260.         }
  261.         if (isset($definition['onDelete'])) {
  262.             $query .= ' ON DELETE ' $definition['onDelete'];
  263.         }
  264.         if (isset($definition['deferrable'])) {
  265.             $query .= ' DEFERRABLE';
  266.         else {
  267.             $query .= ' NOT DEFERRABLE';
  268.         }
  269.         if (isset($definition['feferred'])) {
  270.             $query .= ' INITIALLY DEFERRED';
  271.         else {
  272.             $query .= ' INITIALLY IMMEDIATE';
  273.         }
  274.         return $query;
  275.     }
  276.     /**
  277.      * create sequence
  278.      *
  279.      * @param string    $seqName        name of the sequence to be created
  280.      * @param string    $start          start value of the sequence; default is 1
  281.      * @param array     $options  An associative array of table options:
  282.      *                           array(
  283.      *                               'comment' => 'Foo',
  284.      *                               'charset' => 'utf8',
  285.      *                               'collate' => 'utf8_unicode_ci',
  286.      *                           );
  287.      * @return boolean 
  288.      */
  289.     public function createSequence($seqName$start 1array $options array())
  290.     {
  291.         $sequenceName   $this->conn->quoteIdentifier($this->conn->getSequenceName($seqName)true);
  292.         $seqcolName     $this->conn->quoteIdentifier($this->conn->getAttribute(Doctrine::ATTR_SEQCOL_NAME)true);
  293.         $query          'CREATE TABLE ' $sequenceName ' (' $seqcolName ' INTEGER PRIMARY KEY DEFAULT 0 NOT NULL)';
  294.  
  295.         $this->conn->exec($query);
  296.  
  297.         if ($start == 1{
  298.             return true;
  299.         }
  300.  
  301.         try {
  302.             $this->conn->exec('INSERT INTO ' $sequenceName ' (' $seqcolName ') VALUES (' ($start-1')');
  303.             return true;
  304.         catch(Doctrine_Connection_Exception $e{
  305.             // Handle error    
  306.  
  307.             try {
  308.                 $result $db->exec('DROP TABLE ' $sequenceName);
  309.             catch(Doctrine_Connection_Exception $e{
  310.                 throw new Doctrine_Export_Exception('could not drop inconsistent sequence table');
  311.             }
  312.         }
  313.         throw new Doctrine_Export_Exception('could not create sequence table');
  314.     }
  315.     /**
  316.      * drop existing sequence
  317.      *
  318.      * @param string $sequenceName      name of the sequence to be dropped
  319.      * @return string 
  320.      */
  321.     public function dropSequenceSql($sequenceName)
  322.     {
  323.         $sequenceName $this->conn->quoteIdentifier($this->conn->getSequenceName($sequenceName)true);
  324.  
  325.         return 'DROP TABLE ' $sequenceName;
  326.     }
  327. }