简体   繁体   中英

CodeIgniter DB Forge add Engine and Unique key to table

I am trying to create table for CI Plugin System using Migration. Here is the code for the migration file.

public function up()
{
    $fields = array(
        'plugin_id bigint(20) unsigned NOT NULL AUTO_INCREMENT',
        'plugin_system_name varchar(255) NOT NULL',
        'plugin_uri varchar(120) DEFAULT NULL',
        'plugin_version varchar(30) NOT NULL',
        'plugin_description text',
        'plugin_author varchar(120) DEFAULT NULL',
        'plugin_author_uri varchar(120) DEFAULT NULL',
        'plugin_data longtext'
        );

    $this->dbforge->add_field($fields);
    $this->db->query('UNIQUE KEY `plugin_index` (`plugin_system_name`) USING BTREE');
    $this->db->query('ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=latin1');
    $this->dbforge->add_key('plugin_id', true);
    $this->dbforge->create_table('plugins');

}

No of course it is giving me below error

Error Number: 1064

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNIQUE KEY `plugin_index` (`plugin_system_name`) USING BTREE' at line 1

UNIQUE KEY `plugin_index` (`plugin_system_name`) USING BTREE

Filename: \xampp\htdocs\myapp\system\database\DB_driver.php

Line Number: 330

While CI Plugin sql is as below

DROP TABLE IF EXISTS `plugins`;
CREATE TABLE `plugins` (
  `plugin_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `plugin_system_name` varchar(255) NOT NULL,
  `plugin_name` varchar(255) NOT NULL,
  `plugin_uri` varchar(120) DEFAULT NULL,
  `plugin_version` varchar(30) NOT NULL,
  `plugin_description` text,
  `plugin_author` varchar(120) DEFAULT NULL,
  `plugin_author_uri` varchar(120) DEFAULT NULL,
  `plugin_data` longtext,
  PRIMARY KEY (`plugin_id`),
  UNIQUE KEY `plugin_index` (`plugin_system_name`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;

I have read CodeIgniter document for Forge but they haven't describe in detail for all aspect regarding SQL. So I would appreciate if anyone can help me to resolve this issue and make it works with Migration.

Try this:

$sql = "DROP TABLE IF EXISTS `plugins`;
                  CREATE TABLE `plugins` (
                  `plugin_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
                  `plugin_system_name` varchar(255) NOT NULL,
                  `plugin_name` varchar(255) NOT NULL,
                  `plugin_uri` varchar(120) DEFAULT NULL,
                  `plugin_version` varchar(30) NOT NULL,
                  `plugin_description` text,
                  `plugin_author` varchar(120) DEFAULT NULL,
                  `plugin_author_uri` varchar(120) DEFAULT NULL,
                  `plugin_data` longtext,
                   PRIMARY KEY (`plugin_id`),
                   UNIQUE KEY `plugin_index` (`plugin_system_name`) USING BTREE
                   ) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=latin1; ";
$this->db->query($sql);

According to this post , it is the only way to do this as DBForge doesn't have a way to create a new table.

Update:

This post I think would be a proper solution. Ill give it here incase the link breaks:

The least path of resistance, if you wish to have MYISAM exclusively is to overload the CI_DB_Forge_mysql class. To do this you will need to create a MY_Loader.php class file >located in your application/core folder.

This is from the sparks generated loader class, abreviated with the additional dbforge >overload.

<?php  if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * Sparks
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package  CodeIgniter
 * @author  CodeIgniter Reactor Dev Team
 * @author      Kenny Katzgrau <katzgrau@gmail.com>
 * @since  CodeIgniter Version 1.0
 * @filesource
 */

/**
 * Loader Class
 *
 * Loads views and files
 *
 * @package  CodeIgniter
 * @subpackage Libraries
 * @author  CodeIgniter Reactor Dev Team
 * @author      Kenny Katzgrau <katzgrau@gmail.com>
 * @category Loader
 * @link  http://ellislab.com/codeigniter/user-guide/libraries/loader.html
 */
class MY_Loader extends CI_Loader
{
   ...

 // --------------------------------------------------------------------

 /**
  * Load the Database Forge Class
  *
  * @return string
  */
 public function dbforge()
 {
  if ( ! class_exists('CI_DB'))
  {
   $this->database();
  }

  $CI =& get_instance();

  require_once(BASEPATH.'database/DB_forge.php');
  require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge.php');
  /* Look for overload files in the /application/core folder */
  if (file_exists(BASEPATH.'../'.APPPATH.'core/MY_CI_DB_'.$CI->db->dbdriver.'_forge.php')) {
   require_once(BASEPATH.'../'.APPPATH.'core/MY_CI_DB_'.$CI->db->dbdriver.'_forge.php');
   $class = 'MY_CI_DB_'.$CI->db->dbdriver.'_forge';
  } else {  
   $class = 'CI_DB_'.$CI->db->dbdriver.'_forge';
  }

  $CI->dbforge = new $class();
 } 
} 

Next Create a file in your application/libraries folder called: MY_CI_DB_mysql_forge.php

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * MySQL Forge Class Force MYISAM
 *
 * @category Database
 * @author 
 * @link 
 */
class MY_CI_DB_mysql_forge extends CI_DB_mysql_forge {
 // --------------------------------------------------------------------


 /**
  * Create Table
  *
  * @access private
  * @param string the table name
  * @param mixed the fields
  * @param mixed primary key(s)
  * @param mixed key(s)
  * @param boolean should 'IF NOT EXISTS' be added to the SQL
  * @return bool
  */
 function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 {

  $sql = 'CREATE TABLE ';

  if ($if_not_exists === TRUE)
  {
   $sql .= 'IF NOT EXISTS ';
  }

  $sql .= $this->db->_escape_identifiers($table)." (";

  $sql .= $this->_process_fields($fields);

  if (count($primary_keys) > 0)
  {
   $key_name = $this->db->_protect_identifiers(implode('_', $primary_keys));
   $primary_keys = $this->db->_protect_identifiers($primary_keys);
   $sql .= ",\n\tPRIMARY KEY ".$key_name." (" . implode(', ', $primary_keys) . ")";
  }

  if (is_array($keys) && count($keys) > 0)
  {
   foreach ($keys as $key)
   {
    if (is_array($key))
    {
     $key_name = $this->db->_protect_identifiers(implode('_', $key));
     $key = $this->db->_protect_identifiers($key);
    }
    else
    {
     $key_name = $this->db->_protect_identifiers($key);
     $key = array($key_name);
    }

    $sql .= ",\n\tKEY {$key_name} (" . implode(', ', $key) . ")";
   }
  }

  $sql .= "\n) ENGINE=MYISAM DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};";

  return $sql;
 }
} 

Adding these will enable the $this->dbforge->create_table() method to return the sql for a MYISAM table.

If you have access to the mysql instance, you could force the default table engine to be MYISAM or whatever using the —default-storage-engine or—default-table-type at startup.

This is a pretty good write up I found as well for older versions of CI

I hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM