diff --git a/CHANGELOG.md b/CHANGELOG.md index 76c646c..a04a9bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ### Unreleased + +### [3.0.0-alpha.4] - 2024-03-05 + +- feat(lib/nameserver): added, with tests + + ### 3.0.0-alpha.3 - routes/permission: added GET, POST, DELETE @@ -14,3 +20,4 @@ [3.0.0-alpha.3]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.3 +[3.0.0-alpha.4]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.4 diff --git a/lib/nameserver.js b/lib/nameserver.js new file mode 100644 index 0000000..682a044 --- /dev/null +++ b/lib/nameserver.js @@ -0,0 +1,125 @@ +import Mysql from './mysql.js' +import { mapToDbColumn } from './util.js' + +const nsDbMap = { id: 'nt_nameserver_id', gid: 'nt_group_id' } +const boolFields = ['deleted', 'export_serials'] + +class Nameserver { + constructor() { + this.mysql = Mysql + } + + async create(args) { + if (args.id) { + const g = await this.get({ id: args.id }) + if (g.length === 1) return g[0].id + } + + if (args.export.type) { + const rows = await Mysql.execute(...Mysql.select('SELECT id FROM nt_nameserver_export_type', { name: args.export.type })) + args.export_type_id = rows[0].id + delete args.export.type + } + + return await Mysql.execute( + ...Mysql.insert(`nt_nameserver`, mapToDbColumn(objectToDb(args), nsDbMap)), + ) + } + + async get(args) { + if (args.name !== undefined) { + args['ns.name'] = args.name + delete args.name + } + const rows = await Mysql.execute( + ...Mysql.select( + `SELECT ns.nt_nameserver_id AS id + , ns.nt_group_id AS gid + , ns.name + , ns.ttl + , ns.description + , ns.address + , ns.address6 + , ns.remote_login + , ns.logdir + , ns.datadir + , ns.export_interval + , ns.export_serials + , ns.export_status + , ns.deleted + , t.name AS export_type + FROM nt_nameserver ns + JOIN nt_nameserver_export_type t ON ns.export_type_id=t.id`, + mapToDbColumn(args, nsDbMap), + ), + ) + for (const r of rows) { + for (const b of boolFields) { + r[b] = r[b] === 1 + } + } + return dbToObject(rows) + } + + async put(args) { + if (!args.id) return false + const id = args.id + delete args.id + // Mysql.debug(1) + const r = await Mysql.execute( + ...Mysql.update( + `nt_nameserver`, + `nt_nameserver_id=${id}`, + mapToDbColumn(args, nsDbMap), + ), + ) + // console.log(r) + return r.changedRows === 1 + } + + async delete(args) { + await Mysql.execute(`UPDATE nt_nameserver SET deleted=? WHERE nt_nameserver_id=?`, [ + args.deleted ?? 1, + args.id, + ]) + return true + } + + async destroy(args) { + return await Mysql.execute( + ...Mysql.delete(`nt_nameserver`, { nt_nameserver_id: args.id }), + ) + } +} + +export default new Nameserver() + + +function dbToObject(rows) { + for (const row of rows) { + for (const f of ['export']) { + for (const p of ['type', 'interval', 'serials', 'status']) { + if (row[`${f}_${p}`] !== undefined) { + if (row[f] === undefined) row[f] = {} + row[f][p] = row[`${f}_${p}`] + delete row[`${f}_${p}`] + } + } + } + } + return rows +} + +function objectToDb(row) { + const newRow = JSON.parse(JSON.stringify(row)) + for (const f of ['export']) { + for (const p of ['interval', 'serials', 'status']) { + if (newRow[f] === undefined) continue + if (newRow[f][p] === undefined) continue + newRow[`${f}_${p}`] = newRow[f][p] + delete newRow[f][p] + } + delete newRow[f] + } + return newRow +} diff --git a/lib/nameserver.test.js b/lib/nameserver.test.js new file mode 100644 index 0000000..8e91b1e --- /dev/null +++ b/lib/nameserver.test.js @@ -0,0 +1,44 @@ +import assert from 'node:assert/strict' +import { describe, it, after, before } from 'node:test' + +import Nameserver from './nameserver.js' + +import testCase from './test/nameserver.json' with { type: 'json' } + +before(async () => { + await Nameserver.create(testCase) +}) + +after(async () => { + // Nameserver.destroy({ id: testCase.id }) + Nameserver.mysql.disconnect() +}) + +describe('nameserver', function () { + + it('gets nameserver by id', async () => { + const g = await Nameserver.get({ id: testCase.id }) + assert.deepEqual(g[0], testCase) + }) + + it('gets nameserver by name', async () => { + const g = await Nameserver.get({ name: testCase.name }) + assert.deepEqual(g[0], testCase) + }) + + it('changes a nameserver', async () => { + assert.ok(await Nameserver.put({ id: testCase.id, name: 'b.ns.example.com.' })) + const ns = await Nameserver.get({ id: testCase.id }) + assert.deepEqual(ns[0].name, 'b.ns.example.com.') + assert.ok(await Nameserver.put({ id: testCase.id, name: testCase.name })) + }) + + it('deletes a nameserver', async () => { + assert.ok(await Nameserver.delete({ id: testCase.id })) + let g = await Nameserver.get({ id: testCase.id, deleted: 1 }) + assert.equal(g[0]?.deleted, true) + await Nameserver.delete({ id: testCase.id, deleted: 0 }) // restore + g = await Nameserver.get({ id: testCase.id }) + assert.equal(g[0].deleted, false) + }) +}) diff --git a/lib/test/nameserver.json b/lib/test/nameserver.json new file mode 100644 index 0000000..6888ab9 --- /dev/null +++ b/lib/test/nameserver.json @@ -0,0 +1,19 @@ +{ + "id": 4096, + "gid": 4096, + "name": "a.ns.example.com.", + "description": "", + "address": "1.2.3.4", + "address6": "2001:DB8::1", + "remote_login": "nsd", + "logdir": "/foo", + "datadir": "/bar", + "export": { + "interval": 0, + "serials": true, + "status": "last run:03-05 15:25
last cp :09-20 12:59", + "type": "NSD" + }, + "ttl": 3600, + "deleted": false +} diff --git a/package.json b/package.json index 0d79d33..9c6e38c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nictool/api", - "version": "3.0.0-alpha.3", + "version": "3.0.0-alpha.4", "description": "NicTool API", "main": "index.js", "type": "module",