diff --git a/chapter03/package-lock.json b/chapter03/package-lock.json index f4b2cff..e3f310f 100644 --- a/chapter03/package-lock.json +++ b/chapter03/package-lock.json @@ -4448,6 +4448,22 @@ "object-visit": "1.0.1" } }, + "mariasql": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/mariasql/-/mariasql-0.2.6.tgz", + "integrity": "sha1-q3iwZxFy8Or06A3a0Cm4A/Nc93o=", + "requires": { + "lru-cache": "2.7.3", + "nan": "2.10.0" + }, + "dependencies": { + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" + } + } + }, "md5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", @@ -4566,9 +4582,7 @@ "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, - "optional": true + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "nanomatch": { "version": "1.2.9", diff --git a/chapter03/package.json b/chapter03/package.json index 3c4b064..4cbd70a 100644 --- a/chapter03/package.json +++ b/chapter03/package.json @@ -7,6 +7,7 @@ "build": "flow-remove-types src/ -d out/", "buildWithMaps": "flow-remove-types src/ -d out/ --pretty --sourcemaps", "start": "npm run build && node out/doroundmath.js", + "start-db": "npm run build && node out/dbaccess.js", "nodemon": "nodemon --watch src --delay 1 --exec npm start", "addTypes": "flow-typed install", "update": "npm install && flow-typed install", @@ -71,7 +72,8 @@ "printWidth": 75 }, "dependencies": { - "axios": "^0.18.0" + "axios": "^0.18.0", + "mariasql": "^0.2.6" }, "devDependencies": { "babel-eslint": "^8.2.2", diff --git a/chapter03/src/dbaccess.js b/chapter03/src/dbaccess.js new file mode 100644 index 0000000..e583e3c --- /dev/null +++ b/chapter03/src/dbaccess.js @@ -0,0 +1,115 @@ +/* @flow */ +"use strict"; + +const mariaSQL = require("mariasql"); +const { promisify } = require("util"); + +const DB_HOST = "127.0.0.1"; +const DB_USER = "fkereki"; +const DB_PASS = "modernJS!!"; +const DB_SCHEMA = "world"; + +async function tryDbAccess(dbConn) { + try { + const rows = await dbConn.query("SELECT 1960 AS someYear"); + console.log(`Year was ${rows[0].someYear}`); + } catch (e) { + console.log("Unexpected error", e); + } +} + +async function get10CountriesWithMoreCities(dbConn) { + try { + const myQuery = `SELECT + CI.countryCode, + CO.countryName, + COUNT(*) as countCities + FROM cities CI JOIN countries CO + ON CI.countryCode=CO.countryCode + GROUP BY 1 + ORDER BY 3 DESC + LIMIT 10`; + + const rows = await dbConn.query(myQuery); + rows.forEach(r => + console.log(r.countryCode, r.countryName, r.countCities) + ); + + /* + An alternative: return arrays instead of objects + */ + const rows2 = await dbConn.query(myQuery, null, { + useArray: true + }); + rows2.forEach(r => console.log(r[0], r[1], r[2])); + } catch (e) { + console.log("Unexpected error", e); + } +} + +async function addSeekAndDeleteCountry(dbConn) { + try { + const code = "42"; + const name = "DOUGLASADAMSLAND"; + + /* + 1. Add the new country via a prepared insert statement + */ + + const prepInsert = dbConn.prepare( + "INSERT INTO countries (countryCode, countryName) VALUES (:code, :name)" + ); + const preppedInsert = prepInsert({ code, name }); + await dbConn.query(preppedInsert); + + /* + 1b. Alternative way, with placeholders + await dbConn.query( + "INSERT INTO countries (countryCode, countryName) VALUES (?, ?)", + [code, name] + ); + */ + + /* + 2. Seek the recently added country + */ + const getAdams = `SELECT * FROM countries WHERE countryCode="${code}"`; + const adams = await dbConn.query(getAdams); + console.log( + adams.length, + adams[0].countryCode, + adams[0].countryName + ); + + /* + 3. Drop the new country + */ + await dbConn.query(`DELETE FROM countries WHERE countryCode="42"`); + + /* + 4. Verify that the country is no more + */ + const adams2 = await dbConn.query(getAdams); + console.log(adams2.length); + } catch (e) { + console.log("Unexpected error", e); + } +} + +function getDbConnection(host, user, password, db) { + const dbConn = new mariaSQL({ host, user, password, db }); + dbConn.query = promisify(dbConn.query); + return dbConn; +} + +const dbConn = getDbConnection(DB_HOST, DB_USER, DB_PASS, DB_SCHEMA); + +tryDbAccess(dbConn); + +get10CountriesWithMoreCities(dbConn); + +addSeekAndDeleteCountry(dbConn); + +/* + After everything is done, you can do dbConn.end() +*/ diff --git a/chapter03/src/promisify.js b/chapter03/src/promisify.js index 969c3fd..c00a1e9 100644 --- a/chapter03/src/promisify.js +++ b/chapter03/src/promisify.js @@ -22,9 +22,10 @@ showFileLength1(FILE_TO_READ); // 2. Alternative style using promises function showFileLength2(fileName: string): void { - const readFile = util.promisify(fs.readFile); + fs.readFile = util.promisify(fs.readFile); - readFile(fileName, "utf8") + fs + .readFile(fileName, "utf8") .then((text: string) => { console.log(`2. Reading with promises: ${text.length} bytes`); }) @@ -37,10 +38,10 @@ showFileLength2(FILE_TO_READ); // 3. Using async/await, and with an arrow function just for variety const showFileLength3 = async (fileName: string) => { - const readFile = util.promisify(fs.readFile); + fs.readFile = util.promisify(fs.readFile); try { - const text: string = await readFile(fileName, "utf8"); + const text: string = await fs.readFile(fileName, "utf8"); console.log(`3. Reading with async/await: ${text.length} bytes`); } catch (err) { throw err;