One problem that I am facing is having many queries with similar select statements but different join/where statements.
Below is an example of a code that I am working on via CodeIgniter. What I normally do is make one function, get(), that accepts an array of random keys/values. Depending on what keys/values are passed, it will generate and run the appropriate query. Now, I am wondering is this a good way of doing things? Because as you can see, this function becomes more and more complex. Initially, I had a bunch of functions such as get_all(), get_only_lessons(), etc but it becomes kinda annoying having to repeat the same set of code with one or two lines that are different.
My question is what is the best way with dealing with this problem.
function get($param = NULL)
{
/*
SELECT m.id AS id, CAST(m.order_number AS SIGNED) AS order_number, m.name AS name, m.permalink as permalink,
m.suplesson_id as suplesson_id, CAST(sm.order_number AS SIGNED) AS suplesson_order_number
FROM lessons m
JOIN courses c ON m.course_id = c.id
LEFT JOIN lessons sm ON m.suplesson_id = sm.id
WHERE [various]
*/
$select = 'm.id AS id, CAST(m.order_number AS SIGNED) AS order_number, m.name AS name, m.permalink as permalink, ';
$select .= ' m.suplesson_id as suplesson_id';
if (isset($param['id']) || isset($param['suplesson_order_number']) || isset($param['permalink']))
$select .= ', CAST(sm.order_number AS SIGNED) AS suplesson_order_number ';
$this->db->select($select);
$this->db->from($this->table_name.' m');
$this->db->join($this->courses_table_name.' c', 'm.course_id = c.id');
if (isset($param['id']) || isset($param['suplesson_order_number']) || isset($param['permalink']))
$this->db->join($this->table_name.' sm', 'm.suplesson_id = sm.id', 'left');
// where clauses
if (isset($param['course_id']))
$this->db->where(array('c.id' => $param['course_id']));
if (isset($param['id']))
$this->db->where(array('m.id' => $param['id']));
if (isset($param['order_number']))
$this->db->where(array('m.order_number' => $param['order_number']));
if (isset($param['permalink']))
$this->db->like('m.permalink', $param['permalink'], 'none');
if (isset($param['suplesson_id']))
$this->db->where(array('m.suplesson_id' => $param['suplesson_id']));
if (isset($param['suplesson_order_number']))
$this->db->where(array('sm.order_number' => $param['suplesson_order_number']));
if (isset($param['NULL']))
$this->db->where('m.'.$param['NULL'].' IS NULL');
if (isset($param['NOT NULL']))
$this->db->where('m.'.$param['NOT NULL'].' IS NOT NULL');
$this->db->order_by('order_number');
// filter based on num_rows/offset
if (isset($param['id']) || isset($param['permalink']))
$this->db->limit(1);
if (isset($param['num_rows']) && isset($param['offset']))
$this->db->limit($param['num_rows'], $param['offset']);
$query = $this->db->get();
// return row if expecting 1 result
if (isset($param['id']) || isset($param['suplesson_order_number']) || isset($param['permalink']))
return ($query->num_rows() == 1) ? $query->row_array() : NULL;
return ($query->num_rows() > 0) ? $query->result_array() : NULL;
}
The usual way of running DB queries is to structure your model code to have multiple function calls, each one relating to one SQL statement, for example:
You might create a model class called User_model which contains all of the functions you need for reading/updating the user table, so in your controller you call down to the specific model function
It looks like you’re trying to construct one giant model function which checks various parameters in order to determine what SQL statement to run. This isn’t good design and doesn’t fit well with Codeignitors MVC model.
Instead, create a separate model for each table, then in each model create separate functions for each SQL operation you wish to run. Call these models from your controllers to get/update/delete data in your tables.