Class: Mkxms::Mssql::AdoptionScriptWriter

Inherits:
Object
  • Object
show all
Includes:
SqlStringManipulators, XMigra::MSSQLSpecifics
Defined in:
lib/mkxms/mssql/adoption_script_writer.rb

Defined Under Namespace

Classes: CheckConstraintAdoptionChecks, ForeignKeyAdoptionChecks, IndexAdoptionChecks, KeylikeConstraintAdoptionChecks, StatisticsAdoptionChecks, TableAdoptionChecks

Constant Summary

Constants included from SqlStringManipulators

SqlStringManipulators::MSSQL

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SqlStringManipulators

#bit_test, #boolean_desc, #dedent, #stresc, #strlit, #unquoted_identifier

Constructor Details

#initialize(db_expectations) ⇒ AdoptionScriptWriter

Returns a new instance of AdoptionScriptWriter.



14
15
16
17
18
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 14

def initialize(db_expectations)
  @db_expectations = db_expectations
  # Ex nihilo DB schema builder
  @xn_builder = XMigra::SchemaUpdater.new(@db_expectations.schema_dir)
end

Instance Attribute Details

#db_expectationsObject (readonly)

Returns the value of attribute db_expectations.



20
21
22
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 20

def db_expectations
  @db_expectations
end

Instance Method Details

#access_object_adoption_sql(type, qualified_name) ⇒ Object



1152
1153
1154
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 1152

def access_object_adoption_sql(type, qualified_name)
  "INSERT INTO [xmigra].[access_objects] ([type], [name]) VALUES (N'#{type}', #{strlit qualified_name});"
end

#adopt_indexes_sqlObject



1058
1059
1060
1061
1062
1063
1064
1065
1066
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 1058

def adopt_indexes_sql
  db_expectations.indexes.map do |index|
    index_builder = @xn_builder.indexes[index.name]
    IndexAdoptionChecks.new(index, method(:adoption_error_sql)).to_s +
    "\nINSERT INTO [xmigra].[indexes] ([IndexID], [name]) VALUES (%s, %s);" % [
      index_builder.id, index_builder.name
    ].map {|s| strlit(s)}
  end
end

#adopt_permissions_sqlObject



1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 1266

