@@ -69,6 +69,13 @@ class Forge
69
69
* @var array
70
70
*/
71
71
protected $ primaryKeys = [];
72
+
73
+ /**
74
+ * List of foreign keys.
75
+ *
76
+ * @var type
77
+ */
78
+ protected $ foreignKeys = [];
72
79
73
80
/**
74
81
* Character set used.
@@ -330,7 +337,63 @@ public function addField($field)
330
337
}
331
338
332
339
//--------------------------------------------------------------------
340
+
341
+ /**
342
+ * Add Foreign Key
343
+ *
344
+ * @param array $field
345
+ *
346
+ * @return \CodeIgniter\Database\Forge
347
+ */
348
+ public function addForeignKey ($ fieldName = '' ,$ tableName = '' , $ tableField = '' , $ onUpdate = false , $ onDelete = false )
349
+ {
350
+
351
+ if ( ! isset ($ this ->fields [$ fieldName ]))
352
+ {
353
+ throw new \RuntimeException ('Field " ' .$ fieldName .'" not exist ' );
354
+ }
355
+
356
+ $ this ->foreignKeys [$ fieldName ] = [
357
+ 'table ' => $ tableName ,
358
+ 'field ' => $ tableField ,
359
+ 'onDelete ' => $ onDelete ,
360
+ 'onUpdate ' => $ onUpdate
361
+ ];
362
+
363
+
364
+ return $ this ;
365
+ }
333
366
367
+ //--------------------------------------------------------------------
368
+
369
+ /**
370
+ * Foreign Key Drop
371
+ *
372
+ * @param string $table Table name
373
+ * @param string $foreign_name Foreign name
374
+ *
375
+ * @return bool
376
+ */
377
+ public function dropForeignKey ($ table , $ foreign_name )
378
+ {
379
+
380
+ $ sql = sprintf ($ this ->dropConstraintStr ,$ this ->db ->escapeIdentifiers ($ this ->db ->DBPrefix .$ table ),$ this ->db ->escapeIdentifiers ($ this ->db ->DBPrefix .$ foreign_name ));
381
+
382
+ if ($ sql === false )
383
+ {
384
+ if ($ this ->db ->DBDebug )
385
+ {
386
+ throw new DatabaseException ('This feature is not available for the database you are using. ' );
387
+ }
388
+
389
+ return false ;
390
+ }
391
+
392
+ return $ this ->db ->query ($ sql );
393
+ }
394
+
395
+ //--------------------------------------------------------------------
396
+
334
397
/**
335
398
* Create Table
336
399
*
@@ -425,8 +488,10 @@ protected function _createTable($table, $if_not_exists, $attributes)
425
488
$ columns [$ i ] = ($ columns [$ i ]['_literal ' ] !== false ) ? "\n\t" . $ columns [$ i ]['_literal ' ] : "\n\t" . $ this ->_processColumn ($ columns [$ i ]);
426
489
}
427
490
428
- $ columns = implode (', ' , $ columns )
429
- . $ this ->_processPrimaryKeys ($ table );
491
+ $ columns = implode (', ' , $ columns );
492
+
493
+ $ columns .= $ this ->_processPrimaryKeys ($ table );
494
+ $ columns .= $ this ->_processForeignKeys ($ table );
430
495
431
496
// Are indexes created from within the CREATE TABLE statement? (e.g. in MySQL)
432
497
if ($ this ->createTableKeys === true )
@@ -472,11 +537,12 @@ protected function _createTableAttributes($attributes)
472
537
*
473
538
* @param string $table_name Table name
474
539
* @param bool $if_exists Whether to add an IF EXISTS condition
540
+ * @param bool $cascade Whether to add an CASCADE condition
475
541
*
476
542
* @return mixed
477
543
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
478
544
*/
479
- public function dropTable ($ table_name , $ if_exists = false )
545
+ public function dropTable ($ table_name , $ if_exists = false , $ cascade = false )
480
546
{
481
547
if ($ table_name === '' )
482
548
{
@@ -488,13 +554,14 @@ public function dropTable($table_name, $if_exists = false)
488
554
return false ;
489
555
}
490
556
557
+
491
558
// If the prefix is already starting the table name, remove it...
492
559
if (! empty ($ this ->db ->DBPrefix ) && strpos ($ table_name , $ this ->db ->DBPrefix ) === 0 )
493
560
{
494
561
$ table_name = substr ($ table_name , strlen ($ this ->db ->DBPrefix ));
495
562
}
496
563
497
- if (($ query = $ this ->_dropTable ($ this ->db ->DBPrefix . $ table_name , $ if_exists )) === true )
564
+ if (($ query = $ this ->_dropTable ($ this ->db ->DBPrefix . $ table_name , $ if_exists, $ cascade )) === true )
498
565
{
499
566
return true ;
500
567
}
@@ -523,10 +590,11 @@ public function dropTable($table_name, $if_exists = false)
523
590
*
524
591
* @param string $table Table name
525
592
* @param bool $if_exists Whether to add an IF EXISTS condition
593
+ * @param bool $cascade Whether to add an CASCADE condition
526
594
*
527
595
* @return string
528
596
*/
529
- protected function _dropTable ($ table , $ if_exists )
597
+ protected function _dropTable ($ table , $ if_exists, $ cascade )
530
598
{
531
599
$ sql = 'DROP TABLE ' ;
532
600
@@ -545,7 +613,9 @@ protected function _dropTable($table, $if_exists)
545
613
}
546
614
}
547
615
548
- return $ sql . ' ' . $ this ->db ->escapeIdentifiers ($ table );
616
+ $ sql = $ sql . ' ' . $ this ->db ->escapeIdentifiers ($ table );
617
+
618
+ return $ sql ;
549
619
}
550
620
551
621
//--------------------------------------------------------------------
@@ -1076,6 +1146,38 @@ protected function _processIndexes($table)
1076
1146
}
1077
1147
1078
1148
//--------------------------------------------------------------------
1149
+ /**
1150
+ * Process foreign keys
1151
+ *
1152
+ * @param string $table Table name
1153
+ *
1154
+ * @return string
1155
+ */
1156
+ protected function _processForeignKeys ($ table ) {
1157
+ $ sql = '' ;
1158
+
1159
+ $ allowActions = array ('CASCADE ' ,'SET NULL ' ,'NO ACTION ' ,'RESTRICT ' ,'SET DEFAULT ' );
1160
+
1161
+ if (count ($ this ->foreignKeys ) > 0 ){
1162
+ foreach ($ this ->foreignKeys as $ field => $ fkey ) {
1163
+ $ name_index = $ table .'_ ' .$ field .'_foreign ' ;
1164
+
1165
+ $ sql .= ", \n\tCONSTRAINT " . $ this ->db ->escapeIdentifiers ($ name_index )
1166
+ . ' FOREIGN KEY( ' . $ this ->db ->escapeIdentifiers ($ field ) . ') REFERENCES ' .$ this ->db ->escapeIdentifiers ($ this ->db ->DBPrefix .$ fkey ['table ' ]).' ( ' .$ this ->db ->escapeIdentifiers ($ fkey ['field ' ]).') ' ;
1167
+
1168
+ if ($ fkey ['onDelete ' ] !== false && in_array ($ fkey ['onDelete ' ], $ allowActions )){
1169
+ $ sql .= " ON DELETE " .$ fkey ['onDelete ' ];
1170
+ }
1171
+
1172
+ if ($ fkey ['onUpdate ' ] !== false && in_array ($ fkey ['onUpdate ' ], $ allowActions )){
1173
+ $ sql .= " ON UPDATE " .$ fkey ['onDelete ' ];
1174
+ }
1175
+
1176
+ }
1177
+ }
1178
+
1179
+ return $ sql ;
1180
+ }
1079
1181
//--------------------------------------------------------------------
1080
1182
1081
1183
/**
0 commit comments