Skip to content

Commit

Permalink
crud helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
Pankaj Patel committed Oct 1, 2019
1 parent 8043d10 commit 8c6cf07
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 78 deletions.
4 changes: 4 additions & 0 deletions .env.example
@@ -0,0 +1,4 @@
DB_HOST=localhost
DB_USER=root
DB_PASS=
DB_DATABASE=twitter_clone
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -61,3 +61,4 @@ typings/
.next

*.spf
.env
68 changes: 68 additions & 0 deletions README.md
Expand Up @@ -17,3 +17,71 @@ You cna run this collection in Postman with following button:


Or Download and import in Postman from here: <a href="./Twitter Clone.postman_collection.json" download>Download</a>

-----

```sql
CREATE DATABASE twitter_clone;

use twitter_clone;

CREATE TABLE users(
id int NOT NULL AUTO_INCREMENT,
username varchar(15) NOT NULL,
password varchar(32) NOT NULL,
followers int DEFAULT 0,
following int DEFAULT 0,
tweets int DEFAULT 0,
PRIMARY KEY (id)
);

CREATE TABLE following(
id int NOT NULL AUTO_INCREMENT,
user1_id int REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
user2_id int REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (id)
);

CREATE TABLE tweets(
id int NOT NULL AUTO_INCREMENT,
username varchar(15) NOT NULL,
user_id int REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
tweet varchar(140) NOT NULL,
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);

INSERT INTO USERS(username, password) VALUE('pankaj', MD5('pankaj'));

INSERT INTO USERS(username, password) VALUE('tim', MD5('tim'));

INSERT INTO USERS(username, password) VALUE('jim', MD5('jim'));

INSERT INTO TWEETS(username, user_id, tweet) VALUE('pankaj', 1, 'Hello World Again!');

INSERT INTO FOLLOWING(user1_id, user2_id) VALUE(1, 2);
INSERT INTO FOLLOWING(user1_id, user2_id) VALUE(1, 3);
INSERT INTO FOLLOWING(user1_id, user2_id) VALUE(3, 1);

SELECT * FROM tweets;

# Followers

SELECT
USER_INFO.*, username as user1_username
FROM (SELECT
user1_id, user2_id, username as user2_username
FROM FOLLOWING LEFT JOIN USERS ON user2_id = users.id
WHERE user1_id = 1) as USER_INFO
LEFT JOIN USERS ON user1_id = users.id ;

# Following

SELECT
USER_INFO.*, username as user1_username
FROM (SELECT
user1_id, user2_id, username as user2_username
FROM FOLLOWING LEFT JOIN USERS ON user2_id = users.id
WHERE user2_id = 1) as USER_INFO
LEFT JOIN USERS ON user1_id = users.id ;
```
54 changes: 38 additions & 16 deletions Twitter Clone.postman_collection.json
Expand Up @@ -2,7 +2,7 @@
"info": {
"_postman_id": "78149020-40a3-4657-80a9-7683bdae2c78",
"name": "Twitter Clone",
"description": "This collection is created to help understand the Rest API creation on Node.js with Express and MySQL\n\nThe original article can be found here: https://time2hack.com/2019/09/creating-rest-api-in-node-js-with-express-and-mysql",
"description": "This collection is created to help understand the Rest API creation on Node.js with Express and MySQL\n\nThe original article can be found here: https://time2hack.com/2019/09/creating-rest-api-in-node-js-with-express-and-mysql/",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
Expand Down Expand Up @@ -223,12 +223,12 @@
"urlencoded": [
{
"key": "username",
"value": "jim",
"value": "r_{{$randomUserName}}",
"type": "text"
},
{
"key": "password",
"value": "jim",
"value": "random-password",
"type": "text"
}
]
Expand All @@ -241,18 +241,6 @@
"path": [
"auth",
"register"
],
"query": [
{
"key": "username",
"value": "",
"disabled": true
},
{
"key": "password",
"value": "",
"disabled": true
}
]
},
"description": "# Register New User\n---\n\n## Params\n\n`username`: `String`\n`password`: `String`\n\nReturns the new User's ID and Set's to Environment"
Expand Down Expand Up @@ -319,12 +307,46 @@
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "9f38fe7c-852d-47ea-94c0-a30a02fe80f1",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "fbd831b3-89ea-4af7-9e1c-b34bd57dba5e",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"variable": [
{
"id": "363978da-cd5b-42e5-97e7-a8f9aab3fbd0",
"id": "163f6187-2a19-4028-b6d8-ec8709bc560b",
"key": "url",
"value": "http://localhost:3000",
"type": "string"
},
{
"id": "974aa83a-3a22-483b-8363-e514a2742d5e",
"key": "user",
"value": "1",
"type": "string"
},
{
"id": "ddcb6d1f-4270-4364-bdcf-5e75ec9afeb4",
"key": "randomPassword",
"value": "random-password",
"type": "string"
}
],
"protocolProfileBehavior": {}
Expand Down
20 changes: 12 additions & 8 deletions app-middlewares/auth.js
Expand Up @@ -5,19 +5,23 @@ const query = require('../helpers/query');
const router = express.Router();
const dbConfig = require('../dbConfig');

const create = require('../crud/create');

router.post('/register', async (req, res) => {
const { username, password } = req.body;
const conn = await connection(dbConfig).catch(e => {});
const user = await query(
const result = await create(
conn,
`INSERT INTO USERS(username, password) VALUE(?, MD5(?));`,
[username, password]
'USERS',
['username', 'password'],
[username, { toString: () => `MD5('${password}')`}]
);
if (user.insertId) {
res.send(await query(conn, `SELECT id, username FROM USERS WHERE ID=?`, [user.insertId]))
return;
}
res.send({ id: null, username: null });

const [user = {}] = result;
res.send({
id: user.id || null,
username: user.username || null,
});
});

router.post('/login', async (req, res) => {
Expand Down
20 changes: 20 additions & 0 deletions crud/create.js
@@ -0,0 +1,20 @@
const query = require('../helpers/query');
const valuesForQuery = require('../helpers/values-for-insert');

/**
* @param {} conn MySQL Connection reference
* @param {String} table Table to insert the values
* @param {[String]} columns Array of column names
* @param {[String]} values Array of values for those column names, can be multidientional
*/
module.exports = async (conn, table, columns, values) => {
const VALUES = valuesForQuery(values)
try {
const user = await query(conn, `INSERT INTO ${table}(${columns.join(', ')}) VALUES ${VALUES};`);
if (user.insertId) {
console.log(user.insertId);
return await query(conn, `SELECT * FROM ${table} WHERE ID=?`, [user.insertId]);
}
return user;
} catch(e) { console.log(e)}
}
4 changes: 4 additions & 0 deletions dbConfig.js
@@ -1,3 +1,7 @@
const dotenv = require("dotenv")

dotenv.config();

// Get the Host from Environment or use default
const host = process.env.DB_HOST || 'localhost';

Expand Down
2 changes: 1 addition & 1 deletion helpers/query.js
Expand Up @@ -8,4 +8,4 @@ module.exports = async (conn, q, params) => new Promise(
resolve(result);
}
conn.query(q, params, handler);
});
}).catch(console.log);
38 changes: 38 additions & 0 deletions helpers/values-for-insert.js
@@ -0,0 +1,38 @@
/**
* @param {[String]} values Array of values for those column names
*/
const valueForQuery = (_values) => {
const values = _values.map(item => {
let val;
switch (typeof item) {
case 'number':
return item;
case 'string':
val = item;
break;
default:
return item.toString();
}
return `'${val}'`;
})
return `(${values.join(', ')})`;
};

/**
* @param {[String]} values Array of values for those column names, can be multidientional
*/
const valuesForQuery = (values) => {
const value = values[0];
let VALUES = '';
if (value instanceof Array) {
VALUES = values.map(valueForQuery).join(', ')
} else {
VALUES = valueForQuery(values);
}
return VALUES;
}

module.exports = {
valueForQuery,
valuesForQuery,
}

0 comments on commit 8c6cf07

Please sign in to comment.