def adopt_permissions_sql
  table = 'expected_permissions'
  [
    # Create a temporary table
    dedent(%Q{
      CREATE TABLE [xmigra].[#{table}] (
        [state] CHAR(1) NOT NULL,
        [subject] NVARCHAR(150) NOT NULL,
        [permission] NVARCHAR(128) NOT NULL,
        [object_type] NVARCHAR(25) NOT NULL,
        [object_schema] NVARCHAR(150) NULL,
        [object] NVARCHAR(150) NULL,
        [column] NVARCHAR(150) NULL
      );
    }),
    # Insert permission rows into the table
    [].tap do |inserts|
      db_expectations.permissions.each do |pg|
        pg.permissions.each do |pmsn|
          state = case pg.action[0].downcase
          when 'g' then pmsn.grant_option? ? 'W' : 'G'
          else pg.action[0].upcase
          end
          nls = ->(s) {s.nil? ? 'NULL' : strlit(s)}
          row_values = [state, pg.subject, pmsn.name] + pmsn.object_id_parts
          inserts << dedent(%Q{
            INSERT INTO [xmigra].[#{table}] (state, subject, permission, object_type, object_schema, object, [column])
            VALUES (%s);
          } % row_values.map(&nls).join(', '))
        end
      end
    end.join("\n"),
    # Write an adoption error for each missing permission
    dedent(%Q{
      WITH
        PermissionTarget AS (
          SELECT
            0 AS "class",
            0 AS major_id,
            0 AS minor_id,
            'DATABASE' AS "class_desc",
            NULL AS "class_specifier",
            NULL AS "schema_name",
            NULL AS "object_name",
            NULL AS "column_name"
          UNION
          SELECT
            1,
            o.object_id,
            0,
            'OBJECT',
            NULL,
            s.name,
            o.name,
            NULL
          FROM sys.objects o
          JOIN sys.schemas s ON o.schema_id = s.schema_id
          UNION
          SELECT
            1,
            c.object_id,
            c.column_id,
            'COLUMN',
            NULL,
            s.name,
            o.name,
            c.name
          FROM sys.columns c
          JOIN sys.objects o ON c.object_id = o.object_id
          JOIN sys.schemas s ON o.schema_id = s.schema_id
          UNION
          SELECT
            3,
            s.schema_id,
            0,
            'SCHEMA',
            'SCHEMA',
            NULL,
            s.name,
            NULL
          FROM sys.schemas s
          UNION
          SELECT
            4,               -- class
            r.principal_id,  -- major_id
            0,               -- minor_id
            'ROLE',          -- class description
            'ROLE',          -- class specifier
            NULL,            -- schema_name
            r.name,          -- object_name
            NULL             -- column_name
          FROM sys.database_principals r
          WHERE r.type = 'R'
          UNION
          SELECT
            5,               -- class
            a.assembly_id,   -- major_id
            0,               -- minor_id
            'ASSEMBLY',      -- class description
            'ASSEMBLY',      -- class specifier
            NULL,            -- schema_name
            a.name,          -- object_name
            NULL             -- column_name
          FROM sys.assemblies a
          UNION
          SELECT
            6,               -- class
            t.user_type_id,  -- major_id
            0,               -- minor_id
            'TYPE',          -- class description
            'TYPE',          -- class specifier
            s.name,          -- schema_name
            t.name,          -- object_name
            NULL             -- column_name
          FROM sys.types t
          JOIN sys.schemas s ON t.schema_id = s.schema_id
          UNION
          SELECT
            10,                        -- class
            xsc.xml_collection_id,     -- major_id
            0,                         -- minor_id
            'XML_SCHEMA_COLLECTION',   -- class description
            'XML SCHEMA COLLECTION',   -- class specifier
            s.name,                    -- schema_name
            xsc.name,                  -- object_name
            NULL                       -- column_name
          FROM sys.xml_schema_collections xsc
          JOIN sys.schemas s ON xsc.schema_id = s.schema_id
        ),
        Permissions AS (
          SELECT
            p.state,
            QUOTENAME(pi.name) AS "subject",
            p.permission_name AS "permission",
            t.class_desc AS "object_type",
            QUOTENAME(t.schema_name) AS "object_schema",
            QUOTENAME(t.object_name) AS "object",
            QUOTENAME(t.column_name) AS "column"
          FROM sys.database_permissions p
          JOIN sys.database_principals pi ON p.grantee_principal_id = pi.principal_id
          JOIN PermissionTarget t 
            ON p.class = t.class 
            AND p.major_id = t.major_id
            AND p.minor_id = t.minor_id
          LEFT JOIN sys.database_principals grantor ON p.grantor_principal_id = grantor.principal_id
          AND (p.class <> 4 OR (
            SELECT dp.type FROM sys.database_principals dp
            WHERE dp.principal_id = p.major_id
          ) = 'R')
          AND (p.class <> 1 OR p.major_id IN (
            SELECT o.object_id FROM sys.objects o
          ))
        )
      INSERT INTO [xmigra].[adoption_errors] ([message])
      SELECT
        e.permission + N' is ' +
        CASE e.state
        WHEN 'G' THEN 
          CASE (
            SELECT p.state
            FROM Permissions p
            WHERE p.subject = e.subject
            AND p.permission = e.permission
            AND p.object_type = e.object_type
            AND COALESCE(p.object_schema, N'.') = COALESCE(e.object_schema, N'.')
            AND COALESCE(p.object, N'.') = COALESCE(e.object, N'.')
            AND COALESCE(p.[column], N'.') = COALESCE(e.[column], N'.')
          )
          WHEN 'W' THEN 'GRANTed with (unexpected) grant option to '
          ELSE N'not GRANTed to '
          END
        WHEN 'W' THEN N'not GRANTed (with grant option) to '
        WHEN 'D' THEN N'not DENYed to '
        WHEN 'R' THEN N'not REVOKEd from '
        END + e.subject + N' on ' + e.object_type +
        CASE 
        WHEN e.object_schema IS NULL THEN N''
        ELSE e.object_schema + N'.'
        END +
        CASE
        WHEN e.object IS NULL THEN N''
        ELSE e.object
        END +
        CASE
        WHEN e.[column] IS NULL THEN N''
        ELSE N' (' + e.[column] + N')'
        END + N'.'
      FROM (
        SELECT state, subject, permission, object_type, object_schema, object, [column]
        FROM [xmigra].[#{table}]
        EXCEPT
        SELECT 
          state COLLATE SQL_Latin1_General_CP1_CI_AS, 
          subject, 
          permission COLLATE SQL_Latin1_General_CP1_CI_AS, 
          object_type, 
          object_schema, 
          object, 
          [column]
        FROM Permissions
      ) e
    }),
    # Record adopted permissions
    db_expectations.permissions.map do |pg|
      pg.regular_permissions.map do |pmsn|
        "EXEC [xmigra].[ip_prepare_revoke] #{[pmsn.name, pmsn.target, pg.subject].map {|s| strlit(unquoted_identifier s)}.join(', ')};"
      end
    end.flatten.join("\n"),
    # Drop the temporary table
    "DROP TABLE [xmigra].[#{table}];",
  ]
end

#adopt_statistics_sqlObject



1142
1143
1144
1145
1146
1147
1148
1149
1150
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 1142

def adopt_statistics_sql
  db_expectations.statistics.map do |statistics|
    StatisticsAdoptionChecks.new(statistics, method(:adoption_error_sql)).to_s +
    "\nINSERT INTO [xmigra].[statistics] ([Name], [Columns]) VALUES (%s, %s);" % [
      statistics.name,
      statistics.columns.join(', ')
    ].map {|s| strlit(s)}
  end
end

#adopt_stored_procedures_sqlObject



1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 1195

def adopt_stored_procedures_sql
  db_expectations.procedures.map do |sproc|
    IndentedStringBuilder.dsl {
      puts "IF NOT EXISTS (%s)" do
        puts dedent %Q{
          SELECT * FROM sys.procedures p
          JOIN sys.schemas s ON p.schema_id = s.schema_id
          WHERE s.name = #{strlit(unquoted_identifier sproc.schema)}
          AND p.name = #{strlit(unquoted_identifier sproc.name)}
        }
      end
      puts "BEGIN"
      indented {
        puts adoption_error_sql "Stored procedure #{sproc.qualified_name} does not exist."
      }
      puts "END ELSE IF NOT EXISTS (%s)" do
        puts dedent %Q{
          SELECT * FROM sys.procedures p
          JOIN sys.schemas s ON p.schema_id = s.schema_id
          JOIN sys.sql_modules sql ON p.object_id = sql.object_id
          WHERE s.name = #{strlit(unquoted_identifier sproc.schema)}
          AND p.name = #{strlit(unquoted_identifier sproc.name)}
          AND #{definition_matches_by_hash('sql.definition', sproc.definition)}
        }
      end
      puts "BEGIN"
      indented {
        puts adoption_error_sql "Stored procedure #{sproc.qualified_name} does not have the expected definition."
      }
      puts "END;"
      puts access_object_adoption_sql(:PROCEDURE, sproc.qualified_name)
    }
  end
end

#adopt_udfs_sqlObject



1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 1230

def adopt_udfs_sql
  db_expectations.udfs.map do |udf|
    IndentedStringBuilder.dsl {
      puts "IF NOT EXISTS (%s)" do
        puts dedent %Q{
          SELECT * FROM sys.objects fn
          JOIN sys.schemas s ON fn.schema_id = s.schema_id
          WHERE s.name = #{strlit(unquoted_identifier udf.schema)}
          AND fn.name = #{strlit(unquoted_identifier udf.name)}
          AND fn.type IN ('FN', 'IF', 'TF')
        }
      end
      puts "BEGIN"
      indented {
        puts adoption_error_sql "Function #{udf.qualified_name} does not exist."
      }
      puts "END ELSE IF NOT EXISTS (%s)" do
        puts dedent %Q{
          SELECT * FROM sys.objects fn
          JOIN sys.schemas s ON fn.schema_id = s.schema_id
          JOIN sys.sql_modules sql ON fn.object_id = sql.object_id
          WHERE s.name = #{strlit(unquoted_identifier udf.schema)}
          AND fn.name = #{strlit(unquoted_identifier udf.name)}
          AND #{definition_matches_by_hash 'sql.definition', udf.definition}
        }
      end
      puts "BEGIN"
      indented {
        puts adoption_error_sql "Function #{udf.qualified_name} does not have the expected definition."
      }
      puts "END;"
      puts access_object_adoption_sql(:FUNCTION, udf.qualified_name)
    }
  end
end

#adopt_views_sqlObject



1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 1160

def adopt_views_sql
  db_expectations.views.map do |view|
    IndentedStringBuilder.dsl {
      puts "IF NOT EXISTS (%s)" do
        puts dedent %Q{
          SELECT * FROM sys.views v
          JOIN sys.schemas s ON v.schema_id = s.schema_id
          WHERE s.name = #{strlit(unquoted_identifier view.schema)}
          AND v.name = #{strlit(unquoted_identifier view.name)}
        }
      end
      puts "BEGIN"
      indented do
        puts adoption_error_sql "View #{view.qualified_name} does not exist."
      end
      puts "END ELSE IF NOT EXISTS (%s)" do
        puts dedent %Q{
          SELECT * FROM sys.views v
          JOIN sys.schemas s ON v.schema_id = s.schema_id
          JOIN sys.sql_modules sql ON v.object_id = sql.object_id
          WHERE s.name = #{strlit(unquoted_identifier view.schema)}
          AND v.name = #{strlit(unquoted_identifier view.name)}
          AND #{definition_matches_by_hash 'sql.definition', view.definition}
        }
      end
      puts "BEGIN"
      indented {
        puts adoption_error_sql "View #{view.qualified_name} does not have the expected definition."
      }
      puts "END;"
      puts access_object_adoption_sql(:VIEW, view.qualified_name)
    }
  end
end

#adoption_sqlObject



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 28

def adoption_sql
  in_ddl_transaction do
    script_parts = [
      # Check for blatantly incorrect application of script, e.g. running
      # on master or template database.
      :check_execution_environment_sql,
      
      # Create schema version control (SVC) tables if they don't exist
      :ensure_version_tables_sql,
      :ensure_permissions_table_sql,
      
      # Create an error table
      :create_adoption_error_table_sql,
      
      # Check roles
      :check_expected_roles_exist_sql,
      :check_expected_role_membership_sql,
      
      # Check schemas
      :check_expected_schemas_exist_sql,
      
      # Check tables (including columns)
      :check_tables_exist_and_structured_as_expected_sql,
      
      # Check column defaults
      :check_expected_column_defaults_exist_sql,
      
      # Check primary key and unique constraints
      :check_primary_key_and_unique_constraints_sql,
      
      # Check foreign key constraints
      :check_foreign_key_constraints_sql,
      
      # Check check constraints
      :check_check_constraints_sql,
      
      # Adopt indexes
      :adopt_indexes_sql,
      
      # Adopt statistics
      :adopt_statistics_sql,
      
      # Adopt views
      :adopt_views_sql,
      
      # Adopt stored procedures
      :adopt_stored_procedures_sql,
      
      # Adopt user defined functions
      :adopt_udfs_sql,
      
      # Adopt permissions
      :adopt_permissions_sql,
      
      # Error out if there are any entries in the error table
      :check_adoption_error_table_empty_sql,
      
      # Write version bridge record to xmigra.applied
      :write_version_bridge_record_sql,
    ]
    
    #script_parts = script_parts.map {|mn| self.send(mn)}.flatten.compact
    script_parts = script_parts.map do |mn|
      [
        %Q{PRINT N'ADOPTION STEP: #{mn}';},
        self.send(mn)
      ]
    end.flatten.compact
    script_parts.join(ddl_block_separator)
  end
end

#check_check_constraints_sqlObject



931
932
933
934
935
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 931

def check_check_constraints_sql
  db_expectations.check_constraints.map do |cnstr|
    CheckConstraintAdoptionChecks.new(cnstr, method(:adoption_error_sql)).to_s
  end # Do not join -- each needs a separate batch (they use variables)
end

#check_expected_column_defaults_exist_sqlObject



416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 416

def check_expected_column_defaults_exist_sql
  db_expectations.column_defaults.map do |col_dflt|
    constraint_id = (col_dflt.name || "on #{col_dflt.column}") + " of #{col_dflt.qualified_table}"
    compose_sql {
      puts "IF NOT EXISTS (%s)" do
        puts "SELECT * FROM sys.default_constraints dc"
        puts "INNER JOIN sys.schemas s ON dc.schema_id = s.schema_id"
        puts "INNER JOIN sys.tables t ON dc.parent_object_id = t.object_id"
        puts "INNER JOIN sys.columns c ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id"
        puts "WHERE dc.name = %s" do
          puts strlit(unquoted_identifier col_dflt.name)
        end if col_dflt.name
      end
      puts "BEGIN"
      indented {puts adoption_error_sql(
        "Expected column default constraint #{constraint_id} does not exist."
      )}
      puts "END ELSE BEGIN"
      indented {
        puts "IF NOT EXISTS (%s)" do
          puts "SELECT * FROM sys.default_constraints dc"
          puts "INNER JOIN sys.schemas s ON dc.schema_id = s.schema_id"
          puts "INNER JOIN sys.tables t ON dc.parent_object_id = t.object_id"
          puts "INNER JOIN sys.columns c ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id"
          puts "WHERE dc.definition = %s" do
            puts strlit col_dflt.expression
          end
          puts "AND dc.name = %s" do
            puts strlit(unquoted_identifier col_dflt.name)
          end if col_dflt.name
        end
        puts("BEGIN".."END;") {
          puts adoption_error_sql("Column default constraint #{constraint_id} does not have the expected definition.")
        }
      }
      puts "END;"
    }
  end.join("\n")
end

#check_expected_role_membership_sqlObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 165

def check_expected_role_membership_sql
  [].tap do |tests|
    db_expectations.roles.each do |r|
      r.encompassing_roles.each do |er_name|
        tests << dedent(%Q{
          IF NOT EXISTS (
            SELECT * FROM sys.database_role_members rm
            INNER JOIN sys.database_principals r ON rm.member_principal_id = r.principal_id
            INNER JOIN sys.database_principals er ON rm.role_principal_id = er.principal_id
            WHERE r.name = #{strlit(unquoted_identifier r.name)} 
            AND er.name = #{strlit(unquoted_identifier er_name)}
          )
          BEGIN
            #{adoption_error_sql "Role #{r.name} should be a member of #{er_name}."}
          END;
        })
      end
    end
  end.join("\n")
end

#check_expected_roles_exist_sqlObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 140

def check_expected_roles_exist_sql
  db_expectations.roles.map do |r|
    dedent %Q{
      IF NOT EXISTS (
        SELECT * FROM sys.database_principals r
        WHERE r.name = #{strlit(unquoted_identifier r.name)}
        AND r.type = 'R'
      )
      BEGIN
        #{adoption_error_sql "Role #{r.name} does not exist."}
      END;
      
      IF EXISTS (
        SELECT * FROM sys.database_principals r
        INNER JOIN sys.database_principals o ON r.owning_principal_id = o.principal_id
        WHERE r.name = #{strlit(unquoted_identifier r.name)}
        AND o.name <> #{strlit(unquoted_identifier r.owner)}
      )
      BEGIN
        #{adoption_error_sql "Role #{r.name} should be owned by #{r.owner}."}
      END;
    }
  end.join("\n")
end

#check_expected_schemas_exist_sqlObject



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 186

def check_expected_schemas_exist_sql
  db_expectations.schemas.map do |schema|
    dedent %Q{
      IF NOT EXISTS (
        SELECT * FROM sys.schemas s
        WHERE s.name = #{strlit(unquoted_identifier schema.name)}
      )
      BEGIN
        #{adoption_error_sql "Schema #{schema.name} does not exist."}
      END ELSE IF NOT EXISTS (
        SELECT * FROM sys.schemas s
        INNER JOIN sys.database_principals r ON s.principal_id = r.principal_id
        WHERE s.name = #{strlit(unquoted_identifier schema.name)}
        AND r.name = #{strlit(unquoted_identifier schema.owner)}
      )
      BEGIN
        #{adoption_error_sql "Schema #{schema.name} is not owned by #{schema.owner}."}
      END;
    }
  end
end

#check_foreign_key_constraints_sqlObject



843
844
845
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 843

def check_foreign_key_constraints_sql
  ForeignKeyAdoptionChecks.new(db_expectations.foreign_keys, method(:adoption_error_sql)).to_s
end

#check_primary_key_and_unique_constraints_sqlObject



662
663
664
665
666
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 662

def check_primary_key_and_unique_constraints_sql
  db_expectations.pku_constraints.map do |cnstr|
    KeylikeConstraintAdoptionChecks.new(cnstr, method(:adoption_error_sql)).to_s
  end # Do not join -- each needs a separate batch (they use variables)
end

#check_tables_exist_and_structured_as_expected_sqlObject



410
411
412
413
414
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 410

def check_tables_exist_and_structured_as_expected_sql
  db_expectations.tables.map do |table|
    TableAdoptionChecks.new(table, method(:adoption_error_sql)).to_s
  end # Do not join -- each needs a separate batch (they use variables)
end

#compose_sql(&blk) ⇒ Object



100
101
102
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 100

def compose_sql(&blk)
  IndentedStringBuilder.dsl(&blk)
end

#create_script(path) ⇒ Object



22
23
24
25
26
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 22

def create_script(path)
  Pathname(path).open('w') do |script|
    script.puts adoption_sql
  end
end

#definition_matches_by_hash(expr, definition) ⇒ Object



1156
1157
1158
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 1156

def definition_matches_by_hash(expr, definition)
  "HASHBYTES('md5', #{expr}) = 0x#{Digest::MD5.hexdigest definition.gsub("\n", "\r\n").encode('UTF-16LE')}"
end

#write_version_bridge_record_sqlObject



1479
1480
1481
1482
1483
1484
# File 'lib/mkxms/mssql/adoption_script_writer.rb', line 1479

def write_version_bridge_record_sql
  dedent %Q{
    INSERT INTO [xmigra].[applied] ([MigrationID], [VersionBridgeMark], [Description])
    VALUES (#{strlit @xn_builder.migrations.last.id}, 1, N'Adoption of existing structure.');
  }
end