示例#1
0
 /**
  * Return the meta data of a certain table.
  *
  * @param string $table the table name
  * @param bool $full all meta data or not
  *
  * @return array with meta data
  */
 public function metadata($table, $full = false)
 {
     /* first connect */
     if ($this->connect() == self::DB_SUCCESS) {
         $ddl = Ddl::create('MySqli');
         /* list fields */
         Tools::atkdebug("Retrieving metadata for {$table}");
         /* The tablename may also contain a schema. If so we check for it. */
         if (strpos($table, '.') !== false) {
             list($dbname, $tablename) = explode('.', $table);
             /* get meta data */
             $id = @$this->_query("SELECT * FROM `{$dbname}`.`{$tablename}` LIMIT 0", true);
         } else {
             /* get meta data */
             $id = $this->_query("SELECT * FROM `{$table}` LIMIT 0", true);
         }
         // table type
         $tableType = $this->_getTableType(isset($tablename) ? $tablename : $table);
         if (!$id) {
             Tools::atkdebug('Metadata query failed.');
             return [];
         }
         $i = 0;
         $result = [];
         while ($finfo = mysqli_fetch_field($id)) {
             $result[$i]['table'] = $finfo->table;
             $result[$i]['table_type'] = $tableType;
             $result[$i]['name'] = $finfo->name;
             $result[$i]['type'] = $finfo->type;
             $result[$i]['gentype'] = $ddl->getGenericType($finfo->type);
             $result[$i]['len'] = $finfo->length;
             $result[$i]['flags'] = 0;
             // if the connection character set is UTF8 MySQL returns the length multiplied
             // by 3, probably because the max length of an UTF8 character is 3 bytes, we need
             // the real size in characters, so we divide the length by 3
             if (strtoupper($this->m_charset) == 'UTF8' && ($result[$i]['gentype'] == 'string' || $result[$i]['gentype'] == 'text')) {
                 $result[$i]['len'] /= 3;
             } else {
                 if ($result[$i]['gentype'] == 'decimal') {
                     // for a mysql type DECIMAL, the length is returned as M+2 (signed) or M+1 (unsigned)
                     $offset = $finfo->flags & MYSQLI_UNSIGNED_FLAG ? 1 : 2;
                     $result[$i]['len'] -= $offset + $finfo->decimals;
                     $result[$i]['len'] .= ',' . $finfo->decimals;
                     // TODO we should also save the "unsigned" flag in $result[$i]["flags"]
                 }
             }
             if ($finfo->flags & MYSQLI_PRI_KEY_FLAG) {
                 $result[$i]['flags'] |= Db::MF_PRIMARY;
             }
             if ($finfo->flags & MYSQLI_UNIQUE_KEY_FLAG) {
                 $result[$i]['flags'] |= Db::MF_UNIQUE;
             }
             if ($finfo->flags & MYSQLI_NOT_NULL_FLAG) {
                 $result[$i]['flags'] |= Db::MF_NOT_NULL;
             }
             if ($finfo->flags & MYSQLI_AUTO_INCREMENT_FLAG) {
                 $result[$i]['flags'] |= Db::MF_AUTO_INCREMENT;
             }
             if ($full) {
                 $result['meta'][$result[$i]['name']] = $i;
             }
             ++$i;
         }
         if ($full) {
             $result['num_fields'] = $i;
         }
         mysqli_free_result($id);
         Tools::atkdebug("Metadata for {$table} complete");
         return $result;
     }
     return [];
 }
示例#2
0
 /**
  * Build a CREATE TABLE query and return it as a string.
  *
  * @return string The CREATE TABLE query.
  */
 public function buildCreate()
 {
     $query = parent::buildCreate();
     if (!empty($this->m_db->m_charset)) {
         $query .= ' DEFAULT CHARACTER SET ' . $this->m_db->m_charset;
         if (!empty($this->m_db->m_collate)) {
             $query .= ' COLLATE ' . $this->m_db->m_collate;
         }
     }
     if (!empty($query) && !empty($this->m_table_type)) {
         $query .= ' TYPE=' . $this->m_table_type;
     }
     return $query;
 }
示例#3
0
文件: Db.php 项目: sintattica/atk
 /**
  * Create an atkDdl object for constructing ddl queries.
  *
  * @return Ddl Ddl object
  */
 public function createDdl()
 {
     $ddl = Ddl::create($this->m_type);
     $ddl->m_db = $this;
     return $ddl;
 }
