Torbjorn Zetterlund

Wed 27 2016
Image

How to add UUID to CodeIgniter Crud library Grocery Crud

by bernt & torsten

I recently had a need to use UUID as my primary key for an application that I have architected using the CodeIgniter framework with Grocery Crud on a MySQL database.


UUID (Universally Unique Identifiers) also known as GUID (Globally Unique Identifier) is a great way to make each of your primary keys a unique key, instead of default integers with the AUTO_INCREMENT flag. The reason why is because they are unique across every table, every database, and every server, allowing the easy merging of records from different databases and easy distribution of databases across multiple servers.

Using UUID in MySQL
Creating a UUID is as easy as using the MySql function UUID(). In CodeIgniter, you could do this with the following code snippet.

$this->db->set('id', 'UUID', FALSE);

This generates a 36 characters hexadecimal key (with 4 dashes included).

ac689561-f7c9-4f7e-be94-33c6c0fb0672

As you can see it has dashes in the string, using the CodeIgniter DB function will insert this in the database with the dashes, it still will work, it does not look clean. You could remove and convert the string to a 32-char key.

To do that I created this function in CodeIgniter, with the CodeIgniter UUID library.

function uuid_key {
        $this->load->library('uuid');
        //Output a v4 UUID 
        $id = $this->uuid->v4();
        $id = str_replace('-', '', $id);
        $this->db->set('id', $id, FALSE);
}

Now I have a 32-byte key,

ac689561f7c94f7ebe9433c6c0fb0672

we can create the table to store it in:

CREATE TABLE `type` (
  `id` char(32) NOT NULL,
  `name` varchar(126) CHARACTER SET latin1 NOT NULL,
  `lastmodified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

I could have done it into a BINARY(16) column – and convert my current 32-bit key into a 16 byte which would have made it faster, I suggest that you should do that if your database is growing very large. I had a need in keeping it 32 bytes, I already have data in the database with primary keys that been generated from scratch, I do not want to keep the old keys and continue with the UUID. That’s my problem.

Using Grocery Crud
Using this with Grocery Crud in CodeIgniter I had to create the uuid_callback that is called before insert.

    // uuid callback
    function uuid_callback($post_array){
        // Build the Grocery CRUD table and form
        $this->load->library('uuid');

        //Output a v4 UUID 
        $id = $this->uuid->v4();
        $id = str_replace('-', '', $id);

        $post_array['id'] = $id;
        return $post_array;
    }

Here is how I set up the Grocery Crud form, which calls the uuid_callback before insert.

public function type() {

$uuid = new grocery_CRUD();

$uuid->set_theme('datatables');

$uuid->set_table('type');
$uuid->callback_after_insert(array($this, 'insert_timestamp', 'type'));

$uuid->set_subject('Type');

$uuid->fields('name');

$uuid->fields('id','name');
$uuid->field_type('id','invisible');
$uuid->callback_before_insert(array($this,'uuid_callback'));

$uuid->columns('name');

$uuid->display_as('name','Name');

$output = $uuid->render();

// Load the views
$this->template->build('tables', $output);
}

The trick is that I have to define the primary key “id” as a field and then declare it as for hidden, before I call the function uuid_callback to get my UUID key.

Conclusions
This is just a quick way to generate UUIDs with CodeIgniter and Grocery Crud. I hope it helps you, and if you have feedback please add it below.

Share: