From 85f869a64a90bcd35c18909251269e933aa42cb0 Mon Sep 17 00:00:00 2001 From: ryanwong Date: Sun, 6 Feb 2022 20:33:09 -0500 Subject: [PATCH] day 2 --- day_1/README.md | 2 + day_2/README.md | 48 ++++++++++++++++ day_2/app.js | 44 +++++++++++++++ day_2/bin/www | 90 ++++++++++++++++++++++++++++++ day_2/models/index.js | 68 ++++++++++++++++++++++ day_2/models/location.js | 21 +++++++ day_2/package.json | 19 +++++++ day_2/public/stylesheets/style.css | 8 +++ day_2/routes/index.js | 9 +++ day_2/routes/users.js | 9 +++ day_2/views/error.jade | 6 ++ day_2/views/index.jade | 5 ++ day_2/views/layout.jade | 7 +++ 13 files changed, 336 insertions(+) create mode 100644 day_2/app.js create mode 100755 day_2/bin/www create mode 100644 day_2/models/index.js create mode 100644 day_2/models/location.js create mode 100644 day_2/package.json create mode 100644 day_2/public/stylesheets/style.css create mode 100644 day_2/routes/index.js create mode 100644 day_2/routes/users.js create mode 100644 day_2/views/error.jade create mode 100644 day_2/views/index.jade create mode 100644 day_2/views/layout.jade diff --git a/day_1/README.md b/day_1/README.md index a07a288..3cf0aae 100644 --- a/day_1/README.md +++ b/day_1/README.md @@ -16,12 +16,14 @@ shipping_dock transaction - id - order_id +- user_id - shipping_dock_id - amount - notes order - id +- user_id - amount - tax - notes diff --git a/day_2/README.md b/day_2/README.md index e69de29..38cd8ee 100644 --- a/day_2/README.md +++ b/day_2/README.md @@ -0,0 +1,48 @@ +# day 2 + +## Instructions + +- Make the following API + +``` +GET /api/v1/order/odd (Return all odd order_id rows) + +GET /api/v1/order?page=1&limit=10 +(paginate the orders. If limit is 10, total pages = # of order / limit. if page = 2 and limit = 10, you return results from item #10 to #20. Create a service to handle this. Response format: +{ + total: 10, + page: 1, + list: [] +}) + +GET /api/v1/order?page=1&limit=10&sort=id&direction=DESC +(paginate the orders. Sort the rows by the field specified in sort. Direction is DESC or ASC. If DESC sort descending order. If ASC sort ascending order. Should work on any field. Response format: +{ + total: 10, + page: 1, + list: [] +}) + +GET /api/v1/order/cursor?id=20&limit=10 +(paginate the orders using cursor method. So if id = 20, then you return 10 rows that are greater than id 20. Response format: +{ + id: 20 + list: [] +}) + +https://stackoverflow.com/questions/18314687/how-to-implement-cursors-for-pagination-in-an-api + +GET /api/v1/report/sale?month=1&year (given the month and year, return total amount for month and year specified) + +GET /api/v1/report/sale?from_date=2022-01-01&to_date=2022-02-02 (given from and to date, calculate total amount in date range. If the date are swapped, check which one earlier) + +GET /api/v1/report/monthly?year=2022 (given the year, calculate and return sale amount per month for that year. If sale for that month 0 don't return it. Use 1 query) + +GET /api/v1/report/user?year=2022&user_id=1 (given the year, calculate and return sale amount per month for that year by user_id. If sale for that month 0 don't return it. Use 1 query) + +GET /api/v1/report/shipping_dock?year=2022&shipping_dock_id=1 (given the year, calculate and return sale amount per month for that year by shipping_dock_id. If sale for that month 0 don't return it.Use 1 query) + +GET /api/v1/report/user/count?year=2022&user_id=1 (given the year, calculate # of orders per month from that user and return # order and month. If month has 0 sale, return 0 with the month. Use 1 query) +``` + +- Everything must be done by end of date diff --git a/day_2/app.js b/day_2/app.js new file mode 100644 index 0000000..97a1728 --- /dev/null +++ b/day_2/app.js @@ -0,0 +1,44 @@ +var createError = require('http-errors'); +var express = require('express'); +var path = require('path'); +var cookieParser = require('cookie-parser'); +var logger = require('morgan'); + +var indexRouter = require('./routes/index'); +var usersRouter = require('./routes/users'); + +const db = require("./models"); +var cors = require("cors"); + +var app = express(); +app.set("db", db); +// view engine setup +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'jade'); +app.use(cors()); +app.use(logger('dev')); +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); +app.use(cookieParser()); +app.use(express.static(path.join(__dirname, 'public'))); + +app.use('/', indexRouter); +app.use('/users', usersRouter); + +// catch 404 and forward to error handler +app.use(function (req, res, next) { + next(createError(404)); +}); + +// error handler +app.use(function (err, req, res, next) { + // set locals, only providing error in development + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + res.status(err.status || 500); + res.render('error'); +}); + +module.exports = app; diff --git a/day_2/bin/www b/day_2/bin/www new file mode 100755 index 0000000..cd1a62f --- /dev/null +++ b/day_2/bin/www @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var app = require('../app'); +var debug = require('debug')('day-1:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '3000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} diff --git a/day_2/models/index.js b/day_2/models/index.js new file mode 100644 index 0000000..39f447f --- /dev/null +++ b/day_2/models/index.js @@ -0,0 +1,68 @@ +'use strict'; +/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2020*/ +/** + * Sequelize File + * @copyright 2020 Manaknightdigital Inc. + * @link https://manaknightdigital.com + * @license Proprietary Software licensing + * @author Ryan Wong + * + */ +const fs = require('fs'); +const path = require('path'); +let Sequelize = require('sequelize'); +const basename = path.basename(__filename); +const config = { + DB_DATABASE: 'mysql', + DB_USERNAME: 'root', + DB_PASSWORD: 'root', + DB_ADAPTER: 'mysql', + DB_NAME: 'day_1', + DB_HOSTNAME: 'localhost', + DB_PORT: 3306, +}; + +let db = {}; + +let sequelize = new Sequelize(config.DB_DATABASE, config.DB_USERNAME, config.DB_PASSWORD, { + dialect: config.DB_ADAPTER, + username: config.DB_USERNAME, + password: config.DB_PASSWORD, + database: config.DB_NAME, + host: config.DB_HOSTNAME, + port: config.DB_PORT, + logging: console.log, + timezone: '-04:00', + pool: { + maxConnections: 1, + minConnections: 0, + maxIdleTime: 100, + }, + define: { + timestamps: false, + underscoredAll: true, + underscored: true, + }, +}); + +// sequelize.sync({ force: true }); + +fs.readdirSync(__dirname) + .filter((file) => { + return file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js'; + }) + .forEach((file) => { + var model = sequelize['import'](path.join(__dirname, file)); + db[model.name] = model; + }); + +Object.keys(db).forEach((modelName) => { + if (db[modelName].associate) { + db[modelName].associate(db); + } +}); + +db.sequelize = sequelize; +db.Sequelize = Sequelize; + +module.exports = db; \ No newline at end of file diff --git a/day_2/models/location.js b/day_2/models/location.js new file mode 100644 index 0000000..f0a885d --- /dev/null +++ b/day_2/models/location.js @@ -0,0 +1,21 @@ +module.exports = (sequelize, DataTypes) => { + const location = sequelize.define( + "location", + { + name: DataTypes.STRING, + created_at: DataTypes.DATEONLY, + updated_at: DataTypes.DATE, + }, + { + timestamps: true, + freezeTableName: true, + tableName: "location", + }, + { + underscoredAll: false, + underscored: false, + } + ); + + return location; +}; \ No newline at end of file diff --git a/day_2/package.json b/day_2/package.json new file mode 100644 index 0000000..219c20e --- /dev/null +++ b/day_2/package.json @@ -0,0 +1,19 @@ +{ + "name": "day-1", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "cookie-parser": "~1.4.4", + "cors": "^2.8.5", + "debug": "~2.6.9", + "express": "~4.16.1", + "http-errors": "~1.6.3", + "jade": "~1.11.0", + "morgan": "~1.9.1", + "mysql2": "^2.3.3", + "sequelize": "^6.15.1" + } +} diff --git a/day_2/public/stylesheets/style.css b/day_2/public/stylesheets/style.css new file mode 100644 index 0000000..9453385 --- /dev/null +++ b/day_2/public/stylesheets/style.css @@ -0,0 +1,8 @@ +body { + padding: 50px; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; +} + +a { + color: #00B7FF; +} diff --git a/day_2/routes/index.js b/day_2/routes/index.js new file mode 100644 index 0000000..ecca96a --- /dev/null +++ b/day_2/routes/index.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function(req, res, next) { + res.render('index', { title: 'Express' }); +}); + +module.exports = router; diff --git a/day_2/routes/users.js b/day_2/routes/users.js new file mode 100644 index 0000000..623e430 --- /dev/null +++ b/day_2/routes/users.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +router.get('/', function(req, res, next) { + res.send('respond with a resource'); +}); + +module.exports = router; diff --git a/day_2/views/error.jade b/day_2/views/error.jade new file mode 100644 index 0000000..51ec12c --- /dev/null +++ b/day_2/views/error.jade @@ -0,0 +1,6 @@ +extends layout + +block content + h1= message + h2= error.status + pre #{error.stack} diff --git a/day_2/views/index.jade b/day_2/views/index.jade new file mode 100644 index 0000000..3d63b9a --- /dev/null +++ b/day_2/views/index.jade @@ -0,0 +1,5 @@ +extends layout + +block content + h1= title + p Welcome to #{title} diff --git a/day_2/views/layout.jade b/day_2/views/layout.jade new file mode 100644 index 0000000..15af079 --- /dev/null +++ b/day_2/views/layout.jade @@ -0,0 +1,7 @@ +doctype html +html + head + title= title + link(rel='stylesheet', href='/stylesheets/style.css') + body + block content