@@ -475,8 +475,7 @@ function baseSetRI( $DS = true ){ // DB Referential Integrity Control.
475
475
){ // MariaDB Check
476
476
$ MariaDB = true ;
477
477
}
478
- $ tmp = $ tmp ['version ' ];
479
- $ DBSV = VS2SV ($ tmp );
478
+ $ DBSV = VS2SV ($ tmp ['version ' ]);
480
479
if ( $ DS ){ // Set RI if possible.
481
480
$ QF = false ; // Query Flag.
482
481
$ RIE = false ; // RI Enable Flag.
@@ -529,68 +528,151 @@ function baseSetRI( $DS = true ){ // DB Referential Integrity Control.
529
528
}
530
529
}
531
530
if ( $ QF ){ // Query Info Schema for RI Information.
531
+ $ SE = true ; // Assume Success
532
532
$ sqlPfx = 'SELECT ' ;
533
- $ LPfx = '' ;
534
- $ RPfx = 'referenced_ ' ;
533
+ $ sqlIS = 'information_schema ' ;
534
+ $ SSfx = 'SCHEMA ' ;
535
535
if ( $ this ->DB_type == 'postgres ' ){
536
- $ LPfx = 'kcu. ' ;
537
- $ RPfx = 'ccu. ' ;
538
- $ sqlPfx .= $ LPfx . 'COLUMN_NAME, ' . $ RPfx
539
- . 'COLUMN_NAME AS REFERENCED_COLUMN_NAME FROM '
540
- . 'information_schema.key_column_usage AS kcu JION '
541
- . ' information_schema.constraint_column_usage '
542
- . " AS ccu ON $ RPfx " . 'constraint_name = '
543
- . $ LPfx . 'constraint_name ' ;
544
- }else {
545
- $ sqlPfx .= $ LPfx . 'COLUMN_NAME, ' . $ RPfx
546
- . 'COLUMN_NAME FROM '
547
- . 'information_schema.key_column_usage ' ;
536
+ $ SSfx = 'CATALOG ' ;
548
537
}
549
- $ sqlPfx .= " WHERE $ RPfx " . "table_name = 'event' "
550
- . " AND $ LPfx " . "TABLE_SCHEMA = ' " . $ this ->DB_name
551
- . "' AND $ LPfx " . "TABLE_NAME = ' " ;
552
- foreach ( $ RItbls as $ val ){
553
- $ EPfx = "$ EMPfx$ val " ;
554
- $ Cval = $ RIcl [$ val ];
555
- $ sql = "$ sqlPfx$ val' AND $ LPfx "
556
- . "CONSTRAINT_NAME = ' "
557
- . $ Cval . "' " ;
558
- DumpSQL ($ sql , 3 );
559
- $ rs = $ this ->DB ->Execute ($ sql );
560
- if (
561
- $ rs != false && $ this ->baseErrorMessage () == ''
562
- ){ // Error Check
563
- if ( $ rs ->RecordCount () > 0 ){
564
- $ tmp = '' ;
565
- if ( $ val == 'acid_ag_alert ' ){
566
- $ tmp = 'ag_ ' ;
538
+ $ sql = $ sqlPfx . 'CONSTRAINT_NAME, UPDATE_RULE, '
539
+ . 'DELETE_RULE FROM ' . $ sqlIS
540
+ . '.referential_constraints WHERE '
541
+ . "CONSTRAINT_ $ SSfx = ' " . $ this ->DB_name . "' " ;
542
+ DumpSQL ($ sql , 3 );
543
+ $ rs = $ this ->DB ->Execute ($ sql );
544
+ if (
545
+ $ rs != false && $ this ->baseErrorMessage () == ''
546
+ ){ // Error Check
547
+ if ( $ rs ->RecordCount () == DB_RICC ){
548
+ $ tmp = array_values ($ RIcl );
549
+ while ( !$ rs ->EOF ){
550
+ $ myrow = $ rs ->fields ;
551
+ if (
552
+ !in_array ($ myrow [0 ], $ tmp )
553
+ || $ myrow [1 ] != $ myrow [2 ]
554
+ || $ myrow [1 ] != 'CASCADE '
555
+ ){
556
+ $ RSC = true ; // Restructure
557
+ break ;
567
558
}
568
- // RI setup in DB table, Verify Structure.
569
- while ( !$ rs ->EOF ){
570
- $ myrow = $ rs ->fields ;
571
- $ myrow [0 ] = preg_replace (
572
- '/^ ' . $ tmp . '/ ' , '' , $ myrow [0 ]
573
- );
574
- if ( $ myrow [0 ] != $ myrow [1 ] ){
575
- // @codeCoverageIgnoreStart
576
- $ rs ->Close (); // Corrupt Structure.
577
- $ RSC = true ; // Restructure
578
- break 2 ;
579
- // @codeCoverageIgnoreEnd
559
+ $ rs ->MoveNext ();
560
+ }
561
+ $ rs ->Close ();
562
+ }else {
563
+ $ RSC = true ; // Restructure
564
+ }
565
+ }else { // Transient DB Error.
566
+ // @codeCoverageIgnoreStart
567
+ KML ($ EPfx . 'access error. ' , 3 );
568
+ $ SE = false ; // Failure
569
+ // @codeCoverageIgnoreEnd
570
+ }
571
+ if ( $ SE && !$ RSC ){
572
+ $ tmp = '' ;
573
+ if ( $ this ->DB_class == 1 ){
574
+ $ tmp = ', referenced_COLUMN_NAME ' ;
575
+ }
576
+ $ sqlt = $ sqlPfx . "COLUMN_NAME $ tmp FROM $ sqlIS "
577
+ . ".key_column_usage WHERE TABLE_ $ SSfx = ' "
578
+ . $ this ->DB_name . "' AND TABLE_NAME = ' " ;
579
+ foreach ( $ RItbls as $ val ){
580
+ $ EPfx = "$ EMPfx$ val " ;
581
+ $ Cval = $ RIcl [$ val ];
582
+ $ sql = "$ sqlt$ val' AND CONSTRAINT_NAME = ' "
583
+ . $ Cval . "' " ;
584
+ DumpSQL ($ sql , 3 );
585
+ $ rs = $ this ->DB ->Execute ($ sql );
586
+ if (
587
+ $ rs != false
588
+ && $ this ->baseErrorMessage () == ''
589
+ ){ // Error Check
590
+ if ( $ rs ->RecordCount () > 0 ){
591
+ $ RCN = array ();
592
+ if ( $ this ->DB_type == 'postgres ' ){
593
+ $ sql2 = $ sqlPfx . 'COLUMN_NAME '
594
+ . " FROM $ sqlIS "
595
+ . '.constraint_column_usage WHERE '
596
+ . "TABLE_ $ SSfx = ' "
597
+ . $ this ->DB_name . "' AND "
598
+ . "CONSTRAINT_NAME = ' " . $ Cval
599
+ . "' " ;
600
+ DumpSQL ($ sql2 , 3 );
601
+ $ rs2 = $ this ->DB ->Execute ($ sql2 );
602
+ if (
603
+ $ rs2 != false
604
+ && $ this ->baseErrorMessage ()
605
+ == ''
606
+ ){ // Error Check
607
+ if ( $ rs2 ->RecordCount () > 0 ){
608
+ while ( !$ rs2 ->EOF ){
609
+ $ myrow = $ rs2 ->fields ;
610
+ array_push (
611
+ $ RCN , $ myrow [0 ]
612
+ );
613
+ $ rs2 ->MoveNext ();
614
+ }
615
+ $ rs2 ->Close ();
616
+ }else {
617
+ $ RSC = true ; // Restructure
618
+ }
619
+ }else { // Transient DB Error.
620
+ // @codeCoverageIgnoreStart
621
+ KML ($ EPfx . 'access error. ' , 3 );
622
+ $ SE = false ; // Failure
623
+ break ;
624
+ // @codeCoverageIgnoreEnd
625
+ }
626
+ }
627
+ $ tmp = '' ;
628
+ if ( $ val == 'acid_ag_alert ' ){
629
+ $ tmp = 'ag_ ' ;
580
630
}
581
- $ rs ->MoveNext ();
631
+ // RI setup in DB table, Verify
632
+ // Structure.
633
+ while ( !$ rs ->EOF ){
634
+ $ myrow = $ rs ->fields ;
635
+ $ myrow [0 ] = preg_replace (
636
+ '/^ ' . $ tmp . '/ ' , '' ,
637
+ $ myrow [0 ]
638
+ );
639
+ $ tmp2 = count ($ myrow );
640
+ if ( $ this ->DB_class == 1 ){
641
+ if (
642
+ $ tmp2 < 2
643
+ || $ myrow [0 ] != $ myrow [1 ]
644
+ ){
645
+ // @codeCoverageIgnoreStart
646
+ $ rs ->Close (); // Corrupt Structure.
647
+ $ RSC = true ; // Restructure
648
+ break 2 ;
649
+ // @codeCoverageIgnoreEnd
650
+ }
651
+ }else {
652
+ if (
653
+ !in_array ($ myrow [0 ], $ RCN )
654
+ ){
655
+ // @codeCoverageIgnoreStart
656
+ $ rs ->Close (); // Corrupt Structure.
657
+ $ RSC = true ; // Restructure
658
+ break 2 ;
659
+ // @codeCoverageIgnoreEnd
660
+ }
661
+ }
662
+ $ rs ->MoveNext ();
663
+ }
664
+ $ rs ->Close ();
665
+ }else { // RI Not setup in DB table.
666
+ $ RSC = true ; // Restructure
667
+ break ;
582
668
}
583
- $ rs ->Close ();
584
- }else { // RI Not setup in DB table.
585
- $ RSC = true ; // Restructure
669
+ }else { // Transient DB Error.
670
+ // @codeCoverageIgnoreStart
671
+ KML ($ EPfx . 'access error. ' , 3 );
672
+ $ SE = false ; // Failure
586
673
break ;
674
+ // @codeCoverageIgnoreEnd
587
675
}
588
- }else { // Transient DB Error.
589
- // @codeCoverageIgnoreStart
590
- KML ($ EPfx . 'access error. ' , 3 );
591
- $ SE = false ; // Failure
592
- break ;
593
- // @codeCoverageIgnoreEnd
594
676
}
595
677
}
596
678
if ( $ RSC ){ // Clear DB RI Structure
@@ -655,19 +737,24 @@ function baseSetRI( $DS = true ){ // DB Referential Integrity Control.
655
737
foreach ( $ RItbls as $ val ){
656
738
$ EPfx = "$ EMPfx$ val " ;
657
739
$ Cval = $ RIcl [$ val ];
658
- $ sql = "ALTER TABLE $ val DROP $ tmp $ tmp2$ Cval " ;
659
- DumpSQL ($ sql , 3 );
660
- $ rs = $ this ->DB ->Execute ($ sql );
661
740
if (
662
- $ rs != false && $ this ->baseErrorMessage () == ''
663
- ){ // Error Check
664
- $ rs ->Close ();
665
- KML ($ EPfx . 'RI disabled. ' , 3 );
666
- }else { // Transient DB Error.
667
- // @codeCoverageIgnoreStart
668
- KML ($ EPfx . 'access error. ' , 3 );
669
- break ;
670
- // @codeCoverageIgnoreEnd
741
+ LoadedString ($ tmp2 )
742
+ || $ this ->baseFKeyExists ($ Cval )
743
+ ){
744
+ $ sql = "ALTER TABLE $ val DROP $ tmp $ tmp2$ Cval " ;
745
+ DumpSQL ($ sql , 3 );
746
+ $ rs = $ this ->DB ->Execute ($ sql );
747
+ if (
748
+ $ rs != false && $ this ->baseErrorMessage () == ''
749
+ ){ // Error Check
750
+ $ rs ->Close ();
751
+ KML ($ EPfx . 'RI disabled. ' , 3 );
752
+ }else { // Transient DB Error.
753
+ // @codeCoverageIgnoreStart
754
+ KML ($ EPfx . 'access error. ' , 3 );
755
+ break ;
756
+ // @codeCoverageIgnoreEnd
757
+ }
671
758
}
672
759
}
673
760
}
@@ -687,6 +774,60 @@ function baseGetRI ( ){
687
774
return $ Ret ;
688
775
}
689
776
777
+ function baseFKeyExists ( $ key = '' ){
778
+ // Returns true if RI is enabled and the RI Foreign Key exists in the
779
+ // DB structure, false otherwise.
780
+ GLOBAL $ use_referential_integrity , $ BCR ;
781
+ $ EMPfx = __FUNCTION__ . ': ' ;
782
+ $ Ret = false ; // Return Value
783
+ $ RIF = false ; // Referential Integrity Flag.
784
+ // @codeCoverageIgnoreStart
785
+ if ( isset ($ BCR ) && is_object ($ BCR ) ){
786
+ $ RIF = $ BCR ->GetCap ('BASE_SSRI ' );
787
+ }else {
788
+ if ( intval ($ use_referential_integrity ) == 1 ){
789
+ $ RIF = true ;
790
+ }
791
+ }
792
+ // @codeCoverageIgnoreEnd
793
+ if ( $ RIF && $ this ->baseisDBUp (true ) && LoadedString ($ key ) ){
794
+ $ SE = false ; // Step Execution Flag Assume Failure.
795
+ $ sqlPfx = 'SELECT ' ;
796
+ $ sqlIS = 'information_schema ' ;
797
+ $ SSfx = 'SCHEMA ' ;
798
+ if ( $ this ->DB_type == 'postgres ' ){
799
+ $ SSfx = 'CATALOG ' ;
800
+ }
801
+ $ sql = $ sqlPfx . 'CONSTRAINT_NAME, TABLE_NAME FROM ' . $ sqlIS
802
+ . '.table_constraints WHERE '
803
+ . "CONSTRAINT_ $ SSfx = ' " . $ this ->DB_name
804
+ . "' AND CONSTRAINT_TYPE = 'FOREIGN KEY' " ;
805
+ DumpSQL ($ sql , 3 );
806
+ $ rs = $ this ->DB ->Execute ($ sql );
807
+ if (
808
+ $ rs != false && $ this ->baseErrorMessage () == ''
809
+ && $ rs ->RecordCount () == DB_RICC
810
+ ){ // Error Check
811
+ while ( !$ rs ->EOF ){
812
+ $ myrow = $ rs ->fields ;
813
+ if ( $ myrow [0 ] == $ key ){
814
+ $ SE = true ; // Key Exists.
815
+ break ;
816
+ }
817
+ $ rs ->MoveNext ();
818
+ }
819
+ $ rs ->Close ();
820
+ }else { // Transient DB Error.
821
+ // @codeCoverageIgnoreStart
822
+ KML ($ EPfx . 'access error. ' , 3 );
823
+ $ SE = false ; // Failure
824
+ // @codeCoverageIgnoreEnd
825
+ }
826
+ $ Ret = $ SE ;
827
+ }
828
+ return $ Ret ;
829
+ }
830
+
690
831
function baseTSE ( $ table = '' ){ // Get Table Storage Engine.
691
832
$ EMPfx = __FUNCTION__ . ': ' ;
692
833
$ Ret = '' ;
0 commit comments