From 8f5bdf468ea0baa35c5442396afdc253da8b2aa7 Mon Sep 17 00:00:00 2001 From: BOBBY Date: Wed, 15 Apr 2020 19:10:44 +0800 Subject: [PATCH 1/5] Able to add todo items and show todo items from SQL database --- .gitignore | 3 ++ index.js | 19 +++++--- package-lock.json | 119 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 22 +++++++++ 4 files changed, 157 insertions(+), 6 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore index c5582434..e3b3ab73 100755 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ .svn *~ .*.swp + + +node_modules \ No newline at end of file diff --git a/index.js b/index.js index 3907d3b5..f0db892b 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,7 @@ console.log("works!!", process.argv[2]); const pg = require('pg'); const configs = { - user: 'akira', + user: 'postgres', host: '127.0.0.1', database: 'todo', port: 5432, @@ -23,14 +23,21 @@ let queryDoneCallback = (err, result) => { let clientConnectionCallback = (err) => { if( err ){ - console.log( "error", err.message ); + console.log( "Connection callback error", err.message ); } + else if (process.argv[2] === 'show'){ + let text = "select * from items"; - let text = "INSERT INTO todo (name) VALUES ($1) RETURNING id"; + client.query(text, queryDoneCallback); + } + else if (process.argv[2] === 'add'){ + let text = "insert into items (name) values ($1) returning id"; + + const values = [process.argv[3]]; - const values = ["hello"]; + client.query(text, values, queryDoneCallback); + } - client.query(text, values, queryDoneCallback); }; -client.connect(clientConnectionCallback); +client.connect(clientConnectionCallback); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..2afe3c42 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,119 @@ +{ + "name": "cli-todo-sql", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "pg": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.0.2.tgz", + "integrity": "sha512-ngOUEDk69kLdH/k/YLT2NRIBcUiPFRcY4l51dviqn79P5qIa5jBIGIFTIGXh4OlT/6gpiCAza5a9uy08izpFQQ==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "0.1.3", + "pg-pool": "^3.1.0", + "pg-protocol": "^1.2.1", + "pg-types": "^2.1.0", + "pgpass": "1.x", + "semver": "4.3.2" + } + }, + "pg-connection-string": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", + "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.1.0.tgz", + "integrity": "sha512-CvxGctDwjZZad6Q7vvhFA4BsYdk26UFIZaFH0XXqHId5uBOc26vco/GFh/laUVIQUpD9IKe/f9/mr/OQHyQ2ZA==" + }, + "pg-protocol": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.2.1.tgz", + "integrity": "sha512-IqZ+VUOqg3yydxSt5NgNKLVK9JgPBuzq4ZbA9GmrmIkQjQAszPT9DLqTtID0mKsLEZB68PU0gjLla561WZ2QkQ==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", + "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "requires": { + "split": "^1.0.0" + } + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.5.tgz", + "integrity": "sha512-pdau6GRPERdAYUQwkBnGKxEfPyhVZXG/JiS44iZWiNdSOWE09N2lUgN6yshuq6fVSon4Pm0VMXd1srUUkLe9iA==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, + "semver": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", + "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..ede0b78e --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "cli-todo-sql", + "version": "1.0.0", + "description": "![https://i.giphy.com/media/26ufnwz3wDUli7GU0/giphy.webp](https://i.giphy.com/media/26ufnwz3wDUli7GU0/giphy.webp)", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/bobbykwong/cli-todo-sql.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/bobbykwong/cli-todo-sql/issues" + }, + "homepage": "https://github.com/bobbykwong/cli-todo-sql#readme", + "dependencies": { + "pg": "^8.0.2" + } +} From 89514ad80199c725cd3d42348b388296d7483fc1 Mon Sep 17 00:00:00 2001 From: BOBBY Date: Wed, 15 Apr 2020 22:08:51 +0800 Subject: [PATCH 2/5] data contains created date. added starter sql file for convenience when dropping and creating tables --- index.js | 36 +++++++++++++++++++++++++++++++----- tables.sql | 7 +++++++ 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 tables.sql diff --git a/index.js b/index.js index f0db892b..77e3a8b4 100644 --- a/index.js +++ b/index.js @@ -14,8 +14,25 @@ const client = new pg.Client(configs); let queryDoneCallback = (err, result) => { if (err) { console.log("query error", err.message); - } else { - console.log("result", result.rows ); + } + else { + console.log(result.rows); + console.log( + ` + ____ _____ ____ __ ____ ___ ____ +( _ \\( _ )( _ \\ ( ) (_ _)/ __)(_ _) + ) _ < )(_)( ) _ < )(__ _)(_ \\__ \\ )( +(____/(_____)(____/ (____)(____)(___/ (__) + + ` + ); + result.rows.forEach(el => { + console.log(` +${el.name} - [${el.done}] +created_at: ${el.created_date} +updated_at: ${el.updated_date} + `); + }) } client.end(); }; @@ -31,11 +48,20 @@ let clientConnectionCallback = (err) => { client.query(text, queryDoneCallback); } else if (process.argv[2] === 'add'){ - let text = "insert into items (name) values ($1) returning id"; + let text = "insert into items (name, done) values ($1, $2) returning id"; + + const values = [process.argv[3], " "]; - const values = [process.argv[3]]; + client.query(text, values, (err, result) => { + if (err) { + console.log("query error: " + err) + } + else{ + console.log("Successfully Added!") + } - client.query(text, values, queryDoneCallback); + client.end(); + }); } }; diff --git a/tables.sql b/tables.sql new file mode 100644 index 00000000..d59295b9 --- /dev/null +++ b/tables.sql @@ -0,0 +1,7 @@ +create table if not exists items( +id serial primary key, +name text, +done text, +created_date text not null default TO_CHAR(NOW() :: DATE, 'dd/mm/yyyy'), +updated_date date +); \ No newline at end of file From 0c0ac23b0b2dffff039e11834168ba0263ff72b8 Mon Sep 17 00:00:00 2001 From: BOBBY Date: Wed, 15 Apr 2020 22:22:00 +0800 Subject: [PATCH 3/5] able to update when todo item is done --- index.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 77e3a8b4..6577c88f 100644 --- a/index.js +++ b/index.js @@ -28,7 +28,7 @@ let queryDoneCallback = (err, result) => { ); result.rows.forEach(el => { console.log(` -${el.name} - [${el.done}] +${el.id}. ${el.name} - [${el.done}] created_at: ${el.created_date} updated_at: ${el.updated_date} `); @@ -64,6 +64,21 @@ let clientConnectionCallback = (err) => { }); } + else if(process.argv[2] === 'done'){ + let text = `update items set done='X' where id=${process.argv[3]}`; + + client.query(text, (err, result) => { + if (err) { + console.log("query error: " + err) + } + else{ + console.log("Update Successful!") + } + + client.end(); + }) + } + }; client.connect(clientConnectionCallback); \ No newline at end of file From 46f5ac4f12ee7d07feac41d1624e181a2c9f79d5 Mon Sep 17 00:00:00 2001 From: BOBBY Date: Wed, 15 Apr 2020 23:10:14 +0800 Subject: [PATCH 4/5] Able to archive data by inserting archived data into archive table and deleting archived data from items table --- archive.sql | 7 +++++ index.js | 83 +++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 archive.sql diff --git a/archive.sql b/archive.sql new file mode 100644 index 00000000..b6dbd682 --- /dev/null +++ b/archive.sql @@ -0,0 +1,7 @@ +create table if not exists archive( +id INTEGER PRIMARY KEY, +name text, +done text, +created_date text not null default TO_CHAR(NOW() :: DATE, 'dd/mm/yyyy'), +updated_date date +); \ No newline at end of file diff --git a/index.js b/index.js index 6577c88f..e4ea5c4f 100644 --- a/index.js +++ b/index.js @@ -11,30 +11,9 @@ const configs = { const client = new pg.Client(configs); +// For showing items in the todolist let queryDoneCallback = (err, result) => { - if (err) { - console.log("query error", err.message); - } - else { - console.log(result.rows); - console.log( - ` - ____ _____ ____ __ ____ ___ ____ -( _ \\( _ )( _ \\ ( ) (_ _)/ __)(_ _) - ) _ < )(_)( ) _ < )(__ _)(_ \\__ \\ )( -(____/(_____)(____/ (____)(____)(___/ (__) - - ` - ); - result.rows.forEach(el => { - console.log(` -${el.id}. ${el.name} - [${el.done}] -created_at: ${el.created_date} -updated_at: ${el.updated_date} - `); - }) - } - client.end(); + }; let clientConnectionCallback = (err) => { @@ -42,11 +21,37 @@ let clientConnectionCallback = (err) => { if( err ){ console.log( "Connection callback error", err.message ); } + // Show items in todo list else if (process.argv[2] === 'show'){ let text = "select * from items"; - client.query(text, queryDoneCallback); + client.query(text, (err, result) => { + if (err) { + console.log("query error", err.message); + } + else { + console.log(result.rows); + console.log( + ` + ____ _____ ____ __ ____ ___ ____ + ( _ \\( _ )( _ \\ ( ) (_ _)/ __)(_ _) + ) _ < )(_)( ) _ < )(__ _)(_ \\__ \\ )( + (____/(_____)(____/ (____)(____)(___/ (__) + + ` + ); + result.rows.forEach(el => { + console.log(` + ${el.id}. ${el.name} - [${el.done}] + created_at: ${el.created_date} + updated_at: ${el.updated_date} + `); + }) + } + client.end(); + }); } + // Add items in todo list else if (process.argv[2] === 'add'){ let text = "insert into items (name, done) values ($1, $2) returning id"; @@ -63,7 +68,7 @@ let clientConnectionCallback = (err) => { client.end(); }); } - + // Mark item as done else if(process.argv[2] === 'done'){ let text = `update items set done='X' where id=${process.argv[3]}`; @@ -78,6 +83,34 @@ let clientConnectionCallback = (err) => { client.end(); }) } + // Archive item by copying row into another table and deleting from current table + else if (process.argv[2] === 'archive'){ + let text1 = `insert into archive (select * from items where id=${process.argv[3]})`; + + let text2 = `delete from items where id=${process.argv[3]}`; + + // Insert archived data into separate archive table + client.query(text1, (err, result) => { + if (err) { + console.log("query error: " + err) + } + else{ + console.log("insert into archive table Successful!") + } + }) + + // Delete archive data from items table + client.query(text2, (err, result) => { + if (err) { + console.log("query error: " + err) + } + else{ + console.log("delete from items table Successful!") + } + client.end(); + }) + } + }; From 4779e7eac265e15e0b5bace90a4d131d7d95e300 Mon Sep 17 00:00:00 2001 From: BOBBY Date: Wed, 15 Apr 2020 23:20:34 +0800 Subject: [PATCH 5/5] Able to update date when marked as completed --- index.js | 4 +++- tables.sql | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index e4ea5c4f..cca04d71 100644 --- a/index.js +++ b/index.js @@ -70,7 +70,9 @@ let clientConnectionCallback = (err) => { } // Mark item as done else if(process.argv[2] === 'done'){ - let text = `update items set done='X' where id=${process.argv[3]}`; + const updatedDate = `TO_CHAR(NOW() :: DATE, 'dd/mm/yyyy')`; + + let text = `update items set done='X', updated_date=${updatedDate} where id=${process.argv[3]}`; client.query(text, (err, result) => { if (err) { diff --git a/tables.sql b/tables.sql index d59295b9..4b2f39a5 100644 --- a/tables.sql +++ b/tables.sql @@ -3,5 +3,5 @@ id serial primary key, name text, done text, created_date text not null default TO_CHAR(NOW() :: DATE, 'dd/mm/yyyy'), -updated_date date +updated_date text ); \ No newline at end of file