Skip to content

Commit

Permalink
Add array repositories
Browse files Browse the repository at this point in the history
  • Loading branch information
juffalow committed Sep 14, 2024
1 parent 72bc5b6 commit 28be231
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 11 deletions.
8 changes: 8 additions & 0 deletions src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@ const database = knex({
});

export default database;

export async function checkConnection() {
return database.raw('SELECT 1 + 1 AS result');
}

export async function migrate() {
return database.migrate.latest({ directory: config.database.migrations.directory });
}
11 changes: 6 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import cors from './middlewares/cors';
import config from './config';
import context from './context';
import schema from './schema';
import database from './database';
import { checkConnection, migrate } from './database';

const app = express();

Expand All @@ -22,11 +22,12 @@ app.all('/graphql', createHandler({

async function start(): Promise<void> {
try {
// check database connection
await database.raw('SELECT 1 + 1 AS result');
if (typeof config.database.connection.host === 'string') {
await checkConnection();

if ('migrations' in config.database) {
await database.migrate.latest({ directory: config.database.migrations.directory });
if ('migrations' in config.database) {
await migrate();
}
}

app.listen(config.port, () => {
Expand Down
136 changes: 136 additions & 0 deletions src/repositories/AuthorArrayRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
const authorsList = [
{ id: 1, firstName: 'John', lastName: 'Johnson', createdAt: '2024-09-14 13:13:00' },
{ id: 2, firstName: 'Martin', lastName: 'Fowler', createdAt: '2024-09-14 13:13:01' },
{ id: 3, firstName: 'Jason', lastName: 'Lengstorf', createdAt: '2024-09-14 13:13:02' },
{ id: 4, firstName: 'Linus', lastName: 'Torvalds', createdAt: '2024-09-14 13:13:03' },
{ id: 5, firstName: 'Robert', lastName: 'Martin', createdAt: '2024-09-14 13:13:04' },
{ id: 6, firstName: 'Bill', lastName: 'Gates', createdAt: '2024-09-14 13:13:05' },
{ id: 7, firstName: 'Felipe', lastName: 'Fortes', createdAt: '2024-09-14 13:13:06' },
{ id: 8, firstName: 'Niels', lastName: 'Bohr', createdAt: '2024-09-14 13:13:07' },
{ id: 9, firstName: 'Jamie', lastName: 'Zawinski', createdAt: '2024-09-14 13:13:08' },
{ id: 10, firstName: 'Sercan', lastName: 'Leylek', createdAt: '2024-09-14 13:13:09' },
{ id: 11, firstName: 'Cory', lastName: 'House', createdAt: '2024-09-14 13:13:10' },
{ id: 12, firstName: 'Patrick', lastName: 'McKenzie', createdAt: '2024-09-14 13:13:11' },
{ id: 13, firstName: 'Joe', lastName: 'Sondow', createdAt: '2024-09-14 13:13:12' },
{ id: 14, firstName: 'Ron', lastName: 'Jeffries', createdAt: '2024-09-14 13:13:13' },
{ id: 15, firstName: 'Stephen', lastName: 'Hawking', createdAt: '2024-09-14 13:13:14' },
{ id: 16, firstName: 'Kathryn', lastName: 'Barrett', createdAt: '2024-09-14 13:13:15' },
{ id: 17, firstName: 'Anonymous', lastName: '', createdAt: '2024-09-14 13:13:16' },
{ id: 18, firstName: 'Rich', lastName: 'Hickey', createdAt: '2024-09-14 13:13:17' },
{ id: 19, firstName: 'Christopher', lastName: 'Thompson', createdAt: '2024-09-14 13:13:18' },
{ id: 20, firstName: 'Fred', lastName: 'Brooks', createdAt: '2024-09-14 13:13:19' },
{ id: 21, firstName: 'Kent', lastName: 'Beck', createdAt: '2024-09-14 13:13:20' },
{ id: 22, firstName: 'Bram', lastName: 'Cohen', createdAt: '2024-09-14 13:13:21' },
{ id: 23, firstName: 'Nicoll', lastName: 'Hunt', createdAt: '2024-09-14 13:13:22' },
{ id: 24, firstName: 'Oscar', lastName: 'Godson', createdAt: '2024-09-14 13:13:23' },
{ id: 25, firstName: 'The Boy Scout Rule', lastName: '', createdAt: '2024-09-14 13:13:24' },
{ id: 26, firstName: 'Chris', lastName: 'Pine', createdAt: '2024-09-14 13:13:25' },
{ id: 27, firstName: 'Damian', lastName: 'Conway', createdAt: '2024-09-14 13:13:26' },
{ id: 28, firstName: 'Alan', lastName: 'Turing', createdAt: '2024-09-14 13:13:27' },
{ id: 29, firstName: 'Richard', lastName: 'Pattis', createdAt: '2024-09-14 13:13:28' },
{ id: 30, firstName: 'Jeff', lastName: 'Atwood', createdAt: '2024-09-14 13:13:29' },
{ id: 31, firstName: 'Mikko', lastName: 'Hypponen', createdAt: '2024-09-14 13:13:30' },
{ id: 32, firstName: 'Ryan', lastName: 'Singer', createdAt: '2024-09-14 13:13:31' },
]

export default class AuthorKnexRepository implements AuthorRepository {
public async get(id: number): Promise<Author> {
const author = authorsList.find((author) => author.id === id);

return author;
}

public async getMany(ids: number[]): Promise<Author[]> {
const authors = authorsList.filter((author) => ids.includes(author.id));

return authors;
}

public async find(params: AuthorRepository.FindParameters): Promise<Author[]> {
const { first, after, firstName, lastName, orderBy } = params;

const authors = authorsList.filter((author) => {
if (typeof firstName !== 'undefined' && author.firstName.startsWith(firstName) === false) {
return false;
}

if (typeof lastName !== 'undefined' && author.lastName.startsWith(lastName) === false) {
return false;
}

return true;
});

if (Array.isArray(orderBy) && orderBy.length > 0) {
authors.sort((a, b) => {
return orderBy.map((ob) => {
if (a[ob.field] < b[ob.field]) {
return ob.direction === 'asc' ? -1 : 1;
} else if (a[ob.field] > b[ob.field]) {
return ob.direction === 'asc' ? 1 : -1;
}
}).reduce((p, n) => p || n, 0);
});
}

return authors.splice(after, first);
}

public async count(params: AuthorRepository.CountParameters): Promise<number> {
const { firstName, lastName } = params;

const count = authorsList.filter((author) => {
if (typeof firstName !== 'undefined' && author.firstName.startsWith(firstName) === false) {
return false;
}

if (typeof lastName !== 'undefined' && author.lastName.startsWith(lastName) === false) {
return false;
}

return true;
}).length;

return count;
}

public async create(params: AuthorRepository.CreateParameters): Promise<Author> {
const author = {
id: authorsList.length + 1,
firstName: params.firstName,
lastName: params.lastName,
createdAt: new Date().toISOString(),
};

authorsList.push(author);

return author;
}

public async update(id: number, firstName: string, lastName: string): Promise<Author> {
const author = authorsList.find((author) => author.id === id);

const authorIndex = authorsList.findIndex((author) => author.id === id);

if (authorIndex === -1) {
throw new Error('Author not found!');
}

authorsList[authorIndex] = {
...author,
firstName,
lastName,
};

return authorsList[authorIndex];
}

public async delete(id: number): Promise<Author> {
const author = authorsList.find((author) => author.id === id);
const authorIndex = authorsList.findIndex((author) => author.id === id);

authorsList.splice(authorIndex, 1);

return author;
}
}
87 changes: 87 additions & 0 deletions src/repositories/QuoteArrayRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const quotesList = [
{ id: 1, authorId: 1, text: 'First, solve the problem. Then, write the code.', createdAt: '2024-09-14 13:59:00' },
{ id: 2, authorId: 2, text: 'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.', createdAt: '2024-09-14 13:59:01' },
{ id: 3, authorId: 3, text: 'If you stop learning, then the projects you work on are stuck in whatever time period you decided to settle.', createdAt: '2024-09-14 13:59:02' },
{ id: 4, authorId: 4, text: 'Bad programmers worry about the code. Good programmers worry about the data structures and their relationships.', createdAt: '2024-09-14 13:59:03' },
{ id: 5, authorId: 4, text: 'Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.', createdAt: '2024-09-14 13:59:04' },
{ id: 6, authorId: 4, text: 'When you say \'I wrote a program that crashed Windows,\' people just stare at you blankly and say \'Hey, I got those with the system, for free.\'', createdAt: '2024-09-14 13:59:05' },
{ id: 7, authorId: 4, text: 'A computer is like air conditioning - it becomes useless when you open Windows.', createdAt: '2024-09-14 13:59:06' },
{ id: 8, authorId: 4, text: 'If you think your users are idiots, only idiots will use it.', createdAt: '2024-09-14 13:59:07' },
{ id: 9, authorId: 5, text: 'You should name a variable using the same care with which you name a first-born child.', createdAt: '2024-09-14 13:59:08' },
{ id: 10, authorId: 6, text: 'If you are born poor, it is not your mistake, but if you die poor it is your mistake.', createdAt: '2024-09-14 13:59:09' },
{ id: 11, authorId: 6, text: 'No one will need more than 637Kb of memory for a personal computer.', createdAt: '2024-09-14 13:59:10' },
{ id: 12, authorId: 7, text: 'Debugging is like being the detective in a crime movie where you are also the murderer.', createdAt: '2024-09-14 13:59:11' },
{ id: 13, authorId: 8, text: 'An expert is a person who has made all the mistakes that can be made in a very narrow field.', createdAt: '2024-09-14 13:59:12' },
{ id: 14, authorId: 9, text: 'Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.', createdAt: '2024-09-14 13:59:13' },
{ id: 15, authorId: 10, text: 'Every programmer is an author.', createdAt: '2024-09-14 13:59:14' },
{ id: 16, authorId: 11, text: 'Code is like humor. When you have to explain it, it\'s bad.', createdAt: '2024-09-14 13:59:15' },
{ id: 17, authorId: 12, text: 'Every great developer you know got there by solving problems they were unqualified to solve until they actually did it.', createdAt: '2024-09-14 13:59:16' },
{ id: 18, authorId: 13, text: 'A computer is like a mischievous genie. It will give you exactly what you asked for, but not always what you want.', createdAt: '2024-09-14 13:59:17' },
{ id: 19, authorId: 14, text: 'Code never lies; comments sometimes do.', createdAt: '2024-09-14 13:59:18' },
{ id: 20, authorId: 15, text: 'Whether you want to uncover the secrets of the universe, or you just want to pursue a career in the 21st century, basic computer programming is an essential skill to learn.', createdAt: '2024-09-14 13:59:19' },
{ id: 21, authorId: 16, text: 'Falling in love with code means falling in love with problem solving and being a part of a forever ongoing conversation.', createdAt: '2024-09-14 13:59:20' },
{ id: 22, authorId: 17, text: 'There\'s no test like production!', createdAt: '2024-09-14 13:59:21' },
{ id: 23, authorId: 18, text: 'Programming is not about typing, it\'s about thinking.', createdAt: '2024-09-14 13:59:22' },
{ id: 25, authorId: 19, text: 'Sometimes it pays to stay in bed on Monday, rather than spending the rest of the week debugging Monday\'s code.', createdAt: '2024-09-14 13:59:23' },
{ id: 26, authorId: 20, text: 'What one programmer can do in one month, two programmers can do in two months.', createdAt: '2024-09-14 13:59:24' },
{ id: 27, authorId: 5, text: 'It is not the language that makes programs appear simple. It is the programmer that make the language appear simple!', createdAt: '2024-09-14 13:59:25' },
{ id: 28, authorId: 21, text: 'A plan is an example of what could happen, not a prediction of what will happen.', createdAt: '2024-09-14 13:59:26' },
{ id: 29, authorId: 22, text: 'The trick is to fix the problem you have, rather than the problem you want.', createdAt: '2024-09-14 13:59:27' },
{ id: 30, authorId: 27, text: 'It works on my machine.', createdAt: '2024-09-14 13:59:28' },
{ id: 31, authorId: 23, text: 'The first step of any project is to grossly underestimate its complexity and difficulty.', createdAt: '2024-09-14 13:59:29' },
{ id: 32, authorId: 24, text: 'One of the best programming skills you can have is knowing when to walk away for awhile.', createdAt: '2024-09-14 13:59:30' },
{ id: 33, authorId: 17, text: 'Weeks of coding can save you hours of planning.', createdAt: '2024-09-14 13:59:31' },
{ id: 34, authorId: 25, text: 'Always leave the campground cleaner than you found it.', createdAt: '2024-09-14 13:59:32' },
{ id: 35, authorId: 26, text: 'Programming isn\'t about what you know; it\'s about what you can figure out.', createdAt: '2024-09-14 13:59:33' },
{ id: 36, authorId: 27, text: 'Documentation is a love letter that you write to your future self.', createdAt: '2024-09-14 13:59:34' },
{ id: 37, authorId: 28, text: 'Sometimes it is the people no one can imagine anything of who do the things no one can imagine.', createdAt: '2024-09-14 13:59:35' },
{ id: 38, authorId: 29, text: 'When debugging, novices insert corrective code; experts remove defective code.', createdAt: '2024-09-14 13:59:36' },
{ id: 39, authorId: 30, text: 'Hell isn\'t other people\'s code. Hell is your own code from 3 years ago.', createdAt: '2024-09-14 13:59:37' },
{ id: 40, authorId: 31, text: 'Rarely is anyone thanked for the work they did to prevent the disaster that didn\'t happen.', createdAt: '2024-09-14 13:59:38' },
{ id: 44, authorId: 32, text: 'So much complexity in software comes from trying to make one thing do two things.', createdAt: '2024-09-14 13:59:39' },
];

export default class QuoteKnexRepository implements QuoteRepository {

public async get(id: number): Promise<Quote> {
const quote = quotesList.find((q) => q.id === id);

return quote;
}

public async find(params: QuoteRepository.FindParameters): Promise<Quote[]> {
const { first, after, authorId, query } = params;

const quotes = quotesList.filter((quote) => {
if (typeof authorId !== 'undefined' && quote.authorId !== authorId) {
return false;
}

if (typeof query !== 'undefined' && quote.text.indexOf(query) === -1) {
return false;
}

return true;
});

return quotes.splice(after, first);
}

public async count(params: QuoteRepository.CountParameters): Promise<number> {
const { authorId, query } = params;

const count = quotesList.filter((quote) => {
if (typeof authorId !== 'undefined' && quote.authorId === authorId) {
return false;
}

if (typeof query !== 'undefined' && quote.text.indexOf(query) === -1) {
return false;
}

return true;
}).length;

return count;
}
}
19 changes: 15 additions & 4 deletions src/repositories/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import Author from './AuthorKnexRepository';
import Quote from './QuoteKnexRepository';
import AuthorKnexRepository from './AuthorKnexRepository';
import AuthorArrayRepository from './AuthorArrayRepository';
import QuoteKnexRepository from './QuoteKnexRepository';
import QuoteArrayRepository from './QuoteArrayRepository';
import config from '../config';

const container = {
get Author(): AuthorRepository {
if (typeof this._author === 'undefined') {
this._author = new Author();
if (typeof config.database.connection.host === 'string') {
this._author = new AuthorKnexRepository();
} else {
this._author = new AuthorArrayRepository();
}
}

return this._author;
},

get Quote(): QuoteRepository {
if (typeof this._quote === 'undefined') {
this._quote = new Quote();
if (typeof config.database.connection.host === 'string') {
this._quote = new QuoteKnexRepository();
} else {
this._quote = new QuoteArrayRepository();
}
}

return this._quote;
Expand Down
2 changes: 1 addition & 1 deletion src/schema/queries/author.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const author = {
},
},
resolve: (_, { id }, context: Context): Promise<any> => {
return context.repositories.author.get(id);
return context.repositories.author.get(parseInt(id));
},
};

Expand Down
2 changes: 1 addition & 1 deletion src/schema/queries/quote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const quote = {
},
},
resolve: (_, { id }, context: Context) => {
return context.repositories.quote.get(id);
return context.repositories.quote.get(parseInt(id));
},
};

Expand Down

0 comments on commit 28be231

Please sign in to comment.