Skip to content

Commit

Permalink
Schema can be forced when instanciating
Browse files Browse the repository at this point in the history
  • Loading branch information
Léo Frachet committed Mar 9, 2018
1 parent a8a0f58 commit 9407ece
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 40 deletions.
39 changes: 29 additions & 10 deletions gtfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const forEachWithLog = require('./helpers/logging_iterator_wrapper');
const { exportGtfs } = require('./helpers/export');
const getters = require('./helpers/getters');
const { importTable } = require('./helpers/import');
const schema = require('./helpers/schema');
const defaultSchema = require('./helpers/schema');

/**
* Table-generic function to add items in a table of a GTFS.
Expand All @@ -24,7 +24,7 @@ function addItems(gtfs, tableName, items) {
}

const indexedTable = gtfs.getIndexedTable(tableName);
const indexKeys = schema.indexKeysByTableName[tableName];
const indexKeys = gtfs._schema.indexKeysByTableName[tableName];

if (indexKeys.indexKey) {
items.forEach(item => indexedTable.set(item[indexKeys.indexKey], item));
Expand Down Expand Up @@ -76,7 +76,7 @@ function forEachItem(gtfs, tableName, iterator) {
}

const indexedTable = gtfs.getIndexedTable(tableName);
const deepness = schema.deepnessByTableName[tableName];
const deepness = gtfs._schema.deepnessByTableName[tableName];

if (deepness === 1) {
forEachWithLog(`Iterating:${tableName}`, indexedTable, (item) => {
Expand Down Expand Up @@ -105,7 +105,7 @@ function removeItems(gtfs, tableName, items) {
}

const indexedTable = gtfs.getIndexedTable(tableName);
const indexKeys = schema.indexKeysByTableName[tableName];
const indexKeys = gtfs._schema.indexKeysByTableName[tableName];

if (indexKeys.indexKey) {
items.forEach(item => indexedTable.delete(item[indexKeys.indexKey]));
Expand Down Expand Up @@ -133,7 +133,7 @@ function removeItems(gtfs, tableName, items) {
* @param {Object|Map} indexedItems Object properly indexed as the schema requires the table to be (see schema.js).
*/
function setIndexedItems(gtfs, tableName, indexedItems) {
if (indexedItems instanceof Map === false && schema.deepnessByTableName[tableName] !== 0) {
if (indexedItems instanceof Map === false && gtfs._schema.deepnessByTableName[tableName] !== 0) {
throw new Error(`indexedItems must be a Map instead of: ${indexedItems}`);
}

Expand Down Expand Up @@ -165,18 +165,28 @@ class Gtfs {
* }]
* };
*
*
* # options.throws
*
* Optional ad-hoc boolean. Default is true. Will force the parser to ignore invalid rows in the tables.
*
* # options.forcedSchema
*
* Will overwrite the default schema by the value passed.
*
*
* @param {string} [path] Path to the folder that contains the GTFS text files.
* @param {{
* regexPatternObjectsByTableName: Map.<string, Array.<{regex: RegExp, pattern: string}>>,
* throws: boolean
* throws: boolean,
* forcedSchema,
* }} [options] Optional. See list above.
* @return {Gtfs} gtfs Instanciated GTFS object.
*/
constructor(path, {regexPatternObjectsByTableName = new Map(), throws = true} = {}) {
constructor(
path,
{ regexPatternObjectsByTableName = new Map(), throws = true, postImportTableFunction, forcedSchema } = {}
) {
if (path !== undefined) {
if (typeof path !== 'string' || path.length === 0) {
throw new Error(`Gtfs need a valid input path as string, instead of: "${path}".`);
Expand All @@ -194,7 +204,9 @@ class Gtfs {
this._path = path;
this._regexPatternObjectsByTableName = regexPatternObjectsByTableName;
this._shouldThrow = throws;
this._postImportTableFunction = postImportTableFunction;
this._tables = new Map();
this._schema = defaultSchema || forcedSchema;
}

/* Input/Output */
Expand Down Expand Up @@ -273,14 +285,21 @@ class Gtfs {
*
* @return {Set.<string>} Array of the table names
*/
getTableNames() { return new Set([...schema.tableNames, ...this._tables.keys()]); }
getTableNames() { return new Set([...this._schema.tableNames, ...this._tables.keys()]); }

/**
* Get the default schema of the GTFS. For safety, the schema is cloned before being passed.
*
* @return {Object} The schema
*/
static getDefaultSchema() { return JSON.parse(JSON.stringify(defaultSchema)); }

/**
* Get the schema of the GTFS. For safety, the schema is cloned before beeing passed.
* Get the schema of the GTFS. For safety, the schema is cloned before being passed.
*
* @return {Object} The schema
*/
static getSchema() { return JSON.parse(JSON.stringify(schema)); }
getSchema() { return JSON.parse(JSON.stringify(this._schema)); }

/**
* Build the list of the keys used in a table of the GTFS. Since the GTFS specification allows any additional field,
Expand Down
3 changes: 1 addition & 2 deletions helpers/export.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const errorLog = require('debug')('gtfsNodeLib:e');
const fs = require('fs-extra');

const { fromObjectToCsvString } = require('./csv');
const schema = require('./schema');

/**
* Private functions
Expand Down Expand Up @@ -80,7 +79,7 @@ function exportTable(tableName, gtfs, outputPath, callback) {
will be fixed.
2015-03-10
*/
const deepness = schema.deepnessByTableName[tableName];
const deepness = gtfs._schema.deepnessByTableName[tableName];

if (deepness === 0) {
const row = fromObjectToCsvString(gtfs.getIndexedTable(tableName), keys);
Expand Down
28 changes: 14 additions & 14 deletions helpers/getters.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const schema = require('./schema');
/* eslint-disable no-underscore-dangle */

/**
* Build the list of the keys used in a table of the GTFS. Since the GTFS specification allows any additional field,
Expand All @@ -12,8 +12,8 @@ const schema = require('./schema');
*/
function getActualKeysForTable(gtfs, tableName) {
const getSample = iterable => ((iterable && iterable.values().next()) ? iterable.values().next().value : undefined);
const keys = [...schema.keysByTableName[tableName]];
const deepness = schema.deepnessByTableName[tableName];
const keys = [...gtfs._schema.keysByTableName[tableName]];
const deepness = gtfs._schema.deepnessByTableName[tableName];
const table = gtfs.getIndexedTable(tableName);
let sampleItem;

Expand All @@ -27,7 +27,7 @@ function getActualKeysForTable(gtfs, tableName) {

if (sampleItem) {
Object.keys(sampleItem).forEach((key) => {
if (schema.keysByTableName[tableName].includes(key) === false) {
if (gtfs._schema.keysByTableName[tableName].includes(key) === false) {
keys.push(key);
}
});
Expand Down Expand Up @@ -57,15 +57,15 @@ function getGrandParentItem(itemWithForeignIndexId, parentTableName, grandParent
) {
throw new Error(`itemWithForeignIndexId must be a plain object, instead of an "${typeof itemWithForeignIndexId}"`);
}
if (schema.tableNames.includes(parentTableName) === false) {
if (gtfs._schema.tableNames.includes(parentTableName) === false) {
throw new Error(`Cannot find table with name "${parentTableName}"`);
}
if (schema.tableNames.includes(grandParentTableName) === false) {
if (gtfs._schema.tableNames.includes(grandParentTableName) === false) {
throw new Error(`Cannot find table with name "${grandParentTableName}"`);
}

/* Reach parent item */
const parentIndexKey = schema.indexKeysByTableName[parentTableName].indexKey;
const parentIndexKey = gtfs._schema.indexKeysByTableName[parentTableName].indexKey;

if (itemWithForeignIndexId[parentIndexKey] === undefined) {
throw new Error(`itemWithForeignIndexId should contain the foreign index key "${parentIndexKey}"`);
Expand All @@ -78,7 +78,7 @@ function getGrandParentItem(itemWithForeignIndexId, parentTableName, grandParent
}

/* Reach grandparent item */
const grandParentIndexKey = schema.indexKeysByTableName[grandParentTableName].indexKey;
const grandParentIndexKey = gtfs._schema.indexKeysByTableName[grandParentTableName].indexKey;

if (!parentItem[grandParentIndexKey]) {
throw new Error(`parentItem should contain the foreign index key "${grandParentIndexKey}"${parentItem}`);
Expand All @@ -96,14 +96,14 @@ function getGrandParentItem(itemWithForeignIndexId, parentTableName, grandParent
* @return {Map.<string, Object>} Indexed child items.
*/
function getIndexedItemsWithParent(parentItem, tableName, gtfs) {
if (schema.deepnessByTableName[tableName] !== 2) {
if (gtfs._schema.deepnessByTableName[tableName] !== 2) {
throw new Error(`Table "${tableName}" is not of deepness 2.`);
}
if (parentItem === undefined || parentItem === null || typeof parentItem !== 'object') {
throw new Error(`Parent item should be a plain object, instead of an "${typeof parentItem}"`);
}

const firstIndexKey = schema.indexKeysByTableName[tableName].firstIndexKey;
const firstIndexKey = gtfs._schema.indexKeysByTableName[tableName].firstIndexKey;

if (parentItem[firstIndexKey] === undefined) {
throw new Error(`Parent item should contain the foreign index key "${firstIndexKey}"`);
Expand All @@ -123,7 +123,7 @@ function getIndexedItemsWithParent(parentItem, tableName, gtfs) {
* @return {Map.<string, Object>} Indexed child items.
*/
function getIndexedItemsWithParentIndex(parentIndex, tableName, gtfs) {
if (schema.deepnessByTableName[tableName] !== 2) {
if (gtfs._schema.deepnessByTableName[tableName] !== 2) {
throw new Error(`Table "${tableName}" is not of deepness 2.`);
}
if (typeof parentIndex !== 'string') {
Expand All @@ -146,7 +146,7 @@ function getIndexedItemsWithParentIndex(parentIndex, tableName, gtfs) {
* @param {Gtfs} gtfs Gtfs object
*/
function getItemWithIndex(index, tableName, gtfs) {
if (schema.deepnessByTableName[tableName] !== 1) {
if (gtfs._schema.deepnessByTableName[tableName] !== 1) {
throw new Error(`Cannot access item with only one index in "${tableName}", since the deepness is not 1.`);
}
if (typeof index !== 'string') {
Expand All @@ -170,7 +170,7 @@ function getItemWithIndex(index, tableName, gtfs) {
* @param {Gtfs} gtfs Gtfs object
*/
function getItemWithIndexes(firstIndex, secondIndex, tableName, gtfs) {
if (schema.deepnessByTableName[tableName] !== 2) {
if (gtfs._schema.deepnessByTableName[tableName] !== 2) {
throw new Error(`Cannot access item with two indexes in "${tableName}", since the deep is not 2.`);
}
if (firstIndex === undefined || firstIndex === null || typeof firstIndex !== 'string') {
Expand Down Expand Up @@ -202,7 +202,7 @@ function getParentItem(itemWithForeignIndexId, tableName, gtfs) {
throw new Error(`itemWithForeignIndexId must be a plain object, instead of an "${typeof itemWithForeignIndexId}"`);
}

const indexKey = schema.indexKeysByTableName[tableName].indexKey;
const indexKey = gtfs._schema.indexKeysByTableName[tableName].indexKey;

if (itemWithForeignIndexId[indexKey] === undefined) {
throw new Error(
Expand Down
3 changes: 1 addition & 2 deletions helpers/import.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const fs = require('fs-extra');

const eachWithLog = require('./logging_iterator_wrapper');
const { fromCsvStringToArray } = require('./csv');
const schema = require('./schema');

/**
* Import a table in the GTFS.
Expand All @@ -17,7 +16,7 @@ const schema = require('./schema');
*/

exports.importTable = (gtfs, tableName) => {
const indexKeys = schema.indexKeysByTableName[tableName];
const indexKeys = gtfs._schema.indexKeysByTableName[tableName];
const fullPath = `${gtfs.getPath() + tableName}.txt`;

if (fs.existsSync(fullPath)) {
Expand Down
19 changes: 9 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,11 +669,11 @@ describe('Tests on GTFS', () => {
const funkyStop = {};
gtfs.addStop(funkyStop);

expect(Gtfs.getSchema().keysByTableName.stops).to.deep.equal(gtfs.getActualKeysForTable('stops'));
expect(gtfs.getSchema().keysByTableName.stops).to.deep.equal(gtfs.getActualKeysForTable('stops'));

funkyStop.route_funky_name = 'Tshboom tshboom';
funkyStop.route_esoteric_float = 120.37;
const standardRouteKeys = Gtfs.getSchema().keysByTableName.stops;
const standardRouteKeys = gtfs.getSchema().keysByTableName.stops;
const actualRouteKeys = gtfs.getActualKeysForTable('stops');

expect(standardRouteKeys).to.not.deep.equal(actualRouteKeys);
Expand Down

0 comments on commit 9407ece

Please sign in to comment.