├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── JavaScript ├── 1-test.js ├── 2-async.js ├── 3-promise.js ├── README.md ├── application.js ├── db.js ├── example.sql ├── package-lock.json └── package.json ├── LICENSE └── README.md /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | end_of_line = lf 6 | charset = utf-8 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [{*.js,*.mjs,*.ts,*.json,*.yml}] 11 | indent_size = 2 12 | indent_style = space 13 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "node": true 6 | }, 7 | "extends": "eslint:recommended", 8 | "parserOptions": { 9 | "ecmaVersion": "latest" 10 | }, 11 | "globals": { 12 | "BigInt": true 13 | }, 14 | "rules": { 15 | "indent": [ 16 | "error", 17 | 2 18 | ], 19 | "linebreak-style": [ 20 | "error", 21 | "unix" 22 | ], 23 | "quotes": [ 24 | "error", 25 | "single" 26 | ], 27 | "semi": [ 28 | "error", 29 | "always" 30 | ], 31 | "no-loop-func": [ 32 | "error" 33 | ], 34 | "block-spacing": [ 35 | "error", 36 | "always" 37 | ], 38 | "camelcase": [ 39 | "error" 40 | ], 41 | "eqeqeq": [ 42 | "error", 43 | "always" 44 | ], 45 | "strict": [ 46 | "error", 47 | "global" 48 | ], 49 | "brace-style": [ 50 | "error", 51 | "1tbs", 52 | { 53 | "allowSingleLine": true 54 | } 55 | ], 56 | "comma-style": [ 57 | "error", 58 | "last" 59 | ], 60 | "comma-spacing": [ 61 | "error", 62 | { 63 | "before": false, 64 | "after": true 65 | } 66 | ], 67 | "eol-last": [ 68 | "error" 69 | ], 70 | "func-call-spacing": [ 71 | "error", 72 | "never" 73 | ], 74 | "key-spacing": [ 75 | "error", 76 | { 77 | "beforeColon": false, 78 | "afterColon": true, 79 | "mode": "minimum" 80 | } 81 | ], 82 | "keyword-spacing": [ 83 | "error", 84 | { 85 | "before": true, 86 | "after": true, 87 | "overrides": { 88 | "function": { 89 | "after": false 90 | } 91 | } 92 | } 93 | ], 94 | "max-len": [ 95 | "error", 96 | { 97 | "code": 80, 98 | "ignoreUrls": true 99 | } 100 | ], 101 | "max-nested-callbacks": [ 102 | "error", 103 | { 104 | "max": 7 105 | } 106 | ], 107 | "new-cap": [ 108 | "error", 109 | { 110 | "newIsCap": true, 111 | "capIsNew": false, 112 | "properties": true 113 | } 114 | ], 115 | "new-parens": [ 116 | "error" 117 | ], 118 | "no-lonely-if": [ 119 | "error" 120 | ], 121 | "no-trailing-spaces": [ 122 | "error" 123 | ], 124 | "no-unneeded-ternary": [ 125 | "error" 126 | ], 127 | "no-whitespace-before-property": [ 128 | "error" 129 | ], 130 | "object-curly-spacing": [ 131 | "error", 132 | "always" 133 | ], 134 | "operator-assignment": [ 135 | "error", 136 | "always" 137 | ], 138 | "operator-linebreak": [ 139 | "error", 140 | "after" 141 | ], 142 | "semi-spacing": [ 143 | "error", 144 | { 145 | "before": false, 146 | "after": true 147 | } 148 | ], 149 | "space-before-blocks": [ 150 | "error", 151 | "always" 152 | ], 153 | "space-before-function-paren": [ 154 | "error", 155 | { 156 | "anonymous": "never", 157 | "named": "never", 158 | "asyncArrow": "always" 159 | } 160 | ], 161 | "space-in-parens": [ 162 | "error", 163 | "never" 164 | ], 165 | "space-infix-ops": [ 166 | "error" 167 | ], 168 | "space-unary-ops": [ 169 | "error", 170 | { 171 | "words": true, 172 | "nonwords": false, 173 | "overrides": { 174 | "typeof": false 175 | } 176 | } 177 | ], 178 | "no-unreachable": [ 179 | "error" 180 | ], 181 | "no-global-assign": [ 182 | "error" 183 | ], 184 | "no-self-compare": [ 185 | "error" 186 | ], 187 | "no-unmodified-loop-condition": [ 188 | "error" 189 | ], 190 | "no-constant-condition": [ 191 | "error", 192 | { 193 | "checkLoops": false 194 | } 195 | ], 196 | "no-console": [ 197 | "off" 198 | ], 199 | "no-useless-concat": [ 200 | "error" 201 | ], 202 | "no-useless-escape": [ 203 | "error" 204 | ], 205 | "no-shadow-restricted-names": [ 206 | "error" 207 | ], 208 | "no-use-before-define": [ 209 | "error", 210 | { 211 | "functions": false 212 | } 213 | ], 214 | "arrow-parens": [ 215 | "error", 216 | "always" 217 | ], 218 | "arrow-body-style": [ 219 | "error", 220 | "as-needed" 221 | ], 222 | "arrow-spacing": [ 223 | "error" 224 | ], 225 | "no-confusing-arrow": [ 226 | "error", 227 | { 228 | "allowParens": true 229 | } 230 | ], 231 | "no-useless-computed-key": [ 232 | "error" 233 | ], 234 | "no-useless-rename": [ 235 | "error" 236 | ], 237 | "no-var": [ 238 | "error" 239 | ], 240 | "object-shorthand": [ 241 | "error", 242 | "always" 243 | ], 244 | "prefer-arrow-callback": [ 245 | "error" 246 | ], 247 | "prefer-const": [ 248 | "error" 249 | ], 250 | "prefer-numeric-literals": [ 251 | "error" 252 | ], 253 | "prefer-rest-params": [ 254 | "error" 255 | ], 256 | "prefer-spread": [ 257 | "error" 258 | ], 259 | "rest-spread-spacing": [ 260 | "error", 261 | "never" 262 | ], 263 | "template-curly-spacing": [ 264 | "error", 265 | "never" 266 | ], 267 | "consistent-return": [ 268 | "error", 269 | { "treatUndefinedAsUnspecified": true } 270 | ] 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /JavaScript/1-test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { Pool } = require('pg'); 4 | 5 | const pool = new Pool({ 6 | host: '127.0.0.1', 7 | port: 5432, 8 | database: 'application', 9 | user: 'marcus', 10 | password: 'marcus', 11 | }); 12 | 13 | const fields = ['schemaname', 'tablename', 'tableowner'].join(', '); 14 | const sql = `SELECT ${fields} FROM pg_tables WHERE tableowner = $1`; 15 | pool.query(sql, ['marcus'], (err, res) => { 16 | if (err) { 17 | throw err; 18 | } 19 | console.dir({ res }); 20 | console.table(res.fields); 21 | console.table(res.rows); 22 | pool.end(); 23 | }); 24 | -------------------------------------------------------------------------------- /JavaScript/2-async.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { Pool } = require('pg'); 4 | 5 | const pool = new Pool({ 6 | host: '127.0.0.1', 7 | port: 5432, 8 | database: 'application', 9 | user: 'marcus', 10 | password: 'marcus', 11 | }); 12 | 13 | (async () => { 14 | const fields = ['schemaname', 'tablename', 'tableowner'].join(', '); 15 | const sql = `SELECT ${fields} FROM pg_tables WHERE tableowner = $1`; 16 | const { rows } = await pool.query(sql, ['marcus']); 17 | console.table(rows); 18 | pool.end(); 19 | })(); 20 | -------------------------------------------------------------------------------- /JavaScript/3-promise.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { Pool } = require('pg'); 4 | 5 | const pool = new Pool({ 6 | host: '127.0.0.1', 7 | port: 5432, 8 | database: 'application', 9 | user: 'marcus', 10 | password: 'marcus', 11 | }); 12 | 13 | const fields = ['schemaname', 'tablename', 'tableowner', 'hasindexes']; 14 | const sql = 'SELECT ' + fields.join(', ') + 15 | ' FROM pg_catalog.pg_tables WHERE tableowner = $1'; 16 | pool.query(sql, ['marcus']) 17 | .then((res) => { 18 | const { rows } = res; 19 | console.table(rows); 20 | }) 21 | .catch((err) => { 22 | console.log(err); 23 | }) 24 | .finally(() => { 25 | pool.end(); 26 | }); 27 | -------------------------------------------------------------------------------- /JavaScript/README.md: -------------------------------------------------------------------------------- 1 | ## Подготовка окружения для работы с БД 2 | 3 | - Установка сервера для Linux, Windows, MacOS, BSD, Solaris 4 | - Дистрибутивы: https://www.postgresql.org/download/ 5 | - Инструкция для Fedora: https://fedoraproject.org/wiki/PostgreSQL#Installation 6 | - Готовые скрипты: https://github.com/metarhia/impress/blob/master/deploy/ 7 | - Установка PgSQL Admin 8 | - Дистрибутивы: https://www.pgadmin.org/download/ 9 | - Для Fedora: `dnf install pgadmin3` 10 | - Создание пользователя и базу данных 11 | - `su - postgres` 12 | - `psql` попадаем в командную строку PostgreSQL 13 | - `\password postgres` устанавливаем паполь пользователю 14 | - создаем нового пользователя `CREATE USER marcus WITH PASSWORD 'marcus';` 15 | - создаем базу данных `CREATE DATABASE application OWNER marcus;` 16 | - `\quit` выходим 17 | - Исполняем файл с SQL скриптом создания базы 18 | - `sudo psql -U marcus -d application -a -f example.sql` 19 | - Установка зависимостей (включая модуль `pg`) `npm i` 20 | - Запуск `node application.js` 21 | -------------------------------------------------------------------------------- /JavaScript/application.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const db = require('./db.js'); 4 | 5 | const pg = db.open({ 6 | host: '127.0.0.1', 7 | port: 5432, 8 | database: 'application', 9 | user: 'marcus', 10 | password: 'marcus', 11 | }); 12 | 13 | console.dir({ pg }); 14 | 15 | pg.select('pg_tables') 16 | .where({ tableowner: 'marcus', schemaname: 'public' }) 17 | .fields(['schemaname', 'tablename', 'tableowner', 'hasindexes']) 18 | .order('tablename') 19 | .then((rows) => { 20 | console.table(rows); 21 | pg.close(); 22 | }); 23 | -------------------------------------------------------------------------------- /JavaScript/db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { Pool } = require('pg'); 4 | 5 | const where = (conditions) => { 6 | let clause = ''; 7 | const args = []; 8 | let i = 1; 9 | for (const key in conditions) { 10 | let value = conditions[key]; 11 | let condition; 12 | if (typeof value === 'number') { 13 | condition = `${key} = $${i}`; 14 | } else if (typeof value === 'string') { 15 | if (value.startsWith('>=')) { 16 | condition = `${key} >= $${i}`; 17 | value = value.substring(2); 18 | } else if (value.startsWith('<=')) { 19 | condition = `${key} <= $${i}`; 20 | value = value.substring(2); 21 | } else if (value.startsWith('<>')) { 22 | condition = `${key} <> $${i}`; 23 | value = value.substring(2); 24 | } else if (value.startsWith('>')) { 25 | condition = `${key} > $${i}`; 26 | value = value.substring(1); 27 | } else if (value.startsWith('<')) { 28 | condition = `${key} < $${i}`; 29 | value = value.substring(1); 30 | } else if (value.includes('*') || value.includes('?')) { 31 | value = value.replace(/\*/g, '%').replace(/\?/g, '_'); 32 | condition = `${key} LIKE $${i}`; 33 | } else { 34 | condition = `${key} = $${i}`; 35 | } 36 | } 37 | i++; 38 | args.push(value); 39 | clause = clause ? `${clause} AND ${condition}` : condition; 40 | } 41 | return { clause, args }; 42 | }; 43 | 44 | const MODE_ROWS = 0; 45 | const MODE_VALUE = 1; 46 | const MODE_ROW = 2; 47 | const MODE_COL = 3; 48 | const MODE_COUNT = 4; 49 | 50 | class Cursor { 51 | constructor(database, table) { 52 | this.database = database; 53 | this.table = table; 54 | this.cols = null; 55 | this.rows = null; 56 | this.rowCount = 0; 57 | this.ready = false; 58 | this.mode = MODE_ROWS; 59 | this.whereClause = undefined; 60 | this.columns = ['*']; 61 | this.args = []; 62 | this.orderBy = undefined; 63 | } 64 | 65 | resolve(result) { 66 | const { rows, fields, rowCount } = result; 67 | this.rows = rows; 68 | this.cols = fields; 69 | this.rowCount = rowCount; 70 | } 71 | 72 | where(conditions) { 73 | const { clause, args } = where(conditions); 74 | this.whereClause = clause; 75 | this.args = args; 76 | return this; 77 | } 78 | 79 | fields(list) { 80 | this.columns = list; 81 | return this; 82 | } 83 | 84 | value() { 85 | this.mode = MODE_VALUE; 86 | return this; 87 | } 88 | 89 | row() { 90 | this.mode = MODE_ROW; 91 | return this; 92 | } 93 | 94 | col(name) { 95 | this.mode = MODE_COL; 96 | this.columnName = name; 97 | return this; 98 | } 99 | 100 | count() { 101 | this.mode = MODE_COUNT; 102 | return this; 103 | } 104 | 105 | order(name) { 106 | this.orderBy = name; 107 | return this; 108 | } 109 | 110 | then(callback) { 111 | // TODO: store callback to pool 112 | const { mode, table, columns, args } = this; 113 | const { whereClause, orderBy, columnName } = this; 114 | const fields = columns.join(', '); 115 | let sql = `SELECT ${fields} FROM ${table}`; 116 | if (whereClause) sql += ` WHERE ${whereClause}`; 117 | if (orderBy) sql += ` ORDER BY ${orderBy}`; 118 | this.database.query(sql, args, (err, res) => { 119 | this.resolve(res); 120 | const { rows, cols } = this; 121 | if (mode === MODE_VALUE) { 122 | const col = cols[0]; 123 | const row = rows[0]; 124 | callback(row[col.name]); 125 | } else if (mode === MODE_ROW) { 126 | callback(rows[0]); 127 | } else if (mode === MODE_COL) { 128 | const col = []; 129 | for (const row of rows) { 130 | col.push(row[columnName]); 131 | } 132 | callback(col); 133 | } else if (mode === MODE_COUNT) { 134 | callback(this.rowCount); 135 | } else { 136 | callback(rows); 137 | } 138 | }); 139 | return this; 140 | } 141 | } 142 | 143 | class Database { 144 | constructor(config, logger) { 145 | this.pool = new Pool(config); 146 | this.config = config; 147 | this.logger = logger; 148 | } 149 | 150 | query(sql, values, callback) { 151 | if (typeof values === 'function') { 152 | callback = values; 153 | values = []; 154 | } 155 | const startTime = new Date().getTime(); 156 | console.log({ sql, values }); 157 | this.pool.query(sql, values, (err, res) => { 158 | const endTime = new Date().getTime(); 159 | const executionTime = endTime - startTime; 160 | console.log(`Execution time: ${executionTime}`); 161 | if (callback) callback(err, res); 162 | }); 163 | } 164 | 165 | select(table) { 166 | return new Cursor(this, table); 167 | } 168 | 169 | close() { 170 | this.pool.end(); 171 | } 172 | } 173 | 174 | module.exports = { 175 | open: (config, logger) => new Database(config, logger), 176 | }; 177 | -------------------------------------------------------------------------------- /JavaScript/example.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE SystemUser ( 2 | Id serial, 3 | Login varchar(64) NOT NULL, 4 | Password varchar(64) NOT NULL, 5 | FullName varchar(255) 6 | ); 7 | 8 | ALTER TABLE SystemUser ADD CONSTRAINT pkSystemUser PRIMARY KEY (Id); 9 | 10 | CREATE UNIQUE INDEX akSystemUserLogin ON SystemUser (Login); 11 | 12 | CREATE TABLE SystemGroup ( 13 | Id serial, 14 | Name varchar(64) NOT NULL 15 | ); 16 | 17 | ALTER TABLE SystemGroup ADD CONSTRAINT pkSystemGroup PRIMARY KEY (Id); 18 | 19 | CREATE UNIQUE INDEX akSystemGroupName ON SystemGroup (Name); 20 | 21 | CREATE TABLE GroupUser ( 22 | GroupId integer NOT NULL, 23 | UserId integer NOT NULL 24 | ); 25 | 26 | ALTER TABLE GroupUser ADD CONSTRAINT pkGroupUser PRIMARY KEY (GroupId, UserId); 27 | ALTER TABLE GroupUser ADD CONSTRAINT fkGroupUserGroupId FOREIGN KEY (GroupId) REFERENCES SystemGroup (Id) ON DELETE CASCADE; 28 | ALTER TABLE GroupUser ADD CONSTRAINT fkGroupUserUserId FOREIGN KEY (UserId) REFERENCES SystemUser (Id) ON DELETE CASCADE; 29 | 30 | CREATE TABLE Session ( 31 | Id serial, 32 | UserId integer NOT NULL, 33 | Token varchar(64) NOT NULL, 34 | IP varchar(45) NOT NULL, 35 | Data text 36 | ); 37 | 38 | ALTER TABLE Session ADD CONSTRAINT pkSession PRIMARY KEY (Id); 39 | 40 | CREATE UNIQUE INDEX akSession ON Session (Token); 41 | 42 | ALTER TABLE Session ADD CONSTRAINT fkSessionUserId FOREIGN KEY (UserId) REFERENCES Session (Id) ON DELETE CASCADE; 43 | -------------------------------------------------------------------------------- /JavaScript/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dbms-application", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "dbms-application", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "pg": "^8.11.3" 13 | } 14 | }, 15 | "node_modules/buffer-writer": { 16 | "version": "2.0.0", 17 | "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", 18 | "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", 19 | "engines": { 20 | "node": ">=4" 21 | } 22 | }, 23 | "node_modules/inherits": { 24 | "version": "2.0.4", 25 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 26 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 27 | }, 28 | "node_modules/packet-reader": { 29 | "version": "1.0.0", 30 | "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", 31 | "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" 32 | }, 33 | "node_modules/pg": { 34 | "version": "8.11.3", 35 | "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", 36 | "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", 37 | "dependencies": { 38 | "buffer-writer": "2.0.0", 39 | "packet-reader": "1.0.0", 40 | "pg-connection-string": "^2.6.2", 41 | "pg-pool": "^3.6.1", 42 | "pg-protocol": "^1.6.0", 43 | "pg-types": "^2.1.0", 44 | "pgpass": "1.x" 45 | }, 46 | "engines": { 47 | "node": ">= 8.0.0" 48 | }, 49 | "optionalDependencies": { 50 | "pg-cloudflare": "^1.1.1" 51 | }, 52 | "peerDependencies": { 53 | "pg-native": ">=3.0.1" 54 | }, 55 | "peerDependenciesMeta": { 56 | "pg-native": { 57 | "optional": true 58 | } 59 | } 60 | }, 61 | "node_modules/pg-cloudflare": { 62 | "version": "1.1.1", 63 | "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", 64 | "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", 65 | "optional": true 66 | }, 67 | "node_modules/pg-connection-string": { 68 | "version": "2.6.2", 69 | "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", 70 | "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" 71 | }, 72 | "node_modules/pg-int8": { 73 | "version": "1.0.1", 74 | "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", 75 | "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", 76 | "engines": { 77 | "node": ">=4.0.0" 78 | } 79 | }, 80 | "node_modules/pg-pool": { 81 | "version": "3.6.1", 82 | "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", 83 | "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", 84 | "peerDependencies": { 85 | "pg": ">=8.0" 86 | } 87 | }, 88 | "node_modules/pg-protocol": { 89 | "version": "1.6.0", 90 | "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", 91 | "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" 92 | }, 93 | "node_modules/pg-types": { 94 | "version": "2.2.0", 95 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", 96 | "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", 97 | "dependencies": { 98 | "pg-int8": "1.0.1", 99 | "postgres-array": "~2.0.0", 100 | "postgres-bytea": "~1.0.0", 101 | "postgres-date": "~1.0.4", 102 | "postgres-interval": "^1.1.0" 103 | }, 104 | "engines": { 105 | "node": ">=4" 106 | } 107 | }, 108 | "node_modules/pgpass": { 109 | "version": "1.0.4", 110 | "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", 111 | "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", 112 | "dependencies": { 113 | "split2": "^3.1.1" 114 | } 115 | }, 116 | "node_modules/postgres-array": { 117 | "version": "2.0.0", 118 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", 119 | "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", 120 | "engines": { 121 | "node": ">=4" 122 | } 123 | }, 124 | "node_modules/postgres-bytea": { 125 | "version": "1.0.0", 126 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", 127 | "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=", 128 | "engines": { 129 | "node": ">=0.10.0" 130 | } 131 | }, 132 | "node_modules/postgres-date": { 133 | "version": "1.0.7", 134 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", 135 | "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", 136 | "engines": { 137 | "node": ">=0.10.0" 138 | } 139 | }, 140 | "node_modules/postgres-interval": { 141 | "version": "1.2.0", 142 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", 143 | "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", 144 | "dependencies": { 145 | "xtend": "^4.0.0" 146 | }, 147 | "engines": { 148 | "node": ">=0.10.0" 149 | } 150 | }, 151 | "node_modules/readable-stream": { 152 | "version": "3.6.0", 153 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 154 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 155 | "dependencies": { 156 | "inherits": "^2.0.3", 157 | "string_decoder": "^1.1.1", 158 | "util-deprecate": "^1.0.1" 159 | }, 160 | "engines": { 161 | "node": ">= 6" 162 | } 163 | }, 164 | "node_modules/safe-buffer": { 165 | "version": "5.2.1", 166 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 167 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 168 | "funding": [ 169 | { 170 | "type": "github", 171 | "url": "https://github.com/sponsors/feross" 172 | }, 173 | { 174 | "type": "patreon", 175 | "url": "https://www.patreon.com/feross" 176 | }, 177 | { 178 | "type": "consulting", 179 | "url": "https://feross.org/support" 180 | } 181 | ] 182 | }, 183 | "node_modules/split2": { 184 | "version": "3.2.2", 185 | "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", 186 | "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", 187 | "dependencies": { 188 | "readable-stream": "^3.0.0" 189 | } 190 | }, 191 | "node_modules/string_decoder": { 192 | "version": "1.3.0", 193 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 194 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 195 | "dependencies": { 196 | "safe-buffer": "~5.2.0" 197 | } 198 | }, 199 | "node_modules/util-deprecate": { 200 | "version": "1.0.2", 201 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 202 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 203 | }, 204 | "node_modules/xtend": { 205 | "version": "4.0.2", 206 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 207 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 208 | "engines": { 209 | "node": ">=0.4" 210 | } 211 | } 212 | }, 213 | "dependencies": { 214 | "buffer-writer": { 215 | "version": "2.0.0", 216 | "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", 217 | "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" 218 | }, 219 | "inherits": { 220 | "version": "2.0.4", 221 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 222 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 223 | }, 224 | "packet-reader": { 225 | "version": "1.0.0", 226 | "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", 227 | "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" 228 | }, 229 | "pg": { 230 | "version": "8.11.3", 231 | "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", 232 | "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", 233 | "requires": { 234 | "buffer-writer": "2.0.0", 235 | "packet-reader": "1.0.0", 236 | "pg-cloudflare": "^1.1.1", 237 | "pg-connection-string": "^2.6.2", 238 | "pg-pool": "^3.6.1", 239 | "pg-protocol": "^1.6.0", 240 | "pg-types": "^2.1.0", 241 | "pgpass": "1.x" 242 | } 243 | }, 244 | "pg-cloudflare": { 245 | "version": "1.1.1", 246 | "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", 247 | "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", 248 | "optional": true 249 | }, 250 | "pg-connection-string": { 251 | "version": "2.6.2", 252 | "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", 253 | "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" 254 | }, 255 | "pg-int8": { 256 | "version": "1.0.1", 257 | "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", 258 | "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" 259 | }, 260 | "pg-pool": { 261 | "version": "3.6.1", 262 | "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", 263 | "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", 264 | "requires": {} 265 | }, 266 | "pg-protocol": { 267 | "version": "1.6.0", 268 | "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", 269 | "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" 270 | }, 271 | "pg-types": { 272 | "version": "2.2.0", 273 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", 274 | "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", 275 | "requires": { 276 | "pg-int8": "1.0.1", 277 | "postgres-array": "~2.0.0", 278 | "postgres-bytea": "~1.0.0", 279 | "postgres-date": "~1.0.4", 280 | "postgres-interval": "^1.1.0" 281 | } 282 | }, 283 | "pgpass": { 284 | "version": "1.0.4", 285 | "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", 286 | "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", 287 | "requires": { 288 | "split2": "^3.1.1" 289 | } 290 | }, 291 | "postgres-array": { 292 | "version": "2.0.0", 293 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", 294 | "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" 295 | }, 296 | "postgres-bytea": { 297 | "version": "1.0.0", 298 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", 299 | "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" 300 | }, 301 | "postgres-date": { 302 | "version": "1.0.7", 303 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", 304 | "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" 305 | }, 306 | "postgres-interval": { 307 | "version": "1.2.0", 308 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", 309 | "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", 310 | "requires": { 311 | "xtend": "^4.0.0" 312 | } 313 | }, 314 | "readable-stream": { 315 | "version": "3.6.0", 316 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 317 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 318 | "requires": { 319 | "inherits": "^2.0.3", 320 | "string_decoder": "^1.1.1", 321 | "util-deprecate": "^1.0.1" 322 | } 323 | }, 324 | "safe-buffer": { 325 | "version": "5.2.1", 326 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 327 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 328 | }, 329 | "split2": { 330 | "version": "3.2.2", 331 | "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", 332 | "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", 333 | "requires": { 334 | "readable-stream": "^3.0.0" 335 | } 336 | }, 337 | "string_decoder": { 338 | "version": "1.3.0", 339 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 340 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 341 | "requires": { 342 | "safe-buffer": "~5.2.0" 343 | } 344 | }, 345 | "util-deprecate": { 346 | "version": "1.0.2", 347 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 348 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 349 | }, 350 | "xtend": { 351 | "version": "4.0.2", 352 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 353 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" 354 | } 355 | } 356 | } 357 | -------------------------------------------------------------------------------- /JavaScript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dbms-application", 3 | "version": "1.0.0", 4 | "description": "DBMS Application Example", 5 | "author": "Timur Shemsedinov ", 6 | "license": "MIT", 7 | "main": "application.js", 8 | "dependencies": { 9 | "pg": "^8.11.3" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2023 How.Programming.Works contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Databases and SQL 2 | 3 | [![Базы данных в 2020 (введение, история, состояние)](https://img.youtube.com/vi/8RjT2VYBWNQ/0.jpg)](https://youtu.be/8RjT2VYBWNQ) 4 | 5 | [![PostgreSQL: установка, настройка, консоль](https://img.youtube.com/vi/Fm6yLb8qCh4/0.jpg)](https://youtu.be/Fm6yLb8qCh4) 6 | 7 | [![Работа с базами данных в Node.js на примере PostgreSQL](https://img.youtube.com/vi/2tDvHQCBt3w/0.jpg)](https://youtu.be/2tDvHQCBt3w) 8 | --------------------------------------------------------------------------------