Skip to content

Commit d20460f

Browse files
committed
DataProvider: Create a common BaseDataProvider class
1 parent ee50306 commit d20460f

File tree

2 files changed

+67
-50
lines changed

2 files changed

+67
-50
lines changed

lib/data_provider.js

Lines changed: 61 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,25 @@ const fs = require('fs');
2020
const ResourceCache = require('./resource_cache').ResourceCache;
2121

2222
/**
23-
* DataProvider that fetches data from the file system
23+
* Abstract base class for DataProvider classes
2424
*/
25-
class FsDataProvider {
26-
/**
27-
* @param {string} dataRootPath - a path to a directory containing data files
28-
*/
29-
constructor(dataRootPath) {
30-
this.data_path = dataRootPath;
31-
this.cache = new ResourceCache(dataName => new Promise((resolve, reject) => {
32-
fs.readFile(`${dataRootPath}/${dataName}.data`, (err, data) => {
33-
if (err) return reject(err);
34-
return resolve(data.toString('utf8'));
35-
});
36-
}));
25+
class BaseDataProvider {
26+
constructor() {
27+
if (new.target === BaseDataProvider) {
28+
throw new TypeError('Cannot instantiate Abstract BaseDataProvider');
29+
}
30+
31+
const abstractMethods = [
32+
'_loadData',
33+
'list'
34+
];
35+
abstractMethods.forEach((method) => {
36+
if (this[method] === undefined) {
37+
throw new TypeError(`Expected ${method} to be defined`);
38+
}
39+
});
40+
41+
this.cache = new ResourceCache(dataName => this._loadData(dataName));
3742
}
3843

3944
/**
@@ -45,6 +50,29 @@ class FsDataProvider {
4550
fetch(key) {
4651
return this.cache.fetch(key);
4752
}
53+
}
54+
55+
/**
56+
* DataProvider that fetches data from the file system
57+
*/
58+
class FsDataProvider extends BaseDataProvider {
59+
/**
60+
* @param {string} dataRootPath - a path to a directory containing data files
61+
*/
62+
constructor(dataRootPath) {
63+
super();
64+
65+
this.data_path = dataRootPath;
66+
}
67+
68+
_loadData(dataName) {
69+
return new Promise((resolve, reject) => {
70+
fs.readFile(`${this.data_path}/${dataName}.data`, (err, data) => {
71+
if (err) return reject(err);
72+
return resolve(data.toString('utf8'));
73+
});
74+
});
75+
}
4876

4977
/**
5078
* List all data files known to the provider
@@ -67,41 +95,34 @@ class FsDataProvider {
6795
/**
6896
* DataProvider that fetches data from an atg-storage DataStore
6997
*/
70-
class DataStoreDataProvider {
98+
class DataStoreDataProvider extends BaseDataProvider {
7199
/**
72100
* @param {object} datastore - an atg-storage DataStore
73101
* @param {string} tsName - the key to use to access the data file contents in the provided DataStore
74102
*/
75103
constructor(datastore, tsName) {
104+
super();
105+
76106
this.storage = datastore;
77107
this.tsName = tsName;
78-
this.cache = new ResourceCache(
79-
dataName => this.storage.hasItem(this.tsName)
80-
.then((result) => {
81-
if (result) {
82-
return Promise.resolve();
83-
}
84-
return Promise.reject(new Error(`Could not find template set "${this.tsName}" in data store`));
85-
})
86-
.then(() => this.storage.getItem(this.tsName))
87-
.then(ts => ts.dataFiles[dataName])
88-
.then((data) => {
89-
if (typeof data === 'undefined') {
90-
return Promise.reject(new Error(`Failed to find data file named "${dataName}"`));
91-
}
92-
return Promise.resolve(data);
93-
})
94-
);
95108
}
96109

97-
/**
98-
* Get the data file contents associated with the supplied key
99-
*
100-
* @param {string} key
101-
* @returns {object}
102-
*/
103-
fetch(key) {
104-
return this.cache.fetch(key);
110+
_loadData(dataName) {
111+
return this.storage.hasItem(this.tsName)
112+
.then((result) => {
113+
if (result) {
114+
return Promise.resolve();
115+
}
116+
return Promise.reject(new Error(`Could not find template set "${this.tsName}" in data store`));
117+
})
118+
.then(() => this.storage.getItem(this.tsName))
119+
.then(ts => ts.dataFiles[dataName])
120+
.then((data) => {
121+
if (typeof data === 'undefined') {
122+
return Promise.reject(new Error(`Failed to find data file named "${dataName}"`));
123+
}
124+
return Promise.resolve(data);
125+
});
105126
}
106127

107128
/**
@@ -123,6 +144,7 @@ class DataStoreDataProvider {
123144
}
124145

125146
module.exports = {
147+
BaseDataProvider,
126148
FsDataProvider,
127149
DataStoreDataProvider
128150
};

lib/github_provider.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const axios = require('axios');
2222
const ResourceCache = require('./resource_cache').ResourceCache;
2323
const Template = require('./template').Template;
2424
const { BaseTemplateProvider } = require('./template_provider');
25+
const { BaseDataProvider } = require('./data_provider');
2526
const { stripExtension } = require('./utils');
2627

2728
class GitHubContentsApi {
@@ -115,29 +116,23 @@ class GitHubSchemaProvider {
115116
/**
116117
* DataProvider that fetches data from a GitHub repository
117118
*/
118-
class GitHubDataProvider {
119+
class GitHubDataProvider extends BaseDataProvider {
119120
/**
120121
* @param {string} dataRootPath - a path to a directory containing data files
121122
*/
122123
constructor(repo, dataRootPath, options) {
124+
super();
123125
options = options || {};
124126

125127
this._rootDir = `/${dataRootPath}`;
126128
this._contentsApi = new GitHubContentsApi(repo, {
127129
apiToken: options.apiToken
128130
});
129-
this.cache = new ResourceCache(dataName => Promise.resolve()
130-
.then(() => this._contentsApi.getContentsData(`${this._rootDir}/${dataName}.data`)));
131131
}
132132

133-
/**
134-
* Get the data file contents associated with the supplied key
135-
*
136-
* @param {string} key
137-
* @returns {object}
138-
*/
139-
fetch(key) {
140-
return this.cache.fetch(key);
133+
_loadData(dataName) {
134+
return Promise.resolve()
135+
.then(() => this._contentsApi.getContentsData(`${this._rootDir}/${dataName}.data`));
141136
}
142137

143138
/**

0 commit comments

Comments
 (0)