Advertisement
Guest User

Untitled

a guest
Mar 9th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.59 KB | None | 0 0
  1. var pg = require('pg');
  2.  
  3. var config = {
  4. host: 'localhost',
  5. user: 'v',
  6. password: 'a',
  7. database: 'j',
  8. };
  9.  
  10. var pool = new pg.Pool(config);
  11.  
  12. pool.connect(function(err, client, done) {
  13. if(err) {
  14. return console.error('error fetching client from pool', err);
  15. }
  16. client.query('SELECT $1::int AS number', ['1'], function(err, result) {
  17. done(err);
  18.  
  19. if(err) {
  20. return console.error('error running query', err);
  21. }
  22. console.log(result.rows[0].number);
  23. //output: 1
  24. });
  25. });
  26.  
  27. pool.on('error', function (err, client) {
  28. // if an error is encountered by a client while it sits idle in the pool
  29. // the pool itself will emit an error event with both the error and
  30. // the client which emitted the original error
  31. // this is a rare occurrence but can happen if there is a network partition
  32. // between your application and the database, the database restarts, etc.
  33. // and so you might want to handle it and at least log it out
  34. console.error('idle client error', err.message, err.stack)
  35. });
  36.  
  37. module.exports = pool;
  38.  
  39. 'use strict';
  40.  
  41. var express = require('express');
  42. var Promise = require('promise');
  43. var router = express.Router();
  44. var app = express();
  45.  
  46. var pool = require('./db.js')();
  47. var User = require('./models');
  48.  
  49. var PORT = 3000;
  50.  
  51. app.use(function (req, res, next) {
  52. pool.connect(function(error, client, done) {
  53. // Handle connection errors
  54. if (error) {
  55. done(error);
  56. console.log(error.message);
  57. return res.status(500)
  58. .json({success: false, data: error});
  59. }
  60. req.client = client;
  61. req.done = done;
  62. next();
  63. });
  64. });
  65. **index.js**
  66.  
  67. 'use strict';
  68.  
  69. var express = require('express');
  70. var Promise = require('promise');
  71. var router = express.Router();
  72. var app = express();
  73.  
  74. var pool = require('./db.js')();
  75. var User = require('./models');
  76.  
  77. var PORT = 3000;
  78.  
  79. app.use(function (req, res, next) {
  80. pool.connect(function(error, client, done) {
  81. // Handle connection errors
  82. if (error) {
  83. done(error);
  84. console.log(error.message);
  85. return res.status(500)
  86. .json({success: false, data: error});
  87. }
  88. req.client = client;
  89. req.done = done;
  90. next();
  91. });
  92. });
  93.  
  94. router.get('/topActiveUsers', (req, res) => {
  95. topActiveUsers(req, res);
  96. });
  97.  
  98. router.get('/users', (req, res) => {
  99. userInfo(req, res);
  100. });
  101.  
  102. app.use(router);
  103.  
  104. app.get('*', function (req, res) {
  105. res.status(400).send('Invalid route');
  106. });
  107.  
  108. app.listen(PORT, function () {
  109. console.log('App listening on port ' + PORT);
  110. });
  111.  
  112. var topActiveUsers = function topActiveUsers(req, res) {
  113. var ENTRIES_PER_PAGE = 3;
  114. var startIndex = 0;
  115. var total = 0;
  116. req.query.page = +req.query.page || 0;
  117.  
  118. var pageNum = req.query.page > 0 ? req.query.page : 0;
  119. if (pageNum > 0) {
  120. startIndex = ENTRIES_PER_PAGE * (pageNum - 1);
  121. }
  122. total = ENTRIES_PER_PAGE * (pageNum + 1);
  123.  
  124. User.topActiveUsers(req)
  125. .then(function fullfilled(users) {
  126. if (users.length < startIndex) {
  127. throw new Error('Invalid pagination offset');
  128. }
  129. if (users.length > total) {
  130. users = users.slice(startIndex, startIndex + ENTRIES_PER_PAGE);
  131. } else {
  132. users = users.splice(startIndex);
  133. }
  134. return Promise.all(users.map(function (user) {
  135. return user.applicationListings(req);
  136. }));
  137. })
  138. .then(function fullfilled(users) {
  139. var result = users.map(function (user) {
  140. return {
  141. id: user.id,
  142. name: user.name,
  143. count: user._appliedListings.length,
  144. createdAt: user.createdAt,
  145. listings: user._appliedListings
  146. };
  147. });
  148. res.json(result);
  149. })
  150. .catch(function rejected(error) {
  151. console.log(error.message);
  152. throw error;
  153. })
  154. .finally(function () {
  155. res.end();
  156. });
  157. };
  158.  
  159. var userInfo = function userInfo(req, res) {
  160. User.getById(req)
  161. // run companies/listings/applications in "parallel"
  162. .then(function fullfilled(user) {
  163. return Promise.all([
  164. user.id,
  165. user.name,
  166. user.createdAt,
  167. user.companies(req),
  168. user.listings(req),
  169. user.applications(req)
  170. ]);
  171. })
  172. .then(function fullfilled([
  173. id, name, createdAt, companies, listings, applications]) {
  174. res.json({
  175. id: id,
  176. name: name,
  177. createdAt: createdAt,
  178. companies: companies,
  179. listings: listings,
  180. applications: applications
  181. });
  182. })
  183. .catch(function rejected(error) {
  184. console.log('error', error.message);
  185. throw error;
  186. })
  187. .finally(function () {
  188. res.end();
  189. });
  190. };
  191.  
  192. var Promise = require('promise');
  193.  
  194. module.exports = User;
  195.  
  196. /**
  197. * User m2m Company
  198. * User o2m Listing
  199. * User m2m applications
  200. */
  201. function User(opt_data) {
  202. var data = opt_data || {};
  203.  
  204. this.id = data['id'] || null;
  205. this.name = data['name'] || '';
  206. this.createdAt = data['created_at'] || new Date();
  207. this._companies = [];
  208. this._listings = [];
  209. this._applications = [];
  210. this._appliedListings = [];
  211. }
  212. User._RESOURCE_LIMIT = 5;
  213. var UserProto = User.prototype;
  214.  
  215. User.topActiveUsers = function topActiveUsers(req) {
  216. var queryString = "select * from users u inner join "+
  217. "(select user_id, count(id) cnt from applications "+
  218. "where id in (select id from applications where "+
  219. "created_at > current_date - interval '1 week') "+
  220. "group by user_id) a on u.id = a.user_id order by a.cnt desc";
  221. return queryPromise(req, queryString)
  222. .then(function fullfilled(result) {
  223. return result.rows.map(function(row) {
  224. return new User(row);
  225. });
  226. });
  227. };
  228.  
  229. User.getById = function getById(req) {
  230. var queryString = 'select * from users where id = $1::int';
  231. return queryPromise(req, queryString, [req.query.id])
  232. .then(function fullfilled(result) {
  233. return new User(result.rows[0]);
  234. });
  235. };
  236.  
  237. UserProto.companies = function companies(req) {
  238. var queryString = 'select c.id, c.name, t.contact_user '+
  239. 'from companies c, teams t '+
  240. 'where t.user_id = $1::int and t.company_id = c.id '+
  241. 'limit $2::int';
  242. return queryPromise(req, queryString, [this.id, User._RESOURCE_LIMIT])
  243. .then(function fullfilled(result) {
  244. return result.rows.map(function (data) {
  245. return new Company(data);
  246. });
  247. });
  248. };
  249.  
  250. UserProto.listings = function listings(req) {
  251. var queryString = 'select * from listings '+
  252. 'where created_by = $1::int '+
  253. 'limit $2::int';
  254. return queryPromise(req, queryString, [this.id, User._RESOURCE_LIMIT])
  255. .then(function fullfilled(result) {
  256. return result.rows.map(function (data) {
  257. return new Listing(data);
  258. });
  259. });
  260. };
  261.  
  262. UserProto.applicationListings = function applications(req) {
  263. var queryString = "select * from listings l inner join "+
  264. "(select listing_id, user_id, created_at from applications) a "+
  265. "on a.listing_id = l.id "+
  266. "where a.user_id = $1::int order by a.created_at desc limit 3";
  267. var self = this;
  268. return queryPromise(req, queryString, [this.id])
  269. .then(function fullfilled(result) {
  270. self._appliedListings = result.rows.map(function (data) {
  271. return new Listing(data);
  272. });
  273. return self;
  274. });
  275. };
  276.  
  277. UserProto.applications = function applications(req) {
  278. var queryString = 'select a.id as app_id, a.created_at, a.cover_letter, '+
  279. 'l.id as list_id, l.name, l.description '+
  280. 'from applications a, listings l '+
  281. 'where a.user_id = $1::int and a.listing_id = l.id '+
  282. 'limit $2::int';
  283. return queryPromise(req, queryString, [this.id, User._RESOURCE_LIMIT])
  284. .then(function fullfilled(result) {
  285. return result.rows.map(function (data) {
  286. return new Application(data);
  287. });
  288. });
  289. };
  290.  
  291. function Company(opt_data) {
  292. var data = opt_data || {};
  293. this.id = data['id'] || null;
  294. this.createdAt = data['created_at'] || new Date();
  295. this.name = data['name'] || '';
  296. this.isContact = false;
  297. }
  298.  
  299. function Listing(opt_data) {
  300. var data = opt_data || {};
  301. this.id = data['id'] || null;
  302. this.createdAt = data['created_at'] || new Date();
  303. this.name = data['name'] || '';
  304. this.description = data['description'] || '';
  305. }
  306.  
  307. function Application(opt_data) {
  308. var data = opt_data || {};
  309. this.id = data['id'] || null;
  310. this.createdAt = data['created_at'] || new Date();
  311. this.listing = data['listing'] || null;
  312. this.coverLetter = data['cover_letter'] || '';
  313. }
  314.  
  315. function queryPromise(req, queryString, queryParams, debug) {
  316. if (debug) {
  317. console.log(queryString, queryParams);
  318. req.client.connection.on('message', function(msg) {
  319. console.log(msg)
  320. });
  321. }
  322. return new Promise(function _promise(resolve, reject) {
  323. req.client.query(
  324. queryString,
  325. queryParams || [],
  326. function result(error, result) {
  327. req.done(error);
  328.  
  329. if (error) {
  330. console.log('error ' + error.message);
  331. return reject(error);
  332. }
  333. resolve(result);
  334. });
  335. });
  336. };
  337.  
  338. var pg = require('pg');
  339.  
  340. module.exports = function() {
  341. var config = {
  342. port: 5432,
  343. max: 10,
  344. idleTimeoutMillis: 30000
  345. };
  346. switch (process.env.NODE_ENV) {
  347. case 'development':
  348. config.host = 'localhost';
  349. config.user = 'xxxx';
  350. config.password = 'xxxx';
  351. config.database = 'xxxx';
  352. break;
  353. case 'production':
  354. config.user = 'xxxx';
  355. config.database = 'xxxx';
  356. config.password = 'xxxx';
  357. config.host = 'xxxx'
  358. break;
  359. default:
  360. throw new Error('Invalid enviroment');
  361. }
  362.  
  363. var pool = new pg.Pool(config);
  364.  
  365. pool.connect(function(err, client, done) {
  366. if(err) {
  367. return console.error('error fetching client from pool', err);
  368. }
  369. client.query('SELECT $1::int AS number', ['1'], function(err, result) {
  370. done(err);
  371.  
  372. if(err) {
  373. return console.error('error running query', err);
  374. }
  375. console.log(result.rows[0].number);
  376. //output: 1
  377. });
  378. });
  379.  
  380. pool.on('error', function (err, client) {
  381. // if an error is encountered by a client while it sits idle in the pool
  382. // the pool itself will emit an error event with both the error and
  383. // the client which emitted the original error
  384. // this is a rare occurrence but can happen if there is a network partition
  385. // between your application and the database, the database restarts, etc.
  386. // and so you might want to handle it and at least log it out
  387. console.error('idle client error', err.message, err.stack)
  388. });
  389.  
  390. return pool;
  391. };
  392.  
  393. create table users (
  394. id serial primary key,
  395. created_at timestamp default current_timestamp,
  396. name character varying(64)
  397. );
  398.  
  399. create table companies (
  400. id serial primary key,
  401. created_at timestamp default current_timestamp,
  402. name character varying(64)
  403. );
  404.  
  405. create table teams (
  406. id serial primary key,
  407. company_id integer references companies (id),
  408. user_id integer references users (id),
  409. contact_user boolean default false
  410. );
  411.  
  412. create table listings (
  413. id serial primary key,
  414. created_at timestamp default current_timestamp,
  415. created_by integer references users (id),
  416. name character varying(64),
  417. description text
  418. );
  419.  
  420. create table applications (
  421. id serial primary key,
  422. created_at timestamp default current_timestamp,
  423. user_id integer references users (id),
  424. listing_id integer references listings (id),
  425. cover_letter text
  426. );
  427. router.get('/topActiveUsers', (req, res) => {
  428. topActiveUsers(req, res);
  429. });
  430.  
  431. router.get('/users', (req, res) => {
  432. userInfo(req, res);
  433. });
  434.  
  435. app.use(router);
  436.  
  437. app.get('*', function (req, res) {
  438. res.status(400).send('Invalid route');
  439. });
  440.  
  441. app.listen(PORT, function () {
  442. console.log('App listening on port ' + PORT);
  443. });
  444.  
  445. var topActiveUsers = function topActiveUsers(req, res) {
  446. var ENTRIES_PER_PAGE = 3;
  447. var startIndex = 0;
  448. var total = 0;
  449. req.query.page = +req.query.page || 0;
  450.  
  451. var pageNum = req.query.page > 0 ? req.query.page : 0;
  452. if (pageNum > 0) {
  453. startIndex = ENTRIES_PER_PAGE * (pageNum - 1);
  454. }
  455. total = ENTRIES_PER_PAGE * (pageNum + 1);
  456.  
  457. User.topActiveUsers(req)
  458. .then(function fullfilled(users) {
  459. if (users.length < startIndex) {
  460. throw new Error('Invalid pagination offset');
  461. }
  462. if (users.length > total) {
  463. users = users.slice(startIndex, startIndex + ENTRIES_PER_PAGE);
  464. } else {
  465. users = users.splice(startIndex);
  466. }
  467. return Promise.all(users.map(function (user) {
  468. return user.applicationListings(req);
  469. }));
  470. })
  471. .then(function fullfilled(users) {
  472. var result = users.map(function (user) {
  473. return {
  474. id: user.id,
  475. name: user.name,
  476. count: user._appliedListings.length,
  477. createdAt: user.createdAt,
  478. listings: user._appliedListings
  479. };
  480. });
  481. res.json(result);
  482. })
  483. .catch(function rejected(error) {
  484. console.log(error.message);
  485. throw error;
  486. })
  487. .finally(function () {
  488. res.end();
  489. });
  490. };
  491.  
  492. var userInfo = function userInfo(req, res) {
  493. User.getById(req)
  494. // run companies/listings/applications in "parallel"
  495. .then(function fullfilled(user) {
  496. return Promise.all([
  497. user.id,
  498. user.name,
  499. user.createdAt,
  500. user.companies(req),
  501. user.listings(req),
  502. user.applications(req)
  503. ]);
  504. })
  505. .then(function fullfilled([
  506. id, name, createdAt, companies, listings, applications]) {
  507. res.json({
  508. id: id,
  509. name: name,
  510. createdAt: createdAt,
  511. companies: companies,
  512. listings: listings,
  513. applications: applications
  514. });
  515. })
  516. .catch(function rejected(error) {
  517. console.log('error', error.message);
  518. throw error;
  519. })
  520. .finally(function () {
  521. res.end();
  522. });
  523. };
  524.  
  525. insert into users (id, created_at, name) values
  526. (1, '2015-01-13 15:30', 'Mark'),
  527. (2, '2015-01-13 15:30', 'John'),
  528. (3, '2016-01-01 10:30', 'Melinda'),
  529. (4, '2016-01-17 23:30', 'Carl'),
  530. (5, '2016-02-02 16:30', 'Tim'),
  531. (6, '2016-02-02 16:30', 'Jessica')
  532. ;
  533.  
  534. insert into companies (id, created_at, name) values
  535. (1, '2015-01-13 15:00', 'Facewall'),
  536. (2, '2015-01-17 15:00', 'Carl & Co')
  537. ;
  538.  
  539. insert into teams (company_id, user_id, contact_user) values
  540. (1, 1, TRUE),
  541. (2, 3, FALSE),
  542. (2, 4, TRUE)
  543. ;
  544.  
  545. insert into listings (id, created_at, created_by, name, description) values
  546. (1, '2015-01-15 11:00', 1, 'Join us conquering the world!', 'This is your best chance to be on the right side of the equation...')
  547. ;
  548.  
  549. insert into applications (created_at, user_id, listing_id, cover_letter) values
  550. ('2015-01-16 12:00', 2, 1, 'Hello, ...')
  551. ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement