Skip to content

Commit 9894570

Browse files
committed
Add queries & mutations
1 parent 1af0590 commit 9894570

23 files changed

+399
-117
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/bin/bash
22

33
echo "Filling data to `todo_list` table"
4-
node ./scripts/migration/todo-list/index.ts
4+
node ./scripts/seed/todo-list/index.ts

README.md

+64-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,70 @@
1-
# Bookzone API
1+
# Todo API
22

3-
## Table content
3+
# Getting started
44

5-
- [Getting started](/docs/getting-started.md)
6-
- [Development](/docs/development.md)
5+
## Database
6+
7+
Make sure you have [Docker](https://www.docker.com/) installed
8+
9+
### Setting up
10+
11+
**Commands**
12+
13+
To install the database management, run:
14+
15+
```bash
16+
docker-compose up -d
17+
```
18+
19+
To create database, run:
20+
21+
```bash
22+
docker exec -it todo psql -U postgres -c "create database todo"
23+
```
24+
25+
**.env file**
26+
27+
1. Create the `.env` file
28+
2. Copy and parse the `connection information` below:
29+
30+
```bash
31+
DB_USER=postgres
32+
DB_HOST=localhost
33+
DB_DATABASE=todo
34+
DB_PORT=54320
35+
```
36+
37+
## Create tables
38+
39+
Open and run the `database/sql/database.sql` by postgres tools (i.e. [pgAdmin](https://www.pgadmin.org/))
40+
41+
## Seeding data
42+
43+
**dump data**
44+
45+
To initialize the dump data for `todo` database, run:
46+
47+
```bash
48+
npm run seed
49+
```
50+
51+
## Development
52+
53+
To run development environment
54+
55+
```bash
56+
npm run dev
57+
```
58+
59+
## Production
60+
61+
To run production environment
62+
63+
```bash
64+
npm start
65+
```
766

867
# References
968

1069
- [node-postgres](https://node-postgres.com/)
70+
- [pgAdmin](https://www.pgadmin.org/)

docs/development.md

-7
This file was deleted.

docs/getting-started.md

-43
This file was deleted.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"dev": "./.npm-scripts/watch.sh",
1212
"serve": "node dist/server.js",
1313
"build": "tsc",
14-
"migrate": "./.npm-scripts/migration.sh"
14+
"seed": "./.npm-scripts/seed.sh"
1515
},
1616
"keywords": [
1717
"typescript",
File renamed without changes.

scripts/migration/db/index.ts scripts/seed/db/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { connect } = require('../../../scripts/migration/db/connect.ts');
1+
const { connect } = require('../../../scripts/seed/db/connect.ts');
22
const pool = connect();
33

44
const db = {
File renamed without changes.

scripts/migration/todo-list/index.ts scripts/seed/todo-list/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
var fs = require('fs');
2-
var { db } = require('../../../scripts/migration/db/index.ts');
3-
const data = require('../../../scripts/migration/todo-list/data.json')
2+
var { db } = require('../../../scripts/seed/db/index.ts');
3+
const data = require('../../../scripts/seed/todo-list/data.json');
44

55
const todoListItems = [];
66

src/graphql/resolver.ts

+19-6
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,27 @@ type Resolver = {
77

88
export function getResolver() {
99
let resolver: Resolver = {};
10-
// Register resolvers
11-
const files = readdirSync('./src/graphql/resolvers');
1210

13-
files.forEach(name => {
14-
const fileName = `${path.resolve(__dirname, 'resolvers')}/${name}`;
11+
// Register Query to resolvers
12+
const queries = readdirSync('./src/graphql/resolvers/queries');
13+
queries.forEach(name => {
14+
const fileName = `${path.resolve(__dirname, 'resolvers/queries')}/${name}`;
1515
const module = require(fileName);
16-
resolver.Query = (module.default && module.default.Query) ? { ...resolver.Query, ...module.default.Query } : {};
17-
resolver.Mutation = (module.default && module.default.Mutation) ? { ...resolver.Mutation, ...module.default.Mutation } : {};
16+
resolver.Query = {
17+
...resolver.Query,
18+
...module,
19+
};
20+
});
21+
22+
// Register Mutation to resolvers
23+
const mutations = readdirSync('./src/graphql/resolvers/mutations');
24+
mutations.forEach(name => {
25+
const fileName = `${path.resolve(__dirname, 'resolvers/mutations')}/${name}`;
26+
const module = require(fileName);
27+
resolver.Mutation = {
28+
...resolver.Mutation,
29+
...module,
30+
};
1831
});
1932

2033
// Register scalar types
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { DB, QueryConfig, APIResponse } from '../../../types';
2+
import { TodoListItem } from '../../../models';
3+
4+
export async function createTodoItem(db: DB, args: any) {
5+
const {
6+
item: { content },
7+
} = args;
8+
9+
const query: QueryConfig = {
10+
text: `INSERT INTO todo_list(content) VALUES($1) RETURNING *`,
11+
values: [content],
12+
};
13+
14+
const result = await db.query(query);
15+
const response: APIResponse<TodoListItem> = {
16+
status: 'fetching',
17+
};
18+
19+
try {
20+
if (result.rowCount > 0) {
21+
const data = result.rows.map((item: TodoListItem) => {
22+
return {
23+
id: item.id,
24+
content: item.content,
25+
createdAt: item.created_at,
26+
updatedAt: item.updated_at,
27+
};
28+
});
29+
response.status = 'success';
30+
response.data = data;
31+
}
32+
} catch (e) {
33+
response.status = 'error';
34+
}
35+
36+
return response;
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { DB, QueryConfig, APIResponse } from '../../../types';
2+
import { TodoListItem } from '../../../models';
3+
4+
export async function deleteTodoItem(db: DB, args: any) {
5+
const { id } = args;
6+
7+
const query: QueryConfig = {
8+
text: `DELETE FROM todo_list WHERE id = $1 RETURNING *`,
9+
values: [id],
10+
};
11+
12+
const result = await db.query(query);
13+
const response: APIResponse<TodoListItem> = {
14+
status: 'fetching',
15+
};
16+
17+
try {
18+
if (result.rowCount > 0) {
19+
const data = result.rows.map((item: TodoListItem) => {
20+
return {
21+
id: item.id,
22+
content: item.content,
23+
createdAt: item.created_at,
24+
updatedAt: item.updated_at,
25+
};
26+
});
27+
response.status = 'success';
28+
response.data = data;
29+
} else {
30+
response.status = 'error';
31+
response.message = 'Record is not found';
32+
}
33+
} catch (e) {
34+
response.status = 'error';
35+
}
36+
37+
return response;
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { DB, QueryConfig, APIResponse } from '../../../types';
2+
import { TodoListItem } from '../../../models';
3+
4+
export async function updateTodoItem(db: DB, args: any) {
5+
const {
6+
id,
7+
item: { content },
8+
} = args;
9+
10+
const query: QueryConfig = {
11+
text: `UPDATE todo_list SET content = $2 WHERE id = $1 RETURNING *`,
12+
values: [id, content],
13+
};
14+
15+
const result = await db.query(query);
16+
const response: APIResponse<TodoListItem> = {
17+
status: 'fetching',
18+
};
19+
20+
try {
21+
if (result.rowCount > 0) {
22+
const data = result.rows.map((item: TodoListItem) => {
23+
return {
24+
id: item.id,
25+
content: item.content,
26+
createdAt: item.created_at,
27+
updatedAt: item.updated_at,
28+
};
29+
});
30+
response.status = 'success';
31+
response.data = data;
32+
}
33+
} catch (e) {
34+
response.status = 'error';
35+
}
36+
37+
return response;
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { DB, QueryConfig, APIResponse } from '../../../types';
2+
import { TodoListItem } from '../../../models';
3+
4+
export async function todoListItems(db: DB, args: any) {
5+
let query: QueryConfig = { text: 'SELECT * FROM todo_list' };
6+
7+
if (args && args.keyword) {
8+
query = {
9+
text: `SELECT * FROM todo_list WHERE content LIKE '%' || $1 || '%'`,
10+
values: [args.keyword],
11+
};
12+
}
13+
14+
const result = await db.query(query);
15+
16+
const response: APIResponse<TodoListItem[]> = {
17+
status: 'fetching',
18+
};
19+
20+
try {
21+
if (result.rowCount > 0) {
22+
const data = result.rows.map((item: TodoListItem) => {
23+
return {
24+
id: item.id,
25+
content: item.content,
26+
createdAt: item.created_at,
27+
updatedAt: item.updated_at,
28+
};
29+
});
30+
response.status = 'success';
31+
response.data = data;
32+
}
33+
} catch (e) {
34+
response.status = 'error';
35+
}
36+
37+
return response;
38+
}

src/graphql/resolvers/todo-list.ts

-44
This file was deleted.

0 commit comments

Comments
 (0)