diff --git a/.gitignore b/.gitignore index 2f49144f0..822623c1a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ node_modules/ **/*-secret.json **/*.sh .idea -.env \ No newline at end of file +.env +test.js \ No newline at end of file diff --git a/Week1/prep/prep-exe.sql b/Week1/prep/prep-exe.sql new file mode 100644 index 000000000..62905a754 --- /dev/null +++ b/Week1/prep/prep-exe.sql @@ -0,0 +1,96 @@ +-- Очищаем существующие таблицы (для повторного запуска) +DROP TABLE IF EXISTS recipe_methods; +DROP TABLE IF EXISTS recipe_ingredients; +DROP TABLE IF EXISTS recipe_categories; +DROP TABLE IF EXISTS recipes; +DROP TABLE IF EXISTS cooking_methods; +DROP TABLE IF EXISTS ingredients; +DROP TABLE IF EXISTS main_ingredients; +DROP TABLE IF EXISTS categories; +DROP TABLE IF EXISTS cuisines; + +--------------------------------------------------------- +-- 1. Таблица кухонь (Italian, Chinese, Japanese…) +--------------------------------------------------------- +CREATE TABLE cuisines ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL UNIQUE +); + +--------------------------------------------------------- +-- 2. Таблица основных ингредиентов (мясо, рыба, овощи) +--------------------------------------------------------- +CREATE TABLE main_ingredients ( + id SERIAL PRIMARY KEY, + name VARCHAR(150) NOT NULL UNIQUE +); + +--------------------------------------------------------- +-- 3. Таблица всех возможных ингредиентов (морковь, масло, соль) +--------------------------------------------------------- +CREATE TABLE ingredients ( + id SERIAL PRIMARY KEY, + name VARCHAR(150) NOT NULL UNIQUE +); + +--------------------------------------------------------- +-- 4. Таблица категорий (суп, салат, десерт, завтрак) +--------------------------------------------------------- +CREATE TABLE categories ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL UNIQUE +); + +--------------------------------------------------------- +-- 5. Таблица методов приготовления (жарка, запекание, варка) +--------------------------------------------------------- +CREATE TABLE cooking_methods ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL UNIQUE +); + +--------------------------------------------------------- +-- 6. Главная таблица рецептов +--------------------------------------------------------- +CREATE TABLE recipes ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + cuisine_id INT, + main_ingredient_id INT, + FOREIGN KEY (cuisine_id) REFERENCES cuisines(id), + FOREIGN KEY (main_ingredient_id) REFERENCES main_ingredients(id) +); + +--------------------------------------------------------- +-- 7. Связь рецепт ↔ категории (many-to-many) +--------------------------------------------------------- +CREATE TABLE recipe_categories ( + recipe_id INT NOT NULL, + category_id INT NOT NULL, + PRIMARY KEY (recipe_id, category_id), + FOREIGN KEY (recipe_id) REFERENCES recipes(id), + FOREIGN KEY (category_id) REFERENCES categories(id) +); + +--------------------------------------------------------- +-- 8. Связь рецепт ↔ ингредиенты (many-to-many) +--------------------------------------------------------- +CREATE TABLE recipe_ingredients ( + recipe_id INT NOT NULL, + ingredient_id INT NOT NULL, + amount VARCHAR(50), -- например "200 г", "1 ст.л." + PRIMARY KEY (recipe_id, ingredient_id), + FOREIGN KEY (recipe_id) REFERENCES recipes(id), + FOREIGN KEY (ingredient_id) REFERENCES ingredients(id) +); + +--------------------------------------------------------- +-- 9. Связь рецепт ↔ методы приготовления (many-to-many) +--------------------------------------------------------- +CREATE TABLE recipe_methods ( + recipe_id INT NOT NULL, + method_id INT NOT NULL, + PRIMARY KEY (recipe_id, method_id), + FOREIGN KEY (recipe_id) REFERENCES recipes(id), + FOREIGN KEY (method_id) REFERENCES cooking_methods(id) +); \ No newline at end of file diff --git a/Week2/prep/Database ER diagram (crow's foot).png b/Week2/prep/Database ER diagram (crow's foot).png new file mode 100644 index 000000000..579c05848 Binary files /dev/null and b/Week2/prep/Database ER diagram (crow's foot).png differ diff --git a/Week2/prep/Lucid connection.png b/Week2/prep/Lucid connection.png new file mode 100644 index 000000000..8321abffd Binary files /dev/null and b/Week2/prep/Lucid connection.png differ diff --git a/Week2/prep/w1-prep-exe.sql b/Week2/prep/w1-prep-exe.sql new file mode 100644 index 000000000..584bf10ec --- /dev/null +++ b/Week2/prep/w1-prep-exe.sql @@ -0,0 +1,111 @@ +-- Очищаем существующие таблицы (для повторного запуска) -- Drop existing tables (for re-running the script) +DROP TABLE IF EXISTS cuisines CASCADE; +DROP TABLE IF EXISTS main_ingredients CASCADE; +DROP TABLE IF EXISTS ingredients CASCADE; +DROP TABLE IF EXISTS categories CASCADE; +DROP TABLE IF EXISTS cooking_methods CASCADE; +DROP TABLE IF EXISTS recipes CASCADE; +DROP TABLE IF EXISTS recipe_categories CASCADE; +DROP TABLE IF EXISTS recipe_ingredients CASCADE; +DROP TABLE IF EXISTS recipe_methods CASCADE; +DROP TABLE IF EXISTS recipe_ingredient_amounts CASCADE; + + + +--------------------------------------------------------- +-- 1. Таблица кухонь (Italian, Chinese, Japanese…) -- Table of Cuisines (Italian, Chinese, Japanese…) +--------------------------------------------------------- +CREATE TABLE cuisines ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL UNIQUE +); + +--------------------------------------------------------- +-- 2. Таблица основных ингредиентов (мясо, рыба, овощи) -- Table of Main Ingredients (meat, fish, vegetables) +--------------------------------------------------------- +CREATE TABLE main_ingredients ( + id SERIAL PRIMARY KEY, + name VARCHAR(150) NOT NULL UNIQUE +); + +--------------------------------------------------------- +-- 3. Таблица всех возможных ингредиентов (морковь, масло, соль) -- Table of All Possible Ingredients (carrot, oil, salt) +--------------------------------------------------------- +CREATE TABLE ingredients ( + id SERIAL PRIMARY KEY, + name VARCHAR(150) NOT NULL UNIQUE +); + +--------------------------------------------------------- +-- 4. Таблица категорий (суп, салат, десерт, завтрак) -- Table of Categories (soup, salad, dessert, breakfast) +--------------------------------------------------------- +CREATE TABLE categories ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL UNIQUE +); + +--------------------------------------------------------- +-- 5. Таблица методов приготовления (жарка, запекание, варка) -- Table of Cooking Methods (frying, baking, boiling) +--------------------------------------------------------- +CREATE TABLE cooking_methods ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL UNIQUE +); + +--------------------------------------------------------- +-- 6. Главная таблица рецептов -- Main Recipes Table +--------------------------------------------------------- +CREATE TABLE recipes ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + cuisine_id INT, + main_ingredient_id INT, + FOREIGN KEY (cuisine_id) REFERENCES cuisines(id), + FOREIGN KEY (main_ingredient_id) REFERENCES main_ingredients(id) +); + +--------------------------------------------------------- +-- 7. Связь рецепт ↔ категории (many-to-many) -- Recipe ↔ Categories Relationship (many-to-many) +--------------------------------------------------------- +CREATE TABLE recipe_categories ( + recipe_id INT NOT NULL, + category_id INT NOT NULL, + PRIMARY KEY (recipe_id, category_id), + FOREIGN KEY (recipe_id) REFERENCES recipes(id), + FOREIGN KEY (category_id) REFERENCES categories(id) +); + +--------------------------------------------------------- +-- 8. Связь рецепт ↔ ингредиенты (many-to-many) -- Recipe ↔ Ingredients Relationship (many-to-many) +--------------------------------------------------------- +CREATE TABLE recipe_ingredients ( + recipe_id INT NOT NULL, + ingredient_id INT NOT NULL, + amount VARCHAR(50), -- например "200 г", "1 ст.л." + PRIMARY KEY (recipe_id, ingredient_id), + FOREIGN KEY (recipe_id) REFERENCES recipes(id), + FOREIGN KEY (ingredient_id) REFERENCES ingredients(id) +); + +--------------------------------------------------------- +-- 9. Связь рецепт ↔ методы приготовления (many-to-many) -- Recipe ↔ Cooking Methods Relationship (many-to-many) +--------------------------------------------------------- +CREATE TABLE recipe_methods ( + recipe_id INT NOT NULL, + method_id INT NOT NULL, + PRIMARY KEY (recipe_id, method_id), + FOREIGN KEY (recipe_id) REFERENCES recipes(id), + FOREIGN KEY (method_id) REFERENCES cooking_methods(id) +); + +--------------------------------------------------------- +-- 10. кол-во ингредиентов в рецепте -- Quantity of Ingredients in Recipe +--------------------------------------------------------- +CREATE TABLE recipe_ingredient_amounts ( + recipe_id INT NOT NULL, + ingredient_id INT NOT NULL, + amount VARCHAR(50) NOT NULL, -- например "200 г", "1 ст.л." + PRIMARY KEY (recipe_id, ingredient_id), + FOREIGN KEY (recipe_id) REFERENCES recipes(id), + FOREIGN KEY (ingredient_id) REFERENCES ingredients(id) +); \ No newline at end of file diff --git a/Week2/prep/w2-prep-insert-mok-data.sql b/Week2/prep/w2-prep-insert-mok-data.sql new file mode 100644 index 000000000..05a9b7d77 --- /dev/null +++ b/Week2/prep/w2-prep-insert-mok-data.sql @@ -0,0 +1,98 @@ +-- ========================================== +-- Mock data inserts for Week 2 Prep Exercise +-- ========================================== + +-- 1. Cuisines +INSERT INTO cuisines (name) VALUES +('Japanese') +ON CONFLICT (name) DO NOTHING; + +-- 2. Main ingredients +INSERT INTO main_ingredients (name) VALUES +('Cheese'), +('Vegetables'), +('Pasta'), +('Eggs') +ON CONFLICT (name) DO NOTHING; + +-- 3. Categories +INSERT INTO categories (name) VALUES +('Cake'), +('No-Bake'), +('Vegetarian'), +('Vegan'), +('Gluten-Free'), +('Japanese') +ON CONFLICT (name) DO NOTHING; + +-- 4. Ingredients +INSERT INTO ingredients (name) VALUES +('Cheese'), +('Vegetables'), +('Pasta'), +('Eggs'), +('Condensed milk'), +('Cream Cheese'), +('Lemon Juice'), +('Pie Crust'), +('Cherry Jam'), +('Brussels Sprouts'), +('Sesame seeds'), +('Pepper'), +('Salt'), +('Olive oil'), +('Macaroni'), +('Butter'), +('Flour'), +('Milk'), +('Shredded Cheddar cheese'), +('Soy sauce'), +('Sugar') +ON CONFLICT (name) DO NOTHING; + +-- 5. Recipes +INSERT INTO recipes (name, cuisine_id, main_ingredient_id) VALUES +('No-Bake Cheesecake', NULL, 1), +('Roasted Brussels Sprouts', NULL, 2), +('Mac & Cheese', NULL, 3), +('Tamagoyaki Japanese Omelette', 1, 4) +ON CONFLICT DO NOTHING; + +-- 6. Recipe ↔ Categories +INSERT INTO recipe_categories (recipe_id, category_id) VALUES +(1, 1), (1, 2), (1, 3), +(2, 4), (2, 5), +(3, 3), +(4, 3), (4, 6) +ON CONFLICT DO NOTHING; + +-- 7. Recipe ↔ Ingredients +INSERT INTO recipe_ingredients (recipe_id, ingredient_id, amount) VALUES +-- No-Bake Cheesecake +(1, 5, '200 ml'), +(1, 6, '250 g'), +(1, 7, '1 tbsp'), +(1, 8, '1 crust'), +(1, 9, '2 tbsp'), +-- Roasted Brussels Sprouts +(2, 10, '500 g'), +(2, 7, '1 tbsp'), +(2, 11, '1 tsp'), +(2, 12, '1 tsp'), +(2, 13, '1 tsp'), +(2, 14, '2 tbsp'), +-- Mac & Cheese +(3, 15, '200 g'), +(3, 16, '50 g'), +(3, 17, '2 tbsp'), +(3, 13, '1 tsp'), +(3, 12, '1 tsp'), +(3, 18, '200 ml'), +(3, 19, '150 g'), +-- Tamagoyaki Japanese Omelette +(4, 4, '4'), +(4, 20, '1 tbsp'), +(4, 21, '1 tsp'), +(4, 13, '1 tsp'), +(4, 14, '1 tbsp') +ON CONFLICT DO NOTHING; \ No newline at end of file diff --git a/Week2/prep/w2-request.sql b/Week2/prep/w2-request.sql new file mode 100644 index 000000000..6e076e107 --- /dev/null +++ b/Week2/prep/w2-request.sql @@ -0,0 +1,24 @@ +-- 1. All vegetarian recipes with potatoes (но картошки нет в данных) +SELECT r.name AS recipe_name +FROM recipes r +JOIN recipe_categories rc ON r.id = rc.recipe_id +JOIN categories c ON rc.category_id = c.id +WHERE c.name = 'Vegetarian'; + +-- 2. All cakes that do not need baking +SELECT r.name AS recipe_name +FROM recipes r +JOIN recipe_categories rc1 ON r.id = rc1.recipe_id +JOIN categories c1 ON rc1.category_id = c1.id +JOIN recipe_categories rc2 ON r.id = rc2.recipe_id +JOIN categories c2 ON rc2.category_id = c2.id +WHERE c1.name = 'Cake' AND c2.name = 'No-Bake'; + +-- 3. All vegan and Japanese recipes +SELECT r.name AS recipe_name +FROM recipes r +JOIN recipe_categories rc1 ON r.id = rc1.recipe_id +JOIN categories c1 ON rc1.category_id = c1.id +JOIN recipe_categories rc2 ON r.id = rc2.recipe_id +JOIN categories c2 ON rc2.category_id = c2.id +WHERE c1.name = 'Vegan' AND c2.name = 'Japanese'; \ No newline at end of file diff --git a/Week3/assignment/3.1.md b/Week3/assignment/3.1.md new file mode 100644 index 000000000..ddf09f578 --- /dev/null +++ b/Week3/assignment/3.1.md @@ -0,0 +1,34 @@ +QUESTIONS: +1 - What columns violate 1NF? +2 - What entities do you recognize that could be extracted? +3 - Name all the tables and columns that would make a 3NF compliant solution. + +ANSWERS: +1 - colums "food_code" and "food_description" - have the same problem. They have differebt data separated by comas +2 - Members - Club members + Dinners - Dinners (events) + Venues - Venues + Foods - Foods + +Of cource for the real entities extraction we need more tables and info. HoweverHowever, for me personally, this is a tricky question, +because in my experience (outside of programming), we can manipulate data and play with definitions. So, theoretically. +I'd classify the member address in the task as a property rather than an entity (based solely on the column names). +However, this isn't explicitly stated, so I can assume that an address is also an entity, just in a different context. + +3 - table: Members + columns: Member_id, Member_name, Member_address + +tables: Venues +columns: Venue_code, Venue_description, + +tables: Foods +columns: Food_code, Food_description + +tables: Dinners +columns: Dinner_id, Dinner_date, venue_code + +tables: dinner_attendees +columns: Dinner_id, member_id + +tables: dinner_foods +columns: Dinner_id, food_code diff --git a/Week3/assignment/3.2/transaction-create-tables.js b/Week3/assignment/3.2/transaction-create-tables.js new file mode 100644 index 000000000..828422fcb --- /dev/null +++ b/Week3/assignment/3.2/transaction-create-tables.js @@ -0,0 +1,45 @@ +const { Client } = require('pg'); + +const createTables = async () => { + const client = new Client({ + host: 'localhost', + port: 5432, + database: 'hyfuser', + user: 'hyfuser', + password: 'hyfpassword' + }); + + try { + await client.connect(); + + // Создаем таблицу account --- create table account + await client.query(` + CREATE TABLE IF NOT EXISTS account ( + account_number INT PRIMARY KEY, + balance DECIMAL(10,2) NOT NULL DEFAULT 0.00, + CONSTRAINT balance_non_negative CHECK (balance >= 0) + ) + `); + + // Создаем таблицу account_changes --- create table account_changes + await client.query(` + CREATE TABLE IF NOT EXISTS account_changes ( + change_number SERIAL PRIMARY KEY, + account_number INT NOT NULL, + amount DECIMAL(10,2) NOT NULL, + changed_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + remark VARCHAR(255), + FOREIGN KEY (account_number) REFERENCES account(account_number) + ) + `); + + console.log('Tables created successfully!'); + + } catch (error) { + console.error('Error creating tables:', error); + } finally { + await client.end(); + } +}; + +createTables(); \ No newline at end of file diff --git a/Week3/assignment/3.2/transaction-insert-values.js b/Week3/assignment/3.2/transaction-insert-values.js new file mode 100644 index 000000000..fbbac4ed6 --- /dev/null +++ b/Week3/assignment/3.2/transaction-insert-values.js @@ -0,0 +1,39 @@ +const { Client } = require('pg'); + +// Вставляем тестовые данные в таблицы --- insert test data into tables (оставил пароль без учета безопасности --- left password without security considerations) +const insertValues = async () => { + const client = new Client({ + host: 'localhost', + port: 5432, + database: 'hyfuser', + user: 'hyfuser', + password: 'hyfpassword' + }); + + try { + await client.connect(); + + // Вставляем тестовые счета --- insert test accounts + await client.query(` + INSERT INTO account (account_number, balance) + VALUES + (101, 5000.00), + (102, 3000.00), + (103, 10000.00) + ON CONFLICT (account_number) DO NOTHING + `); + + console.log('Test data inserted successfully!'); + + // Показываем что получилось --- show the result + const result = await client.query('SELECT * FROM account'); + console.log('Current accounts:', result.rows); + + } catch (error) { + console.error('Error inserting data:', error); + } finally { + await client.end(); + } +}; + +insertValues(); \ No newline at end of file diff --git a/Week3/assignment/3.2/transaction.js b/Week3/assignment/3.2/transaction.js new file mode 100644 index 000000000..39145ca76 --- /dev/null +++ b/Week3/assignment/3.2/transaction.js @@ -0,0 +1,83 @@ +const { Client } = require('pg'); + +const transferMoney = async () => { + const client = new Client({ + host: 'localhost', + port: 5432, + database: 'hyfuser', + user: 'hyfuser', + password: 'hyfpassword' + }); + + try { + await client.connect(); + + // Начинаем транзакцию --- begin transaction + await client.query('BEGIN'); + + const fromAccount = 101; + const toAccount = 102; + const amount = 1000.00; + + // 1. Проверяем достаточно ли средств на счете 101 --- check if there are enough funds in account 101 + const checkBalance = await client.query( + 'SELECT balance FROM account WHERE account_number = $1', + [fromAccount] + ); + + if (checkBalance.rows.length === 0) { + throw new Error(`account ${fromAccount} not found`); + } + + if (checkBalance.rows[0].balance < amount) { + throw new Error(`Insufficient funds in account ${fromAccount}`); + } + + // 2. Снимаем деньги со счета 101 --- withdraw money from account 101 + await client.query( + 'UPDATE account SET balance = balance - $1 WHERE account_number = $2', + [amount, fromAccount] + ); + + // 3. Записываем операцию снятия в account_changes --- record withdrawal in account_changes + await client.query( + `INSERT INTO account_changes (account_number, amount, remark) + VALUES ($1, $2, $3)`, + [fromAccount, -amount, `Transfer to account ${toAccount}`] + ); + + // 4. Добавляем деньги на счет 102 --- add money to account 102 + await client.query( + 'UPDATE account SET balance = balance + $1 WHERE account_number = $2', + [amount, toAccount] + ); + + // 5. Записываем операцию пополнения в account_changes --- record deposit in account_changes + await client.query( + `INSERT INTO account_changes (account_number, amount, remark) + VALUES ($1, $2, $3)`, + [toAccount, amount, `Transfer from account ${fromAccount}`] + ); + + // Фиксируем транзакцию --- commit transaction + await client.query('COMMIT'); + + console.log(`✅ Transfer of ${amount} from account ${fromAccount} to account ${toAccount} completed successfully!`); + + // Показываем результат --- show the result + const result = await client.query( + 'SELECT * FROM account WHERE account_number IN ($1, $2)', + [fromAccount, toAccount] + ); + console.log('New balances:', result.rows); + + } catch (error) { + // Откатываем транзакцию при ошибке --- rollback transaction on error + await client.query('ROLLBACK'); + console.error('❌ Transaction error:', error.message); + } finally { + await client.end(); + } +}; + +transferMoney(); \ No newline at end of file diff --git a/Week3/assignment/3.3.js b/Week3/assignment/3.3.js new file mode 100644 index 000000000..9181633cf --- /dev/null +++ b/Week3/assignment/3.3.js @@ -0,0 +1,28 @@ +/*this code below will delete table? my pesonal opinion tis one is far mpre dangerous +const name = "'; DROP TABLE Country; --"; +const code = "anything";*/ + +/*this code below will return all records +const name = "' OR '1'='1"; +const code = "' OR '1'='1";*/ + +function getPopulation(Country, name, code, cb) { + // Валидация имени таблицы --- validate table name + const allowedTables = ['Country']; // Допустимые имена таблиц --- allowed table names + if (!allowedTables.includes(Country)) { + return cb(new Error('Invalid table name')); + } + + // Параметризованный запрос --- parameterized query to prevent SQL injection + conn.query( + 'SELECT Population FROM Country WHERE Name = $1 AND Code = $2', + [name, code], + function(err, result) { + if (err) return cb(err); + if (result.length == 0) return cb(new Error('Not found')); + + // 3. Возвращаем Population (according file ..databases/Week1/databases/world.sql) + cb(null, result[0].Population); + } + ); +} \ No newline at end of file diff --git a/Week3/assignment/3.4/package-lock.json b/Week3/assignment/3.4/package-lock.json new file mode 100644 index 000000000..e347e6b84 --- /dev/null +++ b/Week3/assignment/3.4/package-lock.json @@ -0,0 +1,179 @@ +{ + "name": "3.4", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "3.4", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "dotenv": "^17.2.3", + "mongodb": "^7.0.0" + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.2.tgz", + "integrity": "sha512-QgA5AySqB27cGTXBFmnpifAi7HxoGUeezwo6p9dI03MuDB6Pp33zgclqVb6oVK3j6I9Vesg0+oojW2XxB59SGg==", + "license": "MIT", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" + }, + "node_modules/@types/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, + "node_modules/bson": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-7.0.0.tgz", + "integrity": "sha512-Kwc6Wh4lQ5OmkqqKhYGKIuELXl+EPYSCObVE6bWsp1T/cGkOCBN0I8wF/T44BiuhHyNi1mmKVPXk60d41xZ7kw==", + "license": "Apache-2.0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" + }, + "node_modules/mongodb": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.0.0.tgz", + "integrity": "sha512-vG/A5cQrvGGvZm2mTnCSz1LUcbOPl83hfB6bxULKQ8oFZauyox/2xbZOoGNl+64m8VBrETkdGCDBdOsCr3F3jg==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.3.0", + "bson": "^7.0.0", + "mongodb-connection-string-url": "^7.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.806.0", + "@mongodb-js/zstd": "^7.0.0", + "gcp-metadata": "^7.0.1", + "kerberos": "^7.0.0", + "mongodb-client-encryption": ">=7.0.0 <7.1.0", + "snappy": "^7.3.2", + "socks": "^2.8.6" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-7.0.0.tgz", + "integrity": "sha512-irhhjRVLE20hbkRl4zpAYLnDMM+zIZnp0IDB9akAFFUZp/3XdOfwwddc7y6cNvF2WCEtfTYRwYbIfYa2kVY0og==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^13.0.0", + "whatwg-url": "^14.1.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + } + } +} diff --git a/Week3/assignment/3.4/package.json b/Week3/assignment/3.4/package.json new file mode 100644 index 000000000..6f921690f --- /dev/null +++ b/Week3/assignment/3.4/package.json @@ -0,0 +1,16 @@ +{ + "name": "3.4", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "dotenv": "^17.2.3", + "mongodb": "^7.0.0" + } +} diff --git a/Week3/package-lock.json b/Week3/package-lock.json new file mode 100644 index 000000000..7cddf9da6 --- /dev/null +++ b/Week3/package-lock.json @@ -0,0 +1,313 @@ +{ + "name": "week3", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "week3", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "mongodb": "^7.0.0", + "pg": "^8.16.3" + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.2.tgz", + "integrity": "sha512-QgA5AySqB27cGTXBFmnpifAi7HxoGUeezwo6p9dI03MuDB6Pp33zgclqVb6oVK3j6I9Vesg0+oojW2XxB59SGg==", + "license": "MIT", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" + }, + "node_modules/@types/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, + "node_modules/bson": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-7.0.0.tgz", + "integrity": "sha512-Kwc6Wh4lQ5OmkqqKhYGKIuELXl+EPYSCObVE6bWsp1T/cGkOCBN0I8wF/T44BiuhHyNi1mmKVPXk60d41xZ7kw==", + "license": "Apache-2.0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" + }, + "node_modules/mongodb": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.0.0.tgz", + "integrity": "sha512-vG/A5cQrvGGvZm2mTnCSz1LUcbOPl83hfB6bxULKQ8oFZauyox/2xbZOoGNl+64m8VBrETkdGCDBdOsCr3F3jg==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.3.0", + "bson": "^7.0.0", + "mongodb-connection-string-url": "^7.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.806.0", + "@mongodb-js/zstd": "^7.0.0", + "gcp-metadata": "^7.0.1", + "kerberos": "^7.0.0", + "mongodb-client-encryption": ">=7.0.0 <7.1.0", + "snappy": "^7.3.2", + "socks": "^2.8.6" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-7.0.0.tgz", + "integrity": "sha512-irhhjRVLE20hbkRl4zpAYLnDMM+zIZnp0IDB9akAFFUZp/3XdOfwwddc7y6cNvF2WCEtfTYRwYbIfYa2kVY0og==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^13.0.0", + "whatwg-url": "^14.1.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/pg": { + "version": "8.16.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", + "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.9.1", + "pg-pool": "^3.10.1", + "pg-protocol": "^1.10.3", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.2.7" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", + "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", + "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", + "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "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" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/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==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/Week3/package.json b/Week3/package.json new file mode 100644 index 000000000..c9c68cdb4 --- /dev/null +++ b/Week3/package.json @@ -0,0 +1,16 @@ +{ + "name": "week3", + "version": "1.0.0", + "description": "## Agenda", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "mongodb": "^7.0.0", + "pg": "^8.16.3" + } +}