diff --git a/sql/schema.test.js b/sql/schema.test.js index c3f8b3c..2d75c4f 100644 --- a/sql/schema.test.js +++ b/sql/schema.test.js @@ -178,4 +178,70 @@ describe('sql schema', () => { const sql = await fs.readFile(path.join(sqlDir, '12_nt_options.sql'), 'utf8') assert.match(sql, /'db_version','2\.41'/) }) + + it('adds v3 nameserver types without changing existing rows', async () => { + const source = await fs.readFile( + path.join(sqlDir, 'upgrade', '06_add_nameserver_export_types.sql'), + 'utf8', + ) + const migration = source.replaceAll( + '`nt_nameserver_export_type`', + '`test_nameserver_export_type_upgrade`', + ) + const rows = async () => + ( + await conn.query('SELECT id, name, descr, url FROM test_nameserver_export_type_upgrade ORDER BY id') + )[0] + const reset = async (extra) => { + await conn.query('DELETE FROM test_nameserver_export_type_upgrade') + await conn.query( + `INSERT INTO test_nameserver_export_type_upgrade (id, name, descr, url) + SELECT id, name, descr, url FROM nt_nameserver_export_type WHERE id <= 8`, + ) + for (const row of extra) { + await conn.query( + 'INSERT INTO test_nameserver_export_type_upgrade (id, name, descr, url) VALUES (?, ?, ?, ?)', + row, + ) + } + } + + await conn.query('DROP TABLE IF EXISTS test_nameserver_export_type_upgrade') + await conn.query('CREATE TABLE test_nameserver_export_type_upgrade LIKE nt_nameserver_export_type') + try { + await reset([ + [9, 'gerbil', 'Gerbil DNS', ''], + [10, 'otter', 'Otter DNS', ''], + ]) + await conn.query(migration) + + const clashingIds = await rows() + assert.deepEqual(clashingIds.slice(8, 10), [ + { id: 9, name: 'gerbil', descr: 'Gerbil DNS', url: '' }, + { id: 10, name: 'otter', descr: 'Otter DNS', url: '' }, + ]) + assert.equal(clashingIds.filter((r) => r.name === 'coredns').length, 1) + assert.equal(clashingIds.filter((r) => r.name === 'native').length, 1) + + await conn.query(migration) + assert.deepEqual(await rows(), clashingIds, 'repeat migration changed the rows') + + await reset([ + [11, 'coredns', 'Custom CoreDNS', ''], + [12, 'native', 'Custom native', ''], + ]) + await conn.query(migration) + + const existingNames = await rows() + assert.deepEqual( + existingNames.filter((r) => ['coredns', 'native'].includes(r.name)), + [ + { id: 11, name: 'coredns', descr: 'Custom CoreDNS', url: '' }, + { id: 12, name: 'native', descr: 'Custom native', url: '' }, + ], + ) + } finally { + await conn.query('DROP TABLE test_nameserver_export_type_upgrade') + } + }) }) diff --git a/sql/upgrade/06_add_nameserver_export_types.sql b/sql/upgrade/06_add_nameserver_export_types.sql new file mode 100644 index 0000000..6f85cf0 --- /dev/null +++ b/sql/upgrade/06_add_nameserver_export_types.sql @@ -0,0 +1,18 @@ +# Copyright 2004-2026 The Network People, Inc. +# +# Add the nameserver export types introduced in NicTool 3.0 without +# changing existing ids. + +INSERT INTO `nt_nameserver_export_type` (`name`, `descr`, `url`) +SELECT 'coredns', 'CoreDNS', 'coredns.io' +FROM DUAL +WHERE NOT EXISTS ( + SELECT 1 FROM `nt_nameserver_export_type` WHERE `name` = 'coredns' +); + +INSERT INTO `nt_nameserver_export_type` (`name`, `descr`, `url`) +SELECT 'native', 'NicTool (in-process)', 'nictool.com' +FROM DUAL +WHERE NOT EXISTS ( + SELECT 1 FROM `nt_nameserver_export_type` WHERE `name` = 'native' +);