@@ -173,3 +173,66 @@ func TestLoadSchemaFromDB_CombinedFilters(t *testing.T) {
173173 require .Equal (t , "users" , filtered [0 ].Name )
174174 require .NotContains (t , filtered [0 ].Schema , "AUTO_INCREMENT=" )
175175}
176+
177+ func TestLoadSchemaAndExcludedTablesFromDB (t * testing.T ) {
178+ dbName , _ := testutils .CreateUniqueTestDatabase (t )
179+ testutils .RunSQLInDatabase (t , dbName , `CREATE TABLE users (
180+ id bigint unsigned NOT NULL AUTO_INCREMENT,
181+ PRIMARY KEY (id)
182+ ) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=utf8mb4` )
183+ testutils .RunSQLInDatabase (t , dbName , `CREATE TABLE _shadow (id bigint NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB` )
184+ testutils .RunSQLInDatabase (t , dbName , `CREATE TABLE users_archive_2024 (id bigint NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB` )
185+
186+ db , err := sql .Open ("block-mysql" , testutils .DSNForDatabase (dbName ))
187+ require .NoError (t , err )
188+ defer func () { _ = db .Close () }()
189+
190+ tables , excluded , err := LoadSchemaAndExcludedTablesFromDB (t .Context (), db ,
191+ WithoutUnderscoreTables ,
192+ WithoutArchiveTables ,
193+ WithStrippedAutoIncrement ,
194+ )
195+ require .NoError (t , err )
196+ require .Len (t , tables , 1 )
197+ require .Equal (t , "users" , tables [0 ].Name )
198+ require .NotContains (t , tables [0 ].Schema , "AUTO_INCREMENT=" )
199+
200+ // Each excluded table is named alongside the option that excluded it, so a
201+ // caller can word the two exclusions differently.
202+ require .Equal (t , []ExcludedTable {
203+ {Name : "_shadow" , Filter : WithoutUnderscoreTables },
204+ {Name : "users_archive_2024" , Filter : WithoutArchiveTables },
205+ }, excluded )
206+ }
207+
208+ func TestLoadSchemaAndExcludedTablesFromDB_NoFilters (t * testing.T ) {
209+ dbName , _ := testutils .CreateUniqueTestDatabase (t )
210+ testutils .RunSQLInDatabase (t , dbName , `CREATE TABLE users (id bigint NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB` )
211+ testutils .RunSQLInDatabase (t , dbName , `CREATE TABLE _shadow (id bigint NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB` )
212+ testutils .RunSQLInDatabase (t , dbName , `CREATE TABLE users_archive_2024 (id bigint NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB` )
213+
214+ db , err := sql .Open ("block-mysql" , testutils .DSNForDatabase (dbName ))
215+ require .NoError (t , err )
216+ defer func () { _ = db .Close () }()
217+
218+ tables , excluded , err := LoadSchemaAndExcludedTablesFromDB (t .Context (), db )
219+ require .NoError (t , err )
220+ require .Len (t , tables , 3 )
221+ require .Empty (t , excluded )
222+ }
223+
224+ func TestLoadSchemaAndExcludedTablesFromDB_ReportsFirstMatchingFilter (t * testing.T ) {
225+ // A name matching both conventions is excluded once, under the first
226+ // option that matched, so a caller never discloses one table twice.
227+ dbName , _ := testutils .CreateUniqueTestDatabase (t )
228+ testutils .RunSQLInDatabase (t , dbName , `CREATE TABLE _users_archive_2024 (id bigint NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB` )
229+
230+ db , err := sql .Open ("block-mysql" , testutils .DSNForDatabase (dbName ))
231+ require .NoError (t , err )
232+ defer func () { _ = db .Close () }()
233+
234+ tables , excluded , err := LoadSchemaAndExcludedTablesFromDB (t .Context (), db , WithoutUnderscoreTables , WithoutArchiveTables )
235+ require .NoError (t , err )
236+ require .Empty (t , tables )
237+ require .Equal (t , []ExcludedTable {{Name : "_users_archive_2024" , Filter : WithoutUnderscoreTables }}, excluded )
238+ }
0 commit comments