Skip to content

Commit 2f45e06

Browse files
committed
add base files
1 parent c807390 commit 2f45e06

8 files changed

+7439
-0
lines changed

Diff for: .eslintrc

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"plugins": ["node", "prettier"],
3+
"parserOptions": {
4+
"ecmaVersion": 2018
5+
},
6+
"env": {
7+
"jest": true,
8+
"node": true
9+
},
10+
"extends": ["eslint:recommended", "plugin:node/recommended", "plugin:prettier/recommended"],
11+
"rules": {
12+
"node/exports-style": ["error", "module.exports"],
13+
"prettier/prettier": "error"
14+
}
15+
}

Diff for: .npmignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.test.js

Diff for: README.md

+60
Original file line numberDiff line numberDiff line change
@@ -1 +1,61 @@
11
# SQLDataSource
2+
3+
This package combines the power of Knex with the ease of use of Apollo DataSources.
4+
5+
## Getting Started
6+
7+
### Installation
8+
9+
`npm i datasource-sql`
10+
11+
### Usage
12+
13+
```js
14+
const Knex = require("knex");
15+
const { SQLDataSource } = require("datasource-sql");
16+
17+
const MINUTE = 60 * 1000;
18+
19+
const knex = Knex({
20+
client: "pg",
21+
connection: {
22+
/* CONNECTION INFO */
23+
}
24+
});
25+
26+
class MyDatabase extends SQLDataSource {
27+
constructor() {
28+
super();
29+
// Add your instance of Knex to the DataSource
30+
this.knex = knex;
31+
}
32+
33+
getUsers() {
34+
// This can be any valid Knex query
35+
const query = this.db.select().from("users");
36+
37+
// Batch the query and cache the result for 1 minute
38+
return this.getBatchedAndCached(query, MINUTE);
39+
}
40+
}
41+
```
42+
43+
And use it in your Apollo server configuration:
44+
45+
```js
46+
const server = new ApolloServer({
47+
typeDefs,
48+
resolvers,
49+
cache,
50+
context,
51+
dataSources: () => ({
52+
db: new MyDatabase()
53+
})
54+
});
55+
```
56+
57+
## Contributing
58+
59+
All contributions are welcome!
60+
61+
Please open an issue or pull request.

Diff for: SQLCache.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
const { InMemoryLRUCache } = require("apollo-server-caching");
2+
const DataLoader = require("dataloader");
3+
4+
class SQLCache {
5+
constructor(cache = new InMemoryLRUCache(), knex) {
6+
this.cache = cache;
7+
this.loader = new DataLoader(rawQueries =>
8+
Promise.all(rawQueries.map(rawQuery => knex.raw(rawQuery)))
9+
);
10+
}
11+
12+
getBatched(query) {
13+
const queryString = query.toString();
14+
return this.loader.load(queryString).then(result => result && result.rows);
15+
}
16+
17+
getCached(query, ttl) {
18+
const queryString = query.toString();
19+
const cacheKey = `sqlcache:${queryString}`;
20+
21+
return this.cache.get(cacheKey).then(entry => {
22+
if (entry) return Promise.resolve(entry);
23+
return query.then(rows => {
24+
if (rows) this.cache.set(cacheKey, rows, ttl);
25+
return Promise.resolve(rows);
26+
});
27+
});
28+
}
29+
30+
getBatchedAndCached(query, ttl) {
31+
const queryString = query.toString();
32+
const cacheKey = `sqlcache:${queryString}`;
33+
34+
return this.cache.get(cacheKey).then(entry => {
35+
if (entry) return Promise.resolve(entry);
36+
return this.loader
37+
.load(queryString)
38+
.then(result => result && result.rows)
39+
.then(rows => {
40+
if (rows) this.cache.set(cacheKey, rows, ttl);
41+
return Promise.resolve(rows);
42+
});
43+
});
44+
}
45+
}
46+
47+
module.exports = SQLCache;

Diff for: SQLDataSource.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const SQLCache = require("./SQLCache");
2+
const knexTinyLogger = require("knex-tiny-logger").default;
3+
4+
const { DEBUG } = process.env;
5+
6+
class SQLDataSource {
7+
initialize(config) {
8+
if (DEBUG) knexTinyLogger(this.knex); // Add a logging utility for debugging
9+
this.context = config.context;
10+
this.db = this.knex;
11+
this.sqlCache = new SQLCache(config.cache, this.knex);
12+
this.getBatched = query => this.sqlCache.getBatched(query);
13+
this.getCached = (query, ttl) => this.sqlCache.getCached(query, ttl);
14+
this.getBatchedAndCached = (query, ttl) =>
15+
this.sqlCache.getBatchedAndCached(query, ttl);
16+
}
17+
}
18+
19+
module.exports = SQLDataSource;

Diff for: index.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const SQLCache = require("./SQLCache");
2+
const SQLDataSource = require("./SQLDataSource");
3+
4+
module.exports = { SQLCache, SQLDataSource };

0 commit comments

Comments
 (0)