Skip to content

Commit

Permalink
modularise saveProfileData quries
Browse files Browse the repository at this point in the history
relates #36
  • Loading branch information
LawEKS committed May 14, 2018
1 parent 4ac3b1c commit bec14e5
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 112 deletions.
10 changes: 10 additions & 0 deletions src/lib/makeFacCodeName.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const makeFacCodeName = (facCampus, facNumber) => {
const prefix = {
london: 'FAC',
nazareth: 'FACN',
gaza: 'FACG',
}[facCampus.toLowerCase()];
return `${prefix}${facNumber}`;
};

module.exports = makeFacCodeName;
8 changes: 8 additions & 0 deletions src/model/queries/addFacCodeReturnID.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const dbConnection = require('../database/db_connection');

const addFacCodeReturnID = codeName => dbConnection.query(
'INSERT INTO fac_code (code) VALUES ($1) RETURNING id',
[codeName],
).then(res => res[0]);

module.exports = addFacCodeReturnID;
5 changes: 5 additions & 0 deletions src/model/queries/getAllFacCodes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const dbConnection = require('../database/db_connection');

const getAllFacCodes = () => dbConnection.query('SELECT * FROM fac_code');

module.exports = getAllFacCodes;
6 changes: 6 additions & 0 deletions src/model/queries/getFacCodeID.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const dbConnection = require('../database/db_connection');

const getFacCodeID = codeName => dbConnection.query('SELECT id FROM fac_code WHERE code = $1', [codeName])
.then(res => res[0]);

module.exports = getFacCodeID;
127 changes: 15 additions & 112 deletions src/model/queries/saveProfileData.js
Original file line number Diff line number Diff line change
@@ -1,115 +1,18 @@
const dbConnection = require('../database/db_connection');
const addFacCodeReturnID = require('./addFacCodeReturnID');
const getFacCodeID = require('./getFacCodeID');
const updateMemberDetails = require('./updateMemberDetails');
const makeFacCodeName = require('../../lib/makeFacCodeName');

// const formData = {
// full_name: 'Helen',
// github_handle: 'helenzhou6',
// fac_campus: 'London',
// fac_number: '0',
// tech_stack: 'Java',
// linkedin_url: 'knowwhere.com',
// twitter_handle: 'helenTweetz',
// };

/*
* There are a number of steps required to save from data into the database.
*
* The form uses fac_number but the members table requires fac_code_id
* so a query is needed to get the id
* and INSERT INTO the table if what we are looking for does not exist
*
* With the fac_code_id and github_id (provided by router) we can update the
* the members table with the values needed and return the
* member id for member_tech_stack_table
*
* The form also provides tech_stack and there is a member_tech_stack table
* which requires a stack_id, member_id and optional order (I thick this should default to 1)
*
* A query is required to get the stack_id
* and INSERT INTO the table if what we are looking for does not exist
*
* To insert into member_tech_stack we need member_id and stack_id at the same time.
* Using Promise.all(), query updateMemberGetID and getTechStack
* use the response values to query and insert into member_tech_stack
*
* TODO: modularise queries in file and test
*/

// transform query result into an object
const toResObj = res => res[0];

// insert code into fac_code table and return id
const addFacCode = codeName => dbConnection.query(
'INSERT INTO fac_code (code) VALUES ($1) RETURNING id',
[codeName],
).then(toResObj);

// use form data to create fac code neame needed for fac_code table
const makeFacCodeName = (facCampus, facNumber) => {
const prefix = {
london: 'FAC',
nazareth: 'FACN',
gaza: 'FACG',
}[facCampus.toLowerCase()];
return `${prefix}${facNumber}`;
};

// get fac code id for memeber table
const getFacCodeID = (facCampus, facNumber) => {
const codeName = makeFacCodeName(facCampus, facNumber);
return dbConnection.query('SELECT id FROM fac_code WHERE code = $1', [codeName])
.then(res => res[0] || addFacCode(codeName))
.then(o => o.id);
};

// query must be an update because a member is created during authentication
// the id returned is used to insert into member_tech_Stack
const updateMemberGetID = (formDataObj, facCodeID, githubID) => dbConnection.query(`
UPDATE members
SET full_name = $/full_name/,
github_handle = $/github_handle/,
fac_campus = $/fac_campus/,
fac_code_id = $/facCodeID/,
linkedin_url = $/linkedin_url/,
twitter_handle = $/twitter_handle/
WHERE github_id = $/githubID/ RETURNING id
`, { ...formDataObj, facCodeID, githubID })
.then(toResObj)
.then(res => ({ member_id: res.id }));

// query will insert a tech to tech_stack table and return member_id object
const addTechStack = name => dbConnection.query(
'INSERT INTO tech_stack (tech) VALUES ($1) RETURNING id',
[name],
).then(toResObj);

// query will return the stack_id object of a tech and insert it if it does not exist
const getTechStackID = tech => dbConnection.query(
'SELECT id FROM tech_stack WHERE tech = $1',
[tech],
)
.then(res => res[0] || addTechStack(tech))
.then(res => ({ stack_id: res.id }));

// transform promise.all()result array into an object
const promiseAllResultToObj = arr => arr.reduce((acc, curr) => Object.assign(acc, curr), {});

// insert member_id and stack_id into member_tech_stack
// need to handle error for when query tries to insert a stack that someone already has
const addMemberTechStack = idObj => dbConnection.query(
'INSERT INTO member_tech_stack ($/this:name/) VALUES ($/this:list/) RETURNING *',
idObj,
)
.then(toResObj);


// module.exports = saveProfileData;
module.exports = (dataObj, githubID) => {
exports.saveProfileData = (dataObj, githubID) => {
const objClone = JSON.parse(JSON.stringify(dataObj));
return getFacCodeID(objClone.fac_campus, objClone.fac_number)
.then(facCodeID => Promise.all([
updateMemberGetID(objClone, facCodeID, githubID),
getTechStackID(objClone.tech_stack),
]))
.then(promiseAllResultToObj)
.then(addMemberTechStack);
const codeName = makeFacCodeName(objClone.fac_campus, objClone.fac_number);
return getFacCodeID(codeName)
.then((resObj) => {
if (Object.keys(resObj).length === 0) {
return addFacCodeReturnID(codeName);
}
return resObj;
})
.then(facCodeID => updateMemberDetails(objClone, facCodeID.id, githubID));
};

14 changes: 14 additions & 0 deletions src/model/queries/updateMemberDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const dbConnection = require('../database/db_connection');

const updateMemberDetails = (formDataObj, facCodeID, githubID) => dbConnection.query(`
UPDATE members
SET full_name = $/full_name/,
github_handle = $/github_handle/,
fac_campus = $/fac_campus/,
fac_code_id = $/facCodeID/,
linkedin_url = $/linkedin_url/,
twitter_handle = $/twitter_handle/
WHERE github_id = $/githubID/
`, { ...formDataObj, facCodeID, githubID });

module.exports = updateMemberDetails;
55 changes: 55 additions & 0 deletions src/test/db.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const runDbBuild = require('../model/database/db_build_test');
const dbConnection = require('../model/database/db_connection');
const postMemberInfo = require('../model/queries/postMemberInfo.js');
const getMemberData = require('../model/queries/getMemberData.js');
const getAllFacCodes = require('../model/queries/getAllFacCodes.js');
const addFacCodeReturnID = require('../model/queries/addFacCodeReturnID');
const getFacCodeID = require('../model/queries/getFacCodeID');

const selectAllMembers = 'SELECT * FROM members';

Expand Down Expand Up @@ -112,6 +115,58 @@ test('Test postMemberInfo adds a row', (t) => {
});
});

// ADD FACCODE
test('Add fac code to fac_code table and return id', (t) => {
const facCode = 'FAC13';
let original;
runDbBuild()
.then(getAllFacCodes)
.then((res) => {
original = res;
})
.then(() => addFacCodeReturnID(facCode))
.then((res) => {
t.equal(typeof res, 'object', 'db response is an object');
t.deepEqual(Object.keys(res), ['id'], 'res is an object containing an id');
t.end();
})
.then(getAllFacCodes)
.then((res) => {
t.equal(res.length, original.length + 1, 'added one row to fac codes table');
t.deepEqual(res[res.length - 1].code, facCode, 'added FAC13');
})
.catch((error) => {
t.error(error, 'no db error');
t.end();
});
});

// getAllFacCodes
test('Test get all FAC codes', (t) => {
runDbBuild()
.then(() => getAllFacCodes())
.then((res) => {
t.ok(Array.isArray(res), 'db response is an array');
t.end();
})
.catch((error) => {
t.error(error, 'no db error');
t.end();
});
});

// getFacCodeID
test('Test get fac code id', (t) => {
const facCode = 'FAC0';
runDbBuild()
.then(() => getFacCodeID(facCode))
.then((res) => {
t.equal(typeof res, 'object', 'db response is an object');
t.deepEqual(Object.keys(res), ['id'], 'res is an object containing an id');
t.end();
});
});

test.onFinish(() => {
dbConnection.$pool.end();
});

0 comments on commit bec14e5

Please sign in to comment.