Welcome Guest, Not a member yet? Register   Sign In
Multiple primary keys for protected $primaryKey
#1

(This post was last modified: 10-05-2019, 09:56 AM by bustersg.)

PHP Code:
protected $primaryKey 'priKey1'// normal for a table having 1 pri key 

I have a combination of 3 pri key
Then how should I declare it?

PHP Code:
protected $primaryKey 'priKey1, priKey2, priKey3'// don't think this is correct
protected $primaryKey = array('priKey1''priKey2''priKey3'); // ci4 online help document does not show it to be this way 
Reply
#2

I believe that any given SQL table can have only one primary key though the key may consist of several columns. In the multi-column case it would still only have one name which would be the value assigned to $primaryKey.
Reply
#3

dave friend is correct a table can only have one primary key.
But it can have multiple other keys for indexing etc;
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#4

It's a good question if you're asking how to set up Model::primaryKey to support a multi-column primary key. The answer is: you cannot. The value assigned to Model::primaryKey must be the name of a single column. However, the column used need not be the actual PRIMARY key for the table. The property can use any column, but that column should contain unique values and ideally be indexed.

You could probably extend the Model class to handle a composite primary key. That would require overriding five or six functions to achieve the same functionality.

One of the best features of CI4 is its use of namespace and autoloading which makes it much easier to extend any class.
Reply
#5

Any idea how to manage a primary key composed by multiple columns?

I think could be very useful for some data models, like for N-M auxiliary tables
Reply
#6

any solution for this case?
Reply
#7

I don't know if this is possible but, can you create a column in table that concat 2 field?
If this is possible, in that case, the pk in the mysql table remain the same, but in ci4, you can point the pk to the composite field that you create.
Reply
#8

Has anyone worked on this? I'm thinking of modifying Model::doUpdate and adding a test for is_array($id) and if it is then I'll push that into a foreach of where statements.
Reply
#9

Here's my first stab at doing an override in doInsert and doUpdate.

Anyone have any feedback?
 
PHP Code:
protected function doUpdate($id NULL$data NULL)
 : 
bool {
 
$escape $this->escape;
 
$this->escape = [];

 
$builder $this->builder();

 if (
$id) {
 if (
is_array($id) && is_array($this->primaryKey)) {
 for (
$index 0$index count($this->primaryKey); $index++) {
 
$primary_key $this->primaryKey[$index];
 
$value $id[$primary_key];
 
$full_column sprintf("%s.%s"$this->table$primary_key);
 
$builder $builder->whereIn($full_column, array($value));
 }
 } else {
 
$builder $builder->whereIn($this->table '.' $this->primaryKey$id);
 }
 }

 
// Must use the set() method to ensure to set the correct escape flag
 
foreach ($data as $key => $val) {
 
$builder->set($key$val$escape[$key] ?? NULL);
 }

 return 
$builder->update();
 }

 protected function 
doInsert(array $data)
 {
 
$escape $this->escape;
 
$this->escape = [];

 
// Require non empty primaryKey when
 // not using auto-increment feature

 
if (!$this->useAutoIncrement) {
 if (
is_array($this->primaryKey)) {
 foreach (
$this->primaryKey as $primary_key) {
 if (empty(
$data[$primary_key])) {
 throw 
DataException::forEmptyPrimaryKey('insert');
 }
 }
 } else {
 
/** @noinspection PhpIllegalArrayKeyTypeInspection */
 
if (!is_array($this->primaryKey) && empty($data[$this->primaryKey])) {
 throw 
DataException::forEmptyPrimaryKey('insert');
 }
 }
 }

 
$builder $this->builder();

 
// Must use the set() method to ensure to set the correct escape flag
 
foreach ($data as $key => $val) {
 
$builder->set($key$val$escape[$key] ?? NULL);
 }

 
$result $builder->insert();

 
// If insertion succeeded then save the insert ID
 
if ($result) {
 if (
is_array($this->primaryKey)) {
 return 
FALSE;
 } else {
 
$this->insertID = !$this->useAutoIncrement $data[$this->primaryKey] : $this->db->insertID();
 }
 }

 return 
$result;
 } 
Reply




Theme © iAndrew 2016 - Forum software by © MyBB