Skip to content

Commit 28f979e

Browse files
authored
release 3.0.0-alpha.3 (#28)
- routes/permission: added GET, POST, DELETE - permission.get: default search with deleted=0 - session.put: added - session: store user/group info in cookie (saves DB trips) - mysql(insert, select, update, delete): return just the query - lib/group.get: convert booleans - lib/user.get: convert booleans
1 parent a3734f9 commit 28f979e

29 files changed

+558
-244
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule ".release"]
2+
path = .release
3+
url = git@github.com:msimerson/.release.git

.release

Submodule .release added at 8959a99

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# CHANGES
2+
3+
### Unreleased
4+
5+
### 3.0.0-alpha.3
6+
7+
- routes/permission: added GET, POST, DELETE
8+
- permission.get: default search with deleted=0
9+
- session.put: added
10+
- session: store user/group info in cookie (saves DB trips)
11+
- mysql(insert, select, update, delete): return just the query
12+
- lib/group.get: convert booleans
13+
- lib/user.get: convert booleans
14+
15+
16+
[3.0.0-alpha.3]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.3

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ or
3333

3434
`npm run develop (development)`
3535

36-
will start up the HTTP service on the port specified in `conf.d/http.yml`. The default URL for the service is [http://localhost:3000](http://localhost:3000) and the API methods have documentation at [http://localhost:3000/documentation](http://localhost:3000/documentation).
36+
will start up the HTTP service on the port specified in `conf.d/http.yml`. The default URL for the service is [http://localhost:3000](http://localhost:3000) and the API methods have documentation at [http://localhost:3000/documentation#/](http://localhost:3000/documentation#/).
3737

3838

3939
## Using the API service

conf.d/http.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
21
default:
32
host: localhost
43
port: 3000
54
cookie:
65
# https://hapi.dev/module/cookie/api/?v=12.0.1
76
name: sid-nictool
87
password: af1b926a5e21f535c4f5b6c42941c4cf
9-
ttl: 3600000 # 1 hour
8+
ttl: 3600000 # 1 hour
109
# domain:
1110
path: /
1211
clearInvalid: true

conf.d/mysql.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ default:
1313
# settings below this line override default settings
1414
production:
1515
host: mysql
16-
password: "********"
16+
password: '********'
1717

1818
# used for CI testing (GitHub Actions workflows)
1919
test:

lib/group.js

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Mysql from './mysql.js'
22
import { mapToDbColumn } from './util.js'
33

44
const groupDbMap = { id: 'nt_group_id', parent_gid: 'parent_group_id' }
5+
const boolFields = ['deleted']
56

67
class Group {
78
constructor() {
@@ -11,65 +12,61 @@ class Group {
1112
async create(args) {
1213
if (args.id) {
1314
const g = await this.get({ id: args.id })
14-
if (g.length) return g[0].id
15+
if (g.length === 1) return g[0].id
1516
}
1617

17-
return await Mysql.insert(
18-
`INSERT INTO nt_group`,
19-
mapToDbColumn(args, groupDbMap),
18+
return await Mysql.execute(
19+
...Mysql.insert(`nt_group`, mapToDbColumn(args, groupDbMap)),
2020
)
2121
}
2222

2323
async get(args) {
24-
return await Mysql.select(
25-
`SELECT nt_group_id AS id
24+
const rows = await Mysql.execute(
25+
...Mysql.select(
26+
`SELECT nt_group_id AS id
2627
, parent_group_id AS parent_gid
2728
, name
28-
FROM nt_group WHERE`,
29-
mapToDbColumn(args, groupDbMap),
30-
)
31-
}
32-
33-
async getAdmin(args) {
34-
return await Mysql.select(
35-
`SELECT nt_group_id AS id
36-
, name
37-
, parent_group_id AS parent_gid
38-
, deleted
39-
FROM nt_group WHERE`,
40-
mapToDbColumn(args, groupDbMap),
29+
, deleted
30+
FROM nt_group`,
31+
mapToDbColumn(args, groupDbMap),
32+
),
4133
)
34+
for (const r of rows) {
35+
for (const b of boolFields) {
36+
r[b] = r[b] === 1
37+
}
38+
}
39+
return rows
4240
}
4341

4442
async put(args) {
4543
if (!args.id) return false
4644
const id = args.id
4745
delete args.id
4846
// Mysql.debug(1)
49-
const r = await Mysql.update(
50-
`UPDATE nt_group SET`,
51-
`WHERE nt_group_id=${id}`,
52-
mapToDbColumn(args, groupDbMap),
47+
const r = await Mysql.execute(
48+
...Mysql.update(
49+
`nt_group`,
50+
`nt_group_id=${id}`,
51+
mapToDbColumn(args, groupDbMap),
52+
),
5353
)
5454
// console.log(r)
5555
return r.changedRows === 1
5656
}
5757

58-
async delete(args, val) {
59-
const g = await this.getAdmin(args)
60-
if (g.length !== 1) return false
58+
async delete(args) {
6159
await Mysql.execute(`UPDATE nt_group SET deleted=? WHERE nt_group_id=?`, [
62-
val ?? 1,
63-
g[0].id,
60+
args.deleted ?? 1,
61+
args.id,
6462
])
6563
return true
6664
}
6765

6866
async destroy(args) {
69-
const g = await this.getAdmin(args)
70-
if (g.length === 1) {
71-
await Mysql.execute(`DELETE FROM nt_group WHERE nt_group_id=?`, [g[0].id])
72-
}
67+
return await Mysql.execute(
68+
...Mysql.delete(`nt_group`, { nt_group_id: args.id }),
69+
)
7370
}
7471
}
7572

lib/group.test.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ describe('group', function () {
2020
id: testCase.id,
2121
name: testCase.name,
2222
parent_gid: 0,
23+
deleted: false,
2324
})
2425
})
2526

@@ -29,6 +30,7 @@ describe('group', function () {
2930
id: testCase.id,
3031
name: testCase.name,
3132
parent_gid: 0,
33+
deleted: false,
3234
})
3335
})
3436

@@ -39,17 +41,18 @@ describe('group', function () {
3941
id: testCase.id,
4042
name: 'example.net',
4143
parent_gid: 0,
44+
deleted: false,
4245
},
4346
])
4447
assert.ok(await Group.put({ id: testCase.id, name: testCase.name }))
4548
})
4649