示例#4
0
 /**
  * Return the meta data of a certain table.
  *
  * @param string $table the table name
  * @param bool $full all meta data or not
  *
  * @return array with meta data
  */
 public function metadata($table, $full = false)
 {
     $ddl = Ddl::create('PgSql');
     if (strpos($table, '.') != false) {
         // there is a period in the table, so we split out the schema name.
         $schema = substr($table, 0, strpos($table, '.'));
         $table = substr($table, strpos($table, '.') + 1);
         $schema_condition = "AND n.nspname = '{$schema}' ";
         $schema_join = ' LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)';
     } else {
         //no period in the name, so there is no schema
         $schema_condition = '';
         $schema_join = '';
     }
     // Get meta data from system tables.
     // See developer manual (www.postgresql.org)
     // for system table specification.
     $sql = "SELECT\n          a.attnum AS i,\n          a.attname AS name,\n          t.typname AS type,\n          (CASE WHEN LOWER(t.typname) = 'varchar' AND a.attlen = -1 THEN a.atttypmod - 4 ELSE a.attlen END) AS length,\n          (CASE WHEN a.attnotnull THEN 1 ELSE 0 END) AS is_not_null,\n          (\n            SELECT COUNT(1)\n            FROM pg_index i\n            WHERE i.indrelid = c.oid\n            AND i.indisprimary = true\n            AND a.attnum IN (\n              i.indkey[0], i.indkey[1], i.indkey[2],\n              i.indkey[3], i.indkey[4], i.indkey[5],\n              i.indkey[6], i.indkey[7], i.indkey[8]\n            )\n            LIMIT 1\n          ) AS is_primary,\n          (\n            SELECT COUNT(1)\n            FROM pg_index i\n            WHERE i.indrelid = c.oid\n            AND i.indisunique = true\n            AND i.indnatts = 1\n            AND i.indkey[0] = a.attnum\n            LIMIT 1\n          ) AS is_unique,\n          (CASE WHEN ad.adsrc LIKE 'nextval(%::text)' THEN 1 ELSE 0 END) AS is_auto_inc,\n          (CASE WHEN ad.adsrc LIKE 'nextval(%::text)' THEN SUBSTRING(ad.adsrc, '''(.*?)''') END) AS sequence,\n          (CASE WHEN t.typname = 'varchar' THEN SUBSTRING(ad.adsrc FROM '^''(.*)''.*\$') ELSE ad.adsrc END) AS default\n        FROM pg_class c\n        JOIN pg_attribute a ON (a.attrelid = c.oid AND a.attnum > 0)\n        JOIN pg_type t ON (t.oid = a.atttypid)\n        LEFT JOIN pg_attrdef ad ON (ad.adrelid = c.oid AND ad.adnum = a.attnum)\n        {$schema_join}\n        WHERE c.relname = '{$table}'\n        {$schema_condition}\n        ORDER BY a.attnum";
     $meta = [];
     $rows = $this->getRows($sql);
     foreach ($rows as $i => $row) {
         $meta[$i]['table'] = $table;
         $meta[$i]['type'] = $row['type'];
         $meta[$i]['gentype'] = $ddl->getGenericType($row['type']);
         $meta[$i]['name'] = $row['name'];
         $meta[$i]['len'] = $row['length'];
         $meta[$i]['flags'] = ($row['is_primary'] == 1 ? Db::MF_PRIMARY : 0) | ($row['is_unique'] == 1 ? Db::MF_UNIQUE : 0) | ($row['is_not_null'] == 1 ? Db::MF_NOT_NULL : 0) | ($row['is_auto_inc'] == 1 ? Db::MF_AUTO_INCREMENT : 0);
         if ($row['is_auto_inc'] == 1) {
             $meta[$i]['sequence'] = $row['sequence'];
         } else {
             if (Tools::atk_strlen($row['default']) > 0) {
                 // date/time/datetime
                 if (strtolower($row['default']) == 'now' && in_array($meta[$i]['gentype'], array('date', 'time', 'datetime'))) {
                     $meta[$i]['default'] = 'NOW';
                 } else {
                     if (in_array($meta[$i]['gentype'], array('number', 'decimal'))) {
                         $meta[$i]['default'] = $row['default'];
                     } else {
                         if (in_array($meta[$i]['gentype'], array('string', 'text'))) {
                             $meta[$i]['default'] = $row['default'];
                         } else {
                             if ($meta[$i]['gentype'] == 'boolean') {
                                 $meta[$i]['default'] = strtolower($row['default']) == 't' ? 1 : 0;
                             }
                         }
                     }
                 }
             }
         }
         if ($full) {
             $meta['meta'][$row['name']] =& $meta[$i];
         }
     }
     if ($full) {
         $meta['num_fields'] = count($rows);
     }
     return $meta;
 }
示例#5
0
 /**
  * Constructor.
  */
 public function __construct()
 {
     parent::__construct();
 }