-
Notifications
You must be signed in to change notification settings - Fork 18
Mareh A. #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Mareh A. #19
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,27 +1,50 @@ | ||
| ---- Queries | ||
|
|
||
| -- **Question 1** — List the title and published year of every book in the `'Science Fiction'` genre, ordered by published year (oldest first). | ||
| SELECT title , published_year FROM books | ||
| WHERE books.genre = 'Science Fiction'; | ||
|
|
||
| -- **Question 2** — Show every book published before 1950. Display the title and year only. | ||
| SELECT title , published_year FROM books | ||
| WHERE books.published_year < 1950; | ||
|
|
||
| -- **Question 3** — Show every book in the database along with its author's full name. Combine `first_name` and `last_name` into a single column called `author`. _(Hint: you will need a JOIN.)_ | ||
|
|
||
| SELECT title , published_year , authors.first_name || ' ' || authors.last_name AS author FROM books | ||
| JOIN authors ON author_id = books.author_id; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When I run this query, these are the results that are I receive below with duplicate results. The problem is in the JOIN and the id used for checking. How would you fix it? Harry Potter and the Philosopher's Stone 1997 J.K. Rowling |
||
| -- **Question 4** — List all books written by Stephen King. Show the title and published year, ordered by year. _(Hint: JOIN the two tables and filter on the author's name.)_ | ||
|
|
||
| SELECT title , published_year FROM books | ||
| JOIN authors ON author_id = books.author_id | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This query doesn't return results. The problem is with the choose of the id to compare |
||
| WHERE authors.first_name = 'Stephen' AND authors.last_name= 'King' | ||
| ORDER BY published_year; | ||
| -- **Question 5** — Add yourself as a new author. Use your real name, or make one up. Pick any nationality and birth year. | ||
|
|
||
| INSERT INTO authors(first_name,last_name,nationality,birth_year) | ||
| VALUES ("Mareh","Aboghanem","Yemeni",2000); | ||
| -- **Question 6** — Add one book for the author you just inserted. It can be a real book or a made-up one. | ||
|
|
||
| INSERT INTO books(title,published_year,genre,author_id) | ||
| VALUES("HI",2026,"Horror",25); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good! A challenge: there is a way of doing a |
||
| -- **Question 7** — The genre for "The Dark Tower: The Gunslinger" was entered incorrectly as `'Fantasy'`. It should be `'Horror'`. Write an UPDATE to fix it, then verify the change with a SELECT. | ||
| UPDATE books | ||
| SET genre = 'Horror' | ||
| WHERE title = "The Dark Tower: The Gunslinger"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good one here! Adding exactly the title for |
||
|
|
||
| SELECT title,published_year,genre FROM books | ||
| WHERE title = "The Dark Tower: The Gunslinger"; | ||
| -- **Question 8** — Delete the book you added in Question 6. Make sure your query targets only that specific row. | ||
|
|
||
| DELETE FROM books | ||
| WHERE title = "The Dark Tower: The Gunslinger"; | ||
| --- | ||
|
|
||
| -- ### Bonus questions _(optional)_ | ||
|
|
||
| -- These cover topics slightly beyond the core material. Have a go if you finish early. | ||
|
|
||
| -- **Bonus A** — How many books are there per genre? Show the genre name and the count, ordered from most to fewest books. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well done doing the bonus! |
||
| SELECT genre , COUNT() | ||
| FROM books | ||
| GROUP BY genre | ||
| ORDER BY COUNT() ASC; | ||
|
|
||
| -- **Bonus B** — Find any authors in the database who have no books at all. _(Hint: you will need a LEFT JOIN and check for NULL.) | ||
| SELECT first_name , last_name FROM authors | ||
| LEFT JOIN books ON authors.id = books.author_id | ||
| WHERE title IS NULL; | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import Database from "better-sqlite3"; | ||
| import fs from "fs"; | ||
| import { join } from "path"; | ||
|
|
||
|
|
||
| const filePath = join('data', 'data.json'); | ||
| const jsonText = fs.readFileSync(filePath, 'utf-8'); | ||
| const data = JSON.parse(jsonText); | ||
|
|
||
| const dbPath = join("data", "flashcards.db"); | ||
| const db = new Database(dbPath); | ||
| //const db = new Database('flashcards.db'); | ||
| const stmt = db.prepare("INSERT INTO decks (name, description) VALUES (? , ?)"); | ||
| data.decks.forEach((deck) => { | ||
| stmt.run(deck.name, deck.description); | ||
| }); | ||
| const allDecks = db.prepare("SELECT * FROM decks").all(); | ||
| console.log(allDecks); | ||
| const stmt_card = db.prepare( | ||
| "INSERT INTO cards(question,answer,learned,deck_id) VALUES(?,?,?,?)", | ||
| ); | ||
| data.cards.forEach((card) => { | ||
| stmt_card.run(card.question, card.answer, card.learned ? 1 : 0, card.deckId); | ||
| }); | ||
| const allCards = db.prepare("SELECT * FROM cards").all(); | ||
| console.log(allCards); | ||
|
|
||
| db.close(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| DROP TABLE IF EXISTS cards; | ||
| DROP TABLE IF EXISTS decks; | ||
|
|
||
| CREATE TABLE decks( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| name TEXT NOT NULL, | ||
| description TEXT | ||
|
|
||
| ); | ||
| CREATE TABLE cards( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| question TEXT NOT NULL, | ||
| answer TEXT NOT NULL, | ||
| learned INTEGER NOT NULL DEFAULT 0, | ||
| deck_id INTEGER NOT NULL, | ||
| FOREIGN KEY(deck_id) REFERENCES decks(id) | ||
| ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,13 +5,12 @@ | |
| // | ||
| // When every function works correctly, `node app.js` should | ||
| // print exactly the same output as it did with storage.js. | ||
|
|
||
| import Database from 'better-sqlite3'; | ||
| import { fileURLToPath } from 'url'; | ||
| import { dirname, join } from 'path'; | ||
| import Database from "better-sqlite3"; | ||
| import { fileURLToPath } from "url"; | ||
| import { dirname, join } from "path"; | ||
|
|
||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
| const DB_FILE = join(__dirname, '../data/flashcards.db'); | ||
| const DB_FILE = join(__dirname, "../data/flashcards.db"); | ||
|
|
||
| const db = new Database(DB_FILE); | ||
|
|
||
|
|
@@ -20,48 +19,82 @@ const db = new Database(DB_FILE); | |
| // ---------------------------------------------------------------- | ||
|
|
||
| export function getAllDecks() { | ||
| // TODO: return all rows from the decks table | ||
| throw new Error('Not implemented'); | ||
| const stmt = db.prepare("SELECT * FROM decks"); | ||
| const rows = stmt.all(); | ||
| return rows; | ||
| //throw new Error('Not implemented'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you have the same comment many times, maybe better to remove them all? ;) |
||
| } | ||
|
|
||
| export function getDeckById(id) { | ||
| // TODO: return the deck row with the given id, or null if not found | ||
| throw new Error('Not implemented'); | ||
| const stmt = db.prepare("SELECT * FROM decks WHERE id = ? "); | ||
| const getDeck = stmt.get(id); | ||
| return getDeck ?? null; | ||
| //throw new Error('Not implemented'); | ||
| } | ||
|
|
||
| export function addDeck(name, description) { | ||
| // TODO: insert a new deck and return the new row (including its id) | ||
| throw new Error('Not implemented'); | ||
| const stmt = db.prepare( | ||
| "INSERT INTO decks (name, description) VALUES (?, ?)", | ||
| ); | ||
| const add_deck = stmt.run(name, description); | ||
| return { | ||
| id: add_deck.lastInsertRowid, | ||
| name, | ||
| description, | ||
| }; | ||
| //throw new Error('Not implemented'); | ||
| } | ||
|
|
||
| export function deleteDeck(deckId) { | ||
| // TODO: delete the deck with the given id | ||
| // return true if a row was deleted, false otherwise | ||
| throw new Error('Not implemented'); | ||
| const stmt = db.prepare("DELETE FROM decks WHERE id = ?"); | ||
| const deleteDeck = stmt.run(deckId); | ||
| return deleteDeck.changes > 0; | ||
| //throw new Error('Not implemented'); | ||
| } | ||
|
|
||
| // ---------------------------------------------------------------- | ||
| // Cards | ||
| // ---------------------------------------------------------------- | ||
|
|
||
| export function getAllCardsForDeck(deckId) { | ||
| // TODO: return all card rows whose deckId matches | ||
| throw new Error('Not implemented'); | ||
| const stmt = db.prepare( | ||
| "SELECT id, question, answer, learned, deck_id AS deckId FROM cards WHERE deck_id = ?", | ||
| ); | ||
| const getAll = stmt.all(deckId); | ||
| return getAll; | ||
| //throw new Error('Not implemented'); | ||
| } | ||
|
|
||
| export function addCard(question, answer, deckId) { | ||
| // TODO: insert a new card and return the new row (including its id) | ||
| throw new Error('Not implemented'); | ||
| const stmt = db.prepare( | ||
| "INSERT INTO cards (question, answer ,deck_id) VALUES (?, ?,?)", | ||
| ); | ||
| const added_card = stmt.run(question, answer, deckId); | ||
| return { | ||
| id: added_card.lastInsertRowid, | ||
| question, | ||
| answer, | ||
| learned: 0, | ||
| deckId, | ||
| }; | ||
| //throw new Error('Not implemented'); | ||
| } | ||
|
|
||
| export function markCardLearned(cardId) { | ||
| // TODO: set learned = 1 for the card with the given id | ||
| // return the updated row, or null if not found | ||
| throw new Error('Not implemented'); | ||
| const stmt = db | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The const |
||
| .prepare("UPDATE cards SET learned = 1 WHERE id = ?") | ||
| .run(cardId); | ||
| const updatedCard = db | ||
| .prepare( | ||
| "SELECT id, question, answer, learned, deck_id AS deckId FROM cards WHERE id = ?", | ||
| ) | ||
| .get(cardId); | ||
| return updatedCard ?? null; | ||
| } | ||
|
|
||
| export function deleteCard(cardId) { | ||
| // TODO: delete the card with the given id | ||
| // return true if a row was deleted, false otherwise | ||
| throw new Error('Not implemented'); | ||
| const stmt = db.prepare("DELETE FROM cards WHERE id = ?"); | ||
| const deleteCard = stmt.run(cardId); | ||
| return deleteCard.changes > 0; | ||
| //throw new Error('Not implemented'); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is query is not ordering by published year with oldest first. How would you change it?