4750
it('deletes a group', async () => {
4851
assert.ok(await Group.delete({ id: testCase.id }))
49-
let g = await Group.getAdmin({ id: testCase.id })
50-
assert.equal(g[0].deleted, 1)
51-
await Group.delete({ id: testCase.id }, 0) // restore
52-
g = await Group.getAdmin({ id: testCase.id })
53-
assert.equal(g[0].deleted, 0)
52+
let g = await Group.get({ id: testCase.id, deleted: 1 })
53+
assert.equal(g[0]?.deleted, true)
54+
await Group.delete({ id: testCase.id, deleted: 0 }) // restore
55+
g = await Group.get({ id: testCase.id })
56+
assert.equal(g[0].deleted, false)
5457
})
5558
})

lib/mysql.js

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,34 +42,26 @@ class Mysql {
4242
return rows
4343
}
4444

45-
async insert(query, params = {}) {
46-
const skipExecute = params.skipExecute ?? false
47-
delete params.skipExecute
48-
49-
query += `(${Object.keys(params).join(',')}) VALUES(${Object.keys(params).map(() => '?')})`
50-
51-
if (skipExecute) return query
52-
return await this.execute(query, Object.values(params))
45+
insert(table, params = {}) {
46+
return [
47+
`INSERT INTO ${table} (${Object.keys(params).join(',')}) VALUES(${Object.keys(params).map(() => '?')})`,
48+
Object.values(params),
49+
]
5350
}
5451

55-
async select(query, params = {}) {
56-
const skipExecute = params.skipExecute ?? false
57-
delete params.skipExecute
58-
59-
const [queryWhere, paramsArray] = this.whereConditions(query, params)
60-
61-
if (skipExecute) return queryWhere
62-
return await this.execute(queryWhere, paramsArray)
52+
select(query, params = {}) {
53+
return this.whereConditions(query, params)
6354
}
6455

65-
async update(query, where, params = {}) {
66-
const skipExecute = params.skipExecute ?? false
67-
delete params.skipExecute
68-
69-
query += ` ${Object.keys(params).join('=?,')}=? ${where}`
56+
update(table, where, params = {}) {
57+
return [
58+
`UPDATE ${table} SET ${Object.keys(params).join('=?,')}=? WHERE ${where}`,
59+
Object.values(params),
60+
]
61+
}
7062

71-
if (skipExecute) return { q: query, p: Object.values(params) }
72-
return await this.execute(query, Object.values(params))
63+
delete(table, params) {
64+
return this.whereConditions(`DELETE FROM ${table}`, params)
7365
}
7466

7567
whereConditions(query, params) {
@@ -82,6 +74,7 @@ class Mysql {
8274
// Object to WHERE conditions
8375
let first = true
8476
for (const p in params) {
77+
if (first) newQuery += ' WHERE'
8578
if (!first) newQuery += ' AND'
8679
newQuery += ` ${p}=?`
8780
paramsArray.push(params[p])
@@ -91,11 +84,6 @@ class Mysql {
9184
return [newQuery, paramsArray]
9285
}
9386

94-
async delete(query, params) {
95-
const [queryWhere, paramsArray] = this.whereConditions(query, params)
96-
return await this.execute(queryWhere, paramsArray)
97-
}
98-
9987
async disconnect(dbh) {
10088
const d = dbh || this.dbh
10189
if (_debug) console.log(`MySQL connection id ${d.connection.connectionId}`)

lib/mysql.test.js

Lines changed: 63 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,57 +20,80 @@ describe('mysql', () => {
2020
})
2121
}
2222

23-
it('SQL: formats SELECT queries', async () => {
24-
const r = await Mysql.select(`SELECT * FROM nt_user WHERE`, {
25-
last_name: 'Test',
26-
skipExecute: true,
27-
})
28-
assert.equal(r, `SELECT * FROM nt_user WHERE last_name=?`)
23+
it('formats SELECT queries', () => {
24+
assert.deepEqual(
25+
Mysql.select(`SELECT * FROM nt_user`, {
26+
last_name: 'Test',
27+
}),
28+
[`SELECT * FROM nt_user WHERE last_name=?`, ['Test']],
29+
)
2930
})
3031

31-
it('SQL: formats INSERT queries', async () => {
32-
const r = await Mysql.select(`INSERT INTO nt_user SET`, {
32+
it('formats INSERT query', () => {
33+
const r = Mysql.insert(`nt_user`, {
3334
first_name: 'uNite',
3435
last_name: 'Test',
35-
skipExecute: true,
3636
})
37-
assert.equal(r, `INSERT INTO nt_user SET first_name=? AND last_name=?`)
37+
assert.deepEqual(r, [
38+
`INSERT INTO nt_user (first_name,last_name) VALUES(?,?)`,
39+
['uNite', 'Test'],
40+
])
3841
})
3942

40-
it('SQL: formats UPDATE queries, 1', async () => {
41-
const { q, p } = await Mysql.update(
42-
`UPDATE nt_user SET`,
43-
`WHERE nt_user_id=4096`,
44-
{ first_name: 'uNite', skipExecute: true },
45-
)
46-
assert.equal(q, `UPDATE nt_user SET first_name=? WHERE nt_user_id=4096`)
47-
assert.deepEqual(p, ['uNite'])
43+
describe('update', () => {
44+
it('formats with one value', () => {
45+
const r = Mysql.update(`nt_user`, `nt_user_id=4096`, {
46+
first_name: 'uNite',
47+
})
48+
assert.deepEqual(r, [
49+
`UPDATE nt_user SET first_name=? WHERE nt_user_id=4096`,
50+
['uNite'],
51+
])
52+
})
53+
54+
it('formats with two values', () => {
55+
const r = Mysql.update(`nt_user`, `nt_user_id=4096`, {
56+
last_name: 'Teste',
57+
is_admin: 1,
58+
})
59+
assert.deepEqual(r, [
60+
`UPDATE nt_user SET last_name=?,is_admin=? WHERE nt_user_id=4096`,
61+
['Teste', 1],
62+
])
63+
})
64+
65+
it('formats with three values', () => {
66+
const r = Mysql.update(`nt_user`, `nt_user_id=4096`, {
67+
first_name: 'Unit',
68+
last_name: 'Test',
69+
is_admin: 0,
70+
})
71+
assert.deepEqual(r, [
72+
`UPDATE nt_user SET first_name=?,last_name=?,is_admin=? WHERE nt_user_id=4096`,
73+
['Unit', 'Test', 0],
74+
])
75+
})
4876
})
4977

50-
it('SQL: formats UPDATE queries, 2', async () => {
51-
const { q, p } = await Mysql.update(
52-
`UPDATE nt_user SET`,
53-
`WHERE nt_user_id=4096`,
54-
{ last_name: 'Teste', is_admin: 1, skipExecute: true },
55-
)
56-
assert.equal(
57-
q,
58-
`UPDATE nt_user SET last_name=?,is_admin=? WHERE nt_user_id=4096`,
59-
)
60-
assert.deepEqual(p, ['Teste', 1])
78+
describe('delete', () => {
79+
it('no params', () => {
80+
assert.deepEqual(Mysql.delete(`nt_user`, {}), [`DELETE FROM nt_user`, []])
81+
})
82+
83+
it('with params', () => {
84+
assert.deepEqual(Mysql.delete(`nt_user`, { last_name: 'Test' }), [
85+
`DELETE FROM nt_user WHERE last_name=?`,
86+
['Test'],
87+
])
88+
})
6189
})
6290

63-
it('SQL: formats UPDATE queries, 3', async () => {
64-
const { q, p } = await Mysql.update(
65-
`UPDATE nt_user SET`,
66-
`WHERE nt_user_id=4096`,
67-
{ first_name: 'Unit', last_name: 'Test', is_admin: 0, skipExecute: true },
68-
)
69-
assert.equal(
70-
q,
71-
`UPDATE nt_user SET first_name=?,last_name=?,is_admin=? WHERE nt_user_id=4096`,
72-
)
73-
assert.deepEqual(p, ['Unit', 'Test', 0])
91+
it('executes formatted queries', async () => {
92+
const [query, argsArray] = Mysql.select(`SELECT * FROM nt_options`)
93+
const r = await Mysql.execute(query, argsArray)
94+
assert.deepEqual(r[0].option_id, 1)
95+
96+
// await Mysql.execute(...Mysql.select(`SELECT * FROM nt_options`))
7497
})
7598

7699
it('disconnects', async () => {

0 commit comments

Comments
 (0)