@@ -209,6 +209,52 @@ function mixinMigration(PostgreSQL) {
209
209
} ) ;
210
210
} ;
211
211
212
+ PostgreSQL . prototype . isActualIndexes = function ( modelName , callback ) {
213
+ debug ( 'modelName %j' , modelName ) ;
214
+ const self = this ;
215
+
216
+ const model = self . _models [ modelName ] ;
217
+
218
+ self . showIndexes ( modelName , ( err , asIsModelIndexes ) => {
219
+ if ( err ) return callback ( err ) ;
220
+
221
+ debug ( 'asIsModelIndexes %j' , asIsModelIndexes ) ;
222
+
223
+ const asIsIndexes = generateAsIsIndexCompare ( asIsModelIndexes ) ;
224
+
225
+ const toBeIndexes = generateToBeIndexCompare ( model . settings . indexes ) ;
226
+ debug ( 'toBeIndexes' , toBeIndexes ) ;
227
+
228
+ // Look for Differences
229
+ let differenceFound = false ;
230
+ for ( const name in toBeIndexes ) {
231
+ debug ( 'name %j' , name ) ;
232
+ if ( asIsIndexes [ name ] !== toBeIndexes [ name ] ) {
233
+ debug ( 'asIsIndexes[name] %j' , asIsIndexes [ name ] ) ;
234
+ debug ( 'toBeIndexes[name] %j' , toBeIndexes [ name ] ) ;
235
+ differenceFound = true ;
236
+ break ;
237
+ }
238
+ }
239
+
240
+ if ( ! differenceFound ) {
241
+ for ( const name in asIsIndexes ) {
242
+ debug ( 'name %j' , name ) ;
243
+ if ( ! toBeIndexes [ name ] ) {
244
+ debug ( 'name not found in toBe %j' , name ) ;
245
+ differenceFound = true ;
246
+ break ;
247
+ }
248
+ }
249
+ }
250
+ if ( differenceFound ) {
251
+ debug ( 'differenceFound for %j' , modelName ) ;
252
+ }
253
+
254
+ callback ( null , ! differenceFound ) ;
255
+ } ) ;
256
+ } ;
257
+
212
258
PostgreSQL . prototype . getAddModifyColumns = function ( model , actualFields ) {
213
259
let sql = [ ] ;
214
260
const self = this ;
@@ -757,13 +803,16 @@ function mixinMigration(PostgreSQL) {
757
803
function isCaseInsensitiveEqual ( val1 , val2 ) {
758
804
return val1 . toLowerCase ( ) === val2 . toLowerCase ( ) ;
759
805
}
806
+
760
807
/*!
761
808
* Case insensitive comparison of object properties
762
809
* @param {Object } properties
763
810
* @param {String } name
764
811
*/
765
812
function hasColumnProperty ( properties , name ) {
766
- if ( ! name ) { return false ; }
813
+ if ( ! name ) {
814
+ return false ;
815
+ }
767
816
768
817
return ( Object . keys ( properties )
769
818
. map ( function ( k ) {
@@ -870,17 +919,16 @@ function mixinMigration(PostgreSQL) {
870
919
}
871
920
872
921
PostgreSQL . prototype . addIndexes = function ( model , actualIndexes , options , cb ) {
922
+
873
923
const self = this ;
924
+
874
925
const m = self . _models [ model ] ;
875
- const propNames = Object . keys ( m . properties ) . filter ( function ( name ) {
876
- return ! ! m . properties [ name ] ;
877
- } ) ;
878
- const indexNames = m . settings . indexes && Object . keys ( m . settings . indexes ) . filter ( function ( name ) {
879
- return ! ! m . settings . indexes [ name ] ;
880
- } ) || [ ] ;
926
+
927
+ const schema = self . escapeName ( self . schema ( model ) || 'public' ) ;
928
+
881
929
const sql = [ ] ;
930
+
882
931
const ai = { } ;
883
- const propNameRegEx = new RegExp ( '^' + self . table ( model ) + '_([^_]+)_idx' ) ;
884
932
885
933
if ( actualIndexes ) {
886
934
actualIndexes . forEach ( function ( i ) {
@@ -890,75 +938,52 @@ function mixinMigration(PostgreSQL) {
890
938
}
891
939
} ) ;
892
940
}
893
- const aiNames = Object . keys ( ai ) ;
894
-
895
- // remove indexes
896
- aiNames . forEach ( function ( indexName ) {
897
- const schema = self . escapeName ( self . schema ( model ) || 'public' ) ;
898
- const i = ai [ indexName ] ;
899
- let propName = propNameRegEx . exec ( indexName ) ;
900
- let si ; // index definition from model schema
941
+ debug ( 'ai %j' , ai ) ;
901
942
902
- if ( i . primary || ( m . properties [ indexName ] && self . id ( model , indexName ) ) ) return ;
943
+ const asIsIndexes = generateAsIsIndexCompare ( actualIndexes ) ;
944
+ debug ( 'asIsIndexes %j' , asIsIndexes ) ;
903
945
904
- propName = propName && self . propertyName ( model , propName [ 1 ] ) || null ;
905
- if ( ! ( indexNames . indexOf ( indexName ) > - 1 ) && ! ( propName && m . properties [ propName ] &&
906
- m . properties [ propName ] . index ) ) {
907
- sql . push ( 'DROP INDEX ' + schema + '.' + self . escapeName ( indexName ) ) ;
908
- } else {
909
- // The index was found, verify that database matches what we're expecting.
910
- // first: check single column indexes.
911
- if ( propName ) {
912
- // If this property has an index definition, verify that it matches
913
- if ( m . properties [ propName ] && ( si = m . properties [ propName ] . index ) ) {
914
- if (
915
- ( typeof si === 'object' ) &&
916
- ! ( ( ! si . type || si . type === ai [ indexName ] . type ) && ( ! si . unique || si . unique === ai [ indexName ] . unique ) )
917
- ) {
918
- // Drop the index if the type or unique differs from the actual table
919
- sql . push ( 'DROP INDEX ' + schema + '.' + self . escapeName ( indexName ) ) ;
920
- delete ai [ indexName ] ;
921
- }
922
- }
923
- } else {
924
- // second: check other indexes
925
- si = normalizeIndexDefinition ( m . settings . indexes [ indexName ] ) ;
926
-
927
- let identical =
928
- ( ! si . type || si . type === i . type ) && // compare type
929
- ( ( si . options && ! ! si . options . unique ) === i . unique ) ; // compare unique
930
-
931
- // if this is a multi-column query, verify that the order matches
932
- const siKeys = Object . keys ( si . keys ) ;
933
- if ( identical && siKeys . length > 1 ) {
934
- if ( siKeys . length !== i . keys . length ) {
935
- // lengths differ, obviously non-matching
936
- identical = false ;
937
- } else {
938
- siKeys . forEach ( function ( propName , iter ) {
939
- identical = identical && self . column ( model , propName ) === i . keys [ iter ] ;
940
- } ) ;
941
- }
942
- }
946
+ const toBeIndexes = generateToBeIndexCompare ( m . settings . indexes ) ;
947
+ debug ( 'toBeIndexes %j' , toBeIndexes ) ;
943
948
944
- if ( ! identical ) {
945
- sql . push ( 'DROP INDEX ' + schema + '.' + self . escapeName ( indexName ) ) ;
946
- delete ai [ indexName ] ;
947
- }
948
- }
949
+ for ( const name in asIsIndexes ) {
950
+ debug ( 'name %j' , name ) ;
951
+ if ( asIsIndexes [ name ] !== toBeIndexes [ name ] ) {
952
+ debug ( 'asIsIndexes[name] %j' , asIsIndexes [ name ] ) ;
953
+ debug ( 'toBeIndexes[name] %j' , toBeIndexes [ name ] ) ;
954
+ sql . push ( 'DROP INDEX ' + schema + '.' + self . escapeName ( name ) ) ;
955
+ delete ai [ name ] ;
949
956
}
957
+ }
958
+ debug ( 'sql after drop indexes %j' , sql ) ;
959
+ debug ( 'ai after drop indexes %j' , ai ) ;
960
+
961
+ const propNames = Object . keys ( m . properties ) . filter ( function ( name ) {
962
+ return ! ! m . properties [ name ] ;
950
963
} ) ;
964
+ debug ( 'propNames %j' , propNames ) ;
965
+
966
+ const indexNames =
967
+ ( m . settings . indexes &&
968
+ Object . keys ( m . settings . indexes ) . filter ( function ( name ) {
969
+ return ! ! m . settings . indexes [ name ] ;
970
+ } ) ) ||
971
+ [ ] ;
972
+ debug ( 'indexNames %j' , indexNames ) ;
951
973
952
974
// add single-column indexes
953
975
propNames . forEach ( function ( propName ) {
976
+ debug ( 'propName %j' , propName ) ;
954
977
const i = m . properties [ propName ] . index ;
955
978
if ( ! i ) {
956
979
return ;
957
980
}
981
+ debug ( 'i %j' , i ) ;
958
982
959
983
// The index name used should match the default naming scheme
960
984
// by postgres: <column>_<table>_idx
961
985
const iName = [ self . table ( model ) , self . column ( model , propName ) , 'idx' ] . join ( '_' ) ;
986
+ debug ( 'iName %j' , iName ) ;
962
987
963
988
const found = ai [ iName ] ; // && ai[iName].info;
964
989
if ( ! found ) {
@@ -972,12 +997,22 @@ function mixinMigration(PostgreSQL) {
972
997
kind = i . kind ;
973
998
}
974
999
975
- if ( ! kind && ! type && typeof i === 'object' || i . unique && i . unique === true ) {
1000
+ if ( ( ! kind && ! type && typeof i === 'object' ) || ( i . unique && i . unique === true ) ) {
976
1001
kind = ' UNIQUE ' ;
977
1002
}
978
1003
979
- sql . push ( 'CREATE ' + kind + ' INDEX ' + self . escapeName ( iName ) + ' ON ' + self . tableEscaped ( model ) +
980
- type + ' ( ' + pName + ' )' ) ;
1004
+ sql . push (
1005
+ 'CREATE ' +
1006
+ kind +
1007
+ ' INDEX ' +
1008
+ self . escapeName ( iName ) +
1009
+ ' ON ' +
1010
+ self . tableEscaped ( model ) +
1011
+ type +
1012
+ ' ( ' +
1013
+ pName +
1014
+ ' )'
1015
+ ) ;
981
1016
}
982
1017
} ) ;
983
1018
@@ -988,9 +1023,11 @@ function mixinMigration(PostgreSQL) {
988
1023
if ( ! found ) {
989
1024
i = normalizeIndexDefinition ( i ) ;
990
1025
const iName = self . escapeName ( indexName ) ;
991
- const columns = i . keys . map ( function ( key ) {
992
- return self . escapeName ( self . column ( model , key [ 0 ] ) ) + ( key [ 1 ] ? ' ' + key [ 1 ] : '' ) ;
993
- } ) . join ( ', ' ) ;
1026
+ const columns = i . keys
1027
+ . map ( function ( key ) {
1028
+ return self . escapeName ( self . column ( model , key [ 0 ] ) ) + ( key [ 1 ] ? ' ' + key [ 1 ] : '' ) ;
1029
+ } )
1030
+ . join ( ', ' ) ;
994
1031
995
1032
let type = '' ;
996
1033
let kind = '' ;
@@ -1005,8 +1042,9 @@ function mixinMigration(PostgreSQL) {
1005
1042
kind = ' UNIQUE ' ;
1006
1043
}
1007
1044
1008
- sql . push ( 'CREATE ' + kind + ' INDEX ' + iName + ' ON ' + self . tableEscaped ( model ) +
1009
- type + ' ( ' + columns + ')' ) ;
1045
+ sql . push (
1046
+ 'CREATE ' + kind + ' INDEX ' + iName + ' ON ' + self . tableEscaped ( model ) + type + ' ( ' + columns + ')'
1047
+ ) ;
1010
1048
}
1011
1049
} ) ;
1012
1050
0 commit comments