Advertisement
Guest User

Untitled

a guest
Mar 1st, 2017
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.75 KB | None | 0 0
  1. 'use strict';
  2.  
  3. var express = require('express');
  4. var Promise = require('promise');
  5. var router = express.Router();
  6. var app = express();
  7.  
  8. var pool = require('./db.js')();
  9. var User = require('./models');
  10.  
  11. var PORT = 3000;
  12.  
  13. app.use(function (req, res, next) {
  14. pool.connect(function(error, client, done) {
  15. // Handle connection errors
  16. if (error) {
  17. done(error);
  18. console.log(error.message);
  19. return res.status(500)
  20. .json({success: false, data: error});
  21. }
  22. req.client = client;
  23. req.done = done;
  24. next();
  25. });
  26. });
  27.  
  28. router.get('/topActiveUsers', (req, res) => {
  29. topActiveUsers(req, res);
  30. });
  31.  
  32. router.get('/users', (req, res) => {
  33. userInfo(req, res);
  34. });
  35.  
  36. app.use(router);
  37.  
  38. app.get('*', function (req, res) {
  39. res.status(400).send('Invalid route');
  40. });
  41.  
  42. app.listen(PORT, function () {
  43. console.log('App listening on port ' + PORT);
  44. });
  45.  
  46. var topActiveUsers = function topActiveUsers(req, res) {
  47. var ENTRIES_PER_PAGE = 3;
  48. var startIndex = 0;
  49. var total = 0;
  50. req.query.page = +req.query.page || 0;
  51.  
  52. var pageNum = req.query.page > 0 ? req.query.page : 0;
  53. if (pageNum > 0) {
  54. startIndex = ENTRIES_PER_PAGE * (pageNum - 1);
  55. }
  56. total = ENTRIES_PER_PAGE * (pageNum + 1);
  57.  
  58. User.topActiveUsers(req)
  59. .then(function fullfilled(users) {
  60. if (users.length < startIndex) {
  61. throw new Error('Invalid pagination offset');
  62. }
  63. if (users.length > total) {
  64. users = users.slice(startIndex, startIndex + ENTRIES_PER_PAGE);
  65. } else {
  66. users = users.splice(startIndex);
  67. }
  68. return Promise.all(users.map(function (user) {
  69. return user.applicationListings(req);
  70. }));
  71. })
  72. .then(function fullfilled(users) {
  73. var result = users.map(function (user) {
  74. return {
  75. id: user.id,
  76. name: user.name,
  77. count: user._appliedListings.length,
  78. createdAt: user.createdAt,
  79. listings: user._appliedListings
  80. };
  81. });
  82. res.json(result);
  83. })
  84. .catch(function rejected(error) {
  85. console.log(error.message);
  86. throw error;
  87. })
  88. .finally(function () {
  89. res.end();
  90. });
  91. };
  92.  
  93. var userInfo = function userInfo(req, res) {
  94. User.getById(req)
  95. // run companies/listings/applications in "parallel"
  96. .then(function fullfilled(user) {
  97. return Promise.all([
  98. user.id,
  99. user.name,
  100. user.createdAt,
  101. user.companies(req),
  102. user.listings(req),
  103. user.applications(req)
  104. ]);
  105. })
  106. .then(function fullfilled([
  107. id, name, createdAt, companies, listings, applications]) {
  108. res.json({
  109. id: id,
  110. name: name,
  111. createdAt: createdAt,
  112. companies: companies,
  113. listings: listings,
  114. applications: applications
  115. });
  116. })
  117. .catch(function rejected(error) {
  118. console.log('error', error.message);
  119. throw error;
  120. })
  121. .finally(function () {
  122. res.end();
  123. });
  124. };
  125.  
  126. var Promise = require('promise');
  127.  
  128. module.exports = User;
  129.  
  130. /**
  131. * User m2m Company
  132. * User o2m Listing
  133. * User m2m applications
  134. */
  135. function User(opt_data) {
  136. var data = opt_data || {};
  137.  
  138. this.id = data['id'] || null;
  139. this.name = data['name'] || '';
  140. this.createdAt = data['created_at'] || new Date();
  141. this._companies = [];
  142. this._listings = [];
  143. this._applications = [];
  144. this._appliedListings = [];
  145. }
  146. User._RESOURCE_LIMIT = 5;
  147. var UserProto = User.prototype;
  148.  
  149. User.topActiveUsers = function topActiveUsers(req) {
  150. var queryString = "select * from users u inner join "+
  151. "(select user_id, count(id) cnt from applications "+
  152. "where id in (select id from applications where "+
  153. "created_at > current_date - interval '1 week') "+
  154. "group by user_id) a on u.id = a.user_id order by a.cnt desc";
  155. return queryPromise(req, queryString)
  156. .then(function fullfilled(result) {
  157. return result.rows.map(function(row) {
  158. return new User(row);
  159. });
  160. });
  161. };
  162.  
  163. User.getById = function getById(req) {
  164. var queryString = 'select * from users where id = $1::int';
  165. return queryPromise(req, queryString, [req.query.id])
  166. .then(function fullfilled(result) {
  167. return new User(result.rows[0]);
  168. });
  169. };
  170.  
  171. UserProto.companies = function companies(req) {
  172. var queryString = 'select c.id, c.name, t.contact_user '+
  173. 'from companies c, teams t '+
  174. 'where t.user_id = $1::int and t.company_id = c.id '+
  175. 'limit $2::int';
  176. return queryPromise(req, queryString, [this.id, User._RESOURCE_LIMIT])
  177. .then(function fullfilled(result) {
  178. return result.rows.map(function (data) {
  179. return new Company(data);
  180. });
  181. });
  182. };
  183.  
  184. UserProto.listings = function listings(req) {
  185. var queryString = 'select * from listings '+
  186. 'where created_by = $1::int '+
  187. 'limit $2::int';
  188. return queryPromise(req, queryString, [this.id, User._RESOURCE_LIMIT])
  189. .then(function fullfilled(result) {
  190. return result.rows.map(function (data) {
  191. return new Listing(data);
  192. });
  193. });
  194. };
  195.  
  196. UserProto.applicationListings = function applications(req) {
  197. var queryString = "select * from listings l inner join "+
  198. "(select listing_id, user_id, created_at from applications) a "+
  199. "on a.listing_id = l.id "+
  200. "where a.user_id = $1::int order by a.created_at desc limit 3";
  201. var self = this;
  202. return queryPromise(req, queryString, [this.id])
  203. .then(function fullfilled(result) {
  204. self._appliedListings = result.rows.map(function (data) {
  205. return new Listing(data);
  206. });
  207. return self;
  208. });
  209. };
  210.  
  211. UserProto.applications = function applications(req) {
  212. var queryString = 'select a.id as app_id, a.created_at, a.cover_letter, '+
  213. 'l.id as list_id, l.name, l.description '+
  214. 'from applications a, listings l '+
  215. 'where a.user_id = $1::int and a.listing_id = l.id '+
  216. 'limit $2::int';
  217. return queryPromise(req, queryString, [this.id, User._RESOURCE_LIMIT])
  218. .then(function fullfilled(result) {
  219. return result.rows.map(function (data) {
  220. return new Application(data);
  221. });
  222. });
  223. };
  224.  
  225. function Company(opt_data) {
  226. var data = opt_data || {};
  227. this.id = data['id'] || null;
  228. this.createdAt = data['created_at'] || new Date();
  229. this.name = data['name'] || '';
  230. this.isContact = false;
  231. }
  232.  
  233. function Listing(opt_data) {
  234. var data = opt_data || {};
  235. this.id = data['id'] || null;
  236. this.createdAt = data['created_at'] || new Date();
  237. this.name = data['name'] || '';
  238. this.description = data['description'] || '';
  239. }
  240.  
  241. function Application(opt_data) {
  242. var data = opt_data || {};
  243. this.id = data['id'] || null;
  244. this.createdAt = data['created_at'] || new Date();
  245. this.listing = data['listing'] || null;
  246. this.coverLetter = data['cover_letter'] || '';
  247. }
  248.  
  249. function queryPromise(req, queryString, queryParams, debug) {
  250. if (debug) {
  251. console.log(queryString, queryParams);
  252. req.client.connection.on('message', function(msg) {
  253. console.log(msg)
  254. });
  255. }
  256. return new Promise(function _promise(resolve, reject) {
  257. req.client.query(
  258. queryString,
  259. queryParams || [],
  260. function result(error, result) {
  261. req.done(error);
  262.  
  263. if (error) {
  264. console.log('error ' + error.message);
  265. return reject(error);
  266. }
  267. resolve(result);
  268. });
  269. });
  270. };
  271.  
  272. var pg = require('pg');
  273.  
  274. module.exports = function() {
  275. var config = {
  276. port: 5432,
  277. max: 10,
  278. idleTimeoutMillis: 30000
  279. };
  280. switch (process.env.NODE_ENV) {
  281. case 'development':
  282. config.host = 'localhost';
  283. config.user = 'vivek';
  284. config.password = 'admin';
  285. config.database = 'jobbatical';
  286. break;
  287. case 'production':
  288. config.user = 'rragdkrc37';
  289. config.database = 'rragdkrc37_db';
  290. config.password = 'cxbrqnn8wp';
  291. config.host = 'assignment.codsssqklool.eu-central-1.rds.amazonaws.com'
  292. break;
  293. default:
  294. throw new Error('Invalid enviroment');
  295. }
  296.  
  297. var pool = new pg.Pool(config);
  298.  
  299. pool.connect(function(err, client, done) {
  300. if(err) {
  301. return console.error('error fetching client from pool', err);
  302. }
  303. client.query('SELECT $1::int AS number', ['1'], function(err, result) {
  304. done(err);
  305.  
  306. if(err) {
  307. return console.error('error running query', err);
  308. }
  309. console.log(result.rows[0].number);
  310. //output: 1
  311. });
  312. });
  313.  
  314. pool.on('error', function (err, client) {
  315. // if an error is encountered by a client while it sits idle in the pool
  316. // the pool itself will emit an error event with both the error and
  317. // the client which emitted the original error
  318. // this is a rare occurrence but can happen if there is a network partition
  319. // between your application and the database, the database restarts, etc.
  320. // and so you might want to handle it and at least log it out
  321. console.error('idle client error', err.message, err.stack)
  322. });
  323.  
  324. return pool;
  325. };
  326.  
  327. create table users (
  328. id serial primary key,
  329. created_at timestamp default current_timestamp,
  330. name character varying(64)
  331. );
  332.  
  333. create table companies (
  334. id serial primary key,
  335. created_at timestamp default current_timestamp,
  336. name character varying(64)
  337. );
  338.  
  339. create table teams (
  340. id serial primary key,
  341. company_id integer references companies (id),
  342. user_id integer references users (id),
  343. contact_user boolean default false
  344. );
  345.  
  346. create table listings (
  347. id serial primary key,
  348. created_at timestamp default current_timestamp,
  349. created_by integer references users (id),
  350. name character varying(64),
  351. description text
  352. );
  353.  
  354. create table applications (
  355. id serial primary key,
  356. created_at timestamp default current_timestamp,
  357. user_id integer references users (id),
  358. listing_id integer references listings (id),
  359. cover_letter text
  360. );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement