Skip to content

Commit 19ec919

Browse files
author
Ace Nassri
authored
Add GCF SQL samples (#723)
* Initial commit of SQL samples * Move some deps to devDeps
1 parent 85b1c39 commit 19ec919

File tree

3 files changed

+218
-0
lines changed

3 files changed

+218
-0
lines changed

functions/sql/index.js

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* Copyright 2018, Google LLC.
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
'use strict';
17+
18+
const process = require('process'); // Allow env variable mocking
19+
20+
// [START functions_sql_mysql]
21+
const mysql = require('mysql');
22+
// [END functions_sql_mysql]
23+
24+
// [START functions_sql_postgres]
25+
const pg = require('pg');
26+
// [END functions_sql_postgres]
27+
28+
// [START functions_sql_mysql]
29+
// [START functions_sql_postgres]
30+
31+
/**
32+
* TODO(developer): specify SQL connection details
33+
*/
34+
const connectionName = process.env.INSTANCE_CONNECTION_NAME || '<YOUR INSTANCE CONNECTION NAME>';
35+
const dbUser = process.env.SQL_USER || '<YOUR DB USER>';
36+
const dbPassword = process.env.SQL_PASSWORD || '<YOUR DB PASSWORD>';
37+
const dbName = process.env.SQL_NAME || '<YOUR DB NAME>';
38+
39+
// [END functions_sql_postgres]
40+
// [END functions_sql_mysql]
41+
42+
// [START functions_sql_mysql]
43+
const mysqlConfig = {
44+
connectionLimit: 1,
45+
user: dbUser,
46+
password: dbPassword,
47+
database: dbName
48+
};
49+
if (process.env.NODE_ENV === 'production') {
50+
mysqlConfig.socketPath = `/cloudsql/${connectionName}`;
51+
}
52+
53+
const mysqlPool = mysql.createPool(mysqlConfig);
54+
55+
exports.mysqlDemo = (req, res) => {
56+
mysqlPool.query('SELECT NOW() AS now', (err, results) => {
57+
if (err) {
58+
console.error(err);
59+
res.status(500).send(err);
60+
} else {
61+
res.send(JSON.stringify(results));
62+
}
63+
});
64+
};
65+
// [END functions_sql_mysql]
66+
67+
// [START functions_sql_postgres]
68+
const pgConfig = {
69+
max: 1,
70+
user: dbUser,
71+
password: dbPassword,
72+
database: dbName
73+
};
74+
75+
if (process.env.NODE_ENV === 'production') {
76+
pgConfig.socketPath = `/cloudsql/${connectionName}`;
77+
}
78+
79+
const pgPool = new pg.Pool(pgConfig);
80+
81+
exports.postgresDemo = (req, res) => {
82+
pgPool.query('SELECT NOW() as now', (err, results) => {
83+
if (err) {
84+
console.error(err);
85+
res.status(500).send(err);
86+
} else {
87+
res.send(JSON.stringify(results));
88+
}
89+
});
90+
};
91+
// [END functions_sql_postgres]

functions/sql/package.json

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"name": "nodejs-docs-samples-functions-sql",
3+
"version": "0.0.1",
4+
"private": true,
5+
"license": "Apache-2.0",
6+
"author": "Google Inc.",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
10+
},
11+
"engines": {
12+
"node": ">=4.3.2"
13+
},
14+
"scripts": {
15+
"start-proxy-mysql": "cloud_sql_proxy -instances=$INSTANCE_CONNECTION_NAME-mysql=tcp:3306 &",
16+
"start-proxy-pg": "cloud_sql_proxy -instances=$INSTANCE_CONNECTION_NAME-pg=tcp:5432 &",
17+
"start-proxy": "! pgrep cloud_sql_proxy > /dev/null && npm run start-proxy-pg && npm run start-proxy-mysql || exit 0",
18+
"kill-proxy": "killall cloud_sql_proxy",
19+
"lint": "repo-tools lint",
20+
"pretest": "npm run lint",
21+
"ava": "ava -T 20s --verbose test/*.test.js",
22+
"test": "npm run start-proxy && npm run ava && npm run kill-proxy"
23+
},
24+
"dependencies": {
25+
"mysql": "^2.16.0",
26+
"pg": "^7.4.3"
27+
},
28+
"devDependencies": {
29+
"@google-cloud/nodejs-repo-tools": "^2.3.3",
30+
"ava": "0.25.0",
31+
"proxyquire": "^2.1.0",
32+
"semistandard": "^12.0.1",
33+
"sinon": "4.4.2"
34+
},
35+
"cloud-repo-tools": {
36+
"requiresKeyFile": true,
37+
"requiresProjectId": true,
38+
"requiredEnvVars": [
39+
"MYSQL_USER",
40+
"MYSQL_PASSWORD",
41+
"MYSQL_DATABASE",
42+
"POSTGRES_USER",
43+
"POSTGRES_PASSWORD",
44+
"POSTGRES_DATABASE"
45+
]
46+
}
47+
}

functions/sql/test/index.test.js

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Copyright 2018, Google LLC.
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
'use strict';
17+
18+
const sinon = require(`sinon`);
19+
const test = require(`ava`);
20+
const proxyquire = require(`proxyquire`);
21+
22+
const INSTANCE_PREFIX = `nodejs-docs-samples:us-central1:integration-tests-instance`;
23+
24+
const getProgram = (env) => {
25+
return proxyquire(`../`, {
26+
process: {
27+
env: env
28+
}
29+
});
30+
};
31+
32+
test(`should query MySQL`, async (t) => {
33+
const program = getProgram({
34+
INSTANCE_CONNECTION_NAME: `${INSTANCE_PREFIX}-mysql`,
35+
SQL_USER: process.env.MYSQL_USER,
36+
SQL_PASSWORD: process.env.MYSQL_PASSWORD,
37+
SQL_NAME: process.env.MYSQL_DATABASE
38+
});
39+
40+
const resMock = {
41+
status: sinon.stub().returnsThis(),
42+
send: sinon.stub()
43+
};
44+
45+
program.mysqlDemo(null, resMock);
46+
47+
// Give the query time to complete
48+
await new Promise(resolve => { setTimeout(resolve, 1500); });
49+
50+
t.false(resMock.status.called);
51+
t.true(resMock.send.calledOnce);
52+
53+
const response = resMock.send.firstCall.args[0];
54+
t.regex(response, /\d{4}-\d{1,2}-\d{1,2}/);
55+
});
56+
57+
test(`should query Postgres`, async (t) => {
58+
const program = getProgram({
59+
INSTANCE_CONNECTION_NAME: `${INSTANCE_PREFIX}-pg`,
60+
SQL_USER: process.env.POSTGRES_USER,
61+
SQL_PASSWORD: process.env.POSTGRES_PASSWORD,
62+
SQL_NAME: process.env.POSTGRES_DATABASE
63+
});
64+
65+
const resMock = {
66+
status: sinon.stub().returnsThis(),
67+
send: sinon.stub()
68+
};
69+
70+
program.postgresDemo(null, resMock);
71+
72+
// Give the query time to complete
73+
await new Promise(resolve => { setTimeout(resolve, 1500); });
74+
75+
t.false(resMock.status.called);
76+
t.true(resMock.send.calledOnce);
77+
78+
const response = resMock.send.firstCall.args[0];
79+
t.regex(response, /\d{4}-\d{1,2}-\d{1,2}/);
80+
});

0 commit comments

Comments
 (0)