Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ Build an API inside the `api` folder with endpoints for:
Be prepared to demonstrate your understanding of this week's concepts by answering questions on the following topics. You might prepare by writing down your own answers before hand.

1. Explain the difference between Relational Databases and SQL.

In relational database, the data is stored in tabular format grouped into rows and columns (similar to spreadsheets). A collection of rows is called a table. Each row represents a single record in the table and is made up of one or more columns.
These kinds of databases are relational because relation is a mathematical idea equivalent to a table. So relational databases are databases that store their data in tables, while SQL is a standard language, which means that it will certainly be supported, no matter how your database is managed.

2. Why do tables need a Primary Key?

A primary key is the identifier of a piece of data, everything else are just attributes to that number. If you ever want to reference that data from another table you have to use that Primary Key as a Foreign Key in the other table

3. What is the name given to a table column that references the Primary Key on another table?

Foreign Key => They are a type of table field used for creating links between tables.

4. What do we need in order to have a _many to many_ relationship between two tables?

We need to introduce an intermediary table that holds foreign keys that reference the primary key on the related tables to model this relationship.
34 changes: 33 additions & 1 deletion api/project/model.js
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
// build your `Project` model here
const db = require('../../data/dbConfig')

async function getProjects() {
const projects = await db('projects')

return projects.map((project) => {
return {
...project,
project_completed: project.project_completed === 1,
}
})
}

async function findById (id) {
const row = await db('projects')
.where('project_id', id)
.first();
return {
...row,
project_completed: row.project_completed ? true : false
}
}

async function insert (project) {
const [id] = await db('projects')
.insert(project)
return findById(id)
}

module.exports = {
getProjects,
insert
}
23 changes: 22 additions & 1 deletion api/project/router.js
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
// build your `/api/projects` router here
const router = require('express').Router()
const Project = require('./model')

router.get('/', (req, res, next) => {
Project.getProjects()
.then((projects) => {
res.json(projects)
})
.catch(next)
})

router.post('/', async (req, res, next) => {
try {
const project = await Project
.insert(req.body);
res.status(201).json(project)
} catch (err) {
next(err)
}
})

module.exports = router
23 changes: 22 additions & 1 deletion api/resource/model.js
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
// build your `Resource` model here
const db = require('../../data/dbConfig')

async function findAll () {
return db('resources');
}

function findById (id) {
return db('resources')
.where('resource_id', id)
.first();
}

async function insert (resource) {
const [id] = await db('resources')
.insert(resource);
return findById(id)
}

module.exports = {
findAll,
insert
}
23 changes: 22 additions & 1 deletion api/resource/router.js
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
// build your `/api/resources` router here
const router = require('express').Router()
const Resource = require ('./model');

router.get('/', async (req, res, next) => {
try{
const resources = await Resource.findAll();
res.status(200).json(resources);
}catch (err){
next(err);
}
})

router.post('/', async (req, res, next) => {
try {
const resource = await Resource.insert(req.body);
res.status(201).json(resource)
} catch (err) {
next(err);
}
})

module.exports = router
30 changes: 29 additions & 1 deletion api/server.js
Original file line number Diff line number Diff line change
@@ -1 +1,29 @@
// build your server here and require it from index.js
const express = require('express')

const projectRouter = require('./project/router')
const resourceRouter = require('./resource/router')
const taskRouter = require('./task/router')

const server = express()

server.use(express.json())

server.use('/api/projects', projectRouter)
server.use('/api/resources', resourceRouter)
server.use('/api/tasks', taskRouter)

server.use('*', (req, res, next) => {
next({
status: 404,
message: 'This endpoint does not exist'
})
})

server.use((err, req, res, next) => { //eslint-disable-line
res.status(500).json({
message: err.message,
stack: err.message
})
})

module.exports = server
36 changes: 35 additions & 1 deletion api/task/model.js
Original file line number Diff line number Diff line change
@@ -1 +1,35 @@
// build your `Task` model here
const db = require('../../data/dbConfig')

async function findAll () {
const rows = await db('tasks as t')
.join('projects as p', 'p.project_id', 't.project_id')
.select('t.*', 'p.project_name', 'p.project_description')
return rows.map(item => {
return {
...item,
task_completed: item.task_completed ? true : false
}});
}

async function findById (id) {
const row = await db('tasks as t')
.join('projects as p', 'p.project_id', 't.project_id')
.select('t.*', 'p.project_name', 'p.project_description')
.where('task_id', id)
.first()
return {
...row,
task_completed: row.task_completed ? true : false
}
}

async function insert (task) {
const [id] = await db('tasks')
.insert(task)
return findById(id)
}

module.exports = {
findAll,
insert
}
23 changes: 22 additions & 1 deletion api/task/router.js
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
// build your `/api/tasks` router here
const router = require('express').Router()
const Task = require('./model')

router.get('/', async (req, res, next) => {
try {
const tasks = await Task.findAll();
res.status(200).json(tasks)
} catch (err) {
next(err);
}
});

router.post('/', async (req, res, next) => {
try {
const task = await Task.insert(req.body);
res.status(201).json(task);
} catch (err) {
next(err);
}
});

module.exports = router
59 changes: 59 additions & 0 deletions data/migrations/20211105170953_first-migration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

exports.up = async function(knex) {
await knex.schema
.createTable('projects', (table) => {
table.increments('project_id')
table.string('project_name', 128)
.notNullable()
table.string('project_description', 255)
table.boolean('project_completed')
.defaultTo(false)
})
.createTable('resources', (table) => {
table.increments('resource_id')
table.string('resource_name', 128)
.notNullable()
.unique()
table.string('resource_description', 255)
})
.createTable('tasks', (table) => {
table.increments('task_id')
table.string('task_description', 255)
.notNullable()
table.string('task_notes', 255)
table.boolean('task_completed')
.defaultTo(false)
table.integer('project_id')
.unsigned()
.notNullable()
.references('project_id')
.inTable('projects')
.onDelete('RESTRICT')
.onUpdate('RESTRICT')
})
.createTable('project_resources', (table) => {
table.increments('project_resource_id')
table.integer('project_id')
.notNullable()
.unsigned()
.references('project_id')
.inTable('projects')
.onDelete('RESTRICT')
.onUpdate('RESTRICT')
table.integer('resource_id')
.notNullable()
.unsigned()
.references('resource_id')
.inTable('resources')
.onDelete('RESTRICT')
.onUpdate('RESTRICT')
})
}

exports.down = async function(knex) {
await knex.schema
.dropTableIfExists('project_resources')
.dropTableIfExists('tasks')
.dropTableIfExists('resources')
.dropTableIfExists('projects')
}
8 changes: 8 additions & 0 deletions data/seeds/00_cleaner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const cleaner = require('knex-cleaner');

exports.seed = function(knex) {
return cleaner.clean(knex, {
mode: 'truncate', // resets ids
ignoreTables: ['knex_migrations', 'knex_migrations_lock'], // don't empty migration tables
});
};
20 changes: 20 additions & 0 deletions data/seeds/01_projects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

exports.seed = async function(knex) {
return await knex('projects').insert([
{
project_name: "project_1",
project_description: "1st project",
project_completed: false,
},
{
project_name: "project_2",
project_description: "2nd project",
project_completed: true,
},
{
project_name: "project_3",
project_description: "3rd project",
project_completed: false,
},
])
}
41 changes: 41 additions & 0 deletions data/seeds/02_tasks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

exports.seed = async function(knex) {
return await knex('tasks').insert([
{
task_description: "task_1",
task_notes: "project_1's 1st task",
task_completed: false,
project_id: 1,
},
{
task_description: "task_2",
task_notes: "project_1's 2nd task",
task_completed: false,
project_id: 1,
},
{
task_description: "task_3",
task_notes: "project_1's 3rd task",
task_completed: false,
project_id: 1,
},
{
task_description: "task_4",
task_notes: "project_2's 1st task",
task_completed: true,
project_id: 2,
},
{
task_description: "task_5",
task_notes: "project_3's 1st task",
task_completed: false,
project_id: 3,
},
{
task_description: "task_6",
task_notes: "project_3's 2nd task",
task_completed: false,
project_id: 3,
},
])
}
21 changes: 21 additions & 0 deletions data/seeds/03_resources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

exports.seed = async function(knex) {
return await knex('resources').insert([
{
resource_name: "resource_1",
resource_description: "1st resource",
},
{
resource_name: "resource_2",
resource_description: "2nd resource",
},
{
resource_name: "resource_3",
resource_description: "3rd resource",
},
{
resource_name: "resource_4",
resource_description: "4th resource",
},
])
}
21 changes: 21 additions & 0 deletions data/seeds/04_project_resources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

exports.seed = async function(knex) {
return await knex('project_resources').insert([
{
project_id: 1,
resource_id: 1,
},
{
project_id: 1,
resource_id: 2,
},
{
project_id: 2,
resource_id: 3,
},
{
project_id: 3,
resource_id: 4,
},
])
}
Loading