gtfs 4.1.1 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.github/workflows/nodejs.yml +3 -3
  2. package/CHANGELOG.md +19 -0
  3. package/README.md +64 -15
  4. package/lib/db.js +14 -15
  5. package/lib/file-utils.js +7 -9
  6. package/lib/gtfs/shapes.js +8 -0
  7. package/lib/gtfs/stops.js +7 -1
  8. package/lib/import.js +28 -8
  9. package/models/gtfs/agency.js +2 -5
  10. package/models/gtfs/areas.js +1 -0
  11. package/models/gtfs/attributions.js +6 -1
  12. package/models/gtfs/calendar-dates.js +3 -7
  13. package/models/gtfs/calendar.js +1 -0
  14. package/models/gtfs/fare-attributes.js +2 -0
  15. package/models/gtfs/fare-leg-rules.js +9 -0
  16. package/models/gtfs/fare-products.js +7 -0
  17. package/models/gtfs/fare-rules.js +5 -5
  18. package/models/gtfs/fare-transfer-rules.js +10 -0
  19. package/models/gtfs/feed-info.js +0 -5
  20. package/models/gtfs/frequencies.js +3 -6
  21. package/models/gtfs/levels.js +1 -0
  22. package/models/gtfs/pathways.js +3 -0
  23. package/models/gtfs/routes.js +3 -0
  24. package/models/gtfs/shapes.js +3 -6
  25. package/models/gtfs/stop-areas.js +2 -0
  26. package/models/gtfs/stop-times.js +4 -7
  27. package/models/gtfs/stops.js +3 -0
  28. package/models/gtfs/transfers.js +13 -9
  29. package/models/gtfs/translations.js +8 -5
  30. package/models/gtfs/trips.js +5 -0
  31. package/models/gtfs-plus/calendar-attributes.js +1 -0
  32. package/models/gtfs-plus/directions.js +3 -7
  33. package/models/gtfs-plus/route-attributes.js +1 -0
  34. package/models/gtfs-plus/stop-attributes.js +2 -6
  35. package/models/gtfs-realtime/service-alert-targets.js +0 -1
  36. package/models/gtfs-ride/board-alight.js +2 -0
  37. package/models/gtfs-ride/rider-trip.js +5 -0
  38. package/models/gtfs-ride/ridership.js +5 -0
  39. package/models/gtfs-ride/trip-capacity.js +2 -0
  40. package/models/non-standard/timetable-notes-references.js +5 -0
  41. package/models/non-standard/timetable-notes.js +1 -0
  42. package/models/non-standard/timetable-pages.js +1 -0
  43. package/models/non-standard/timetable-stop-order.js +3 -0
  44. package/models/non-standard/timetables.js +3 -0
  45. package/models/non-standard/trips-dated-vehicle-journey.js +1 -0
  46. package/models/ods/deadhead-times.js +4 -0
  47. package/models/ods/deadheads.js +8 -0
  48. package/models/ods/ops-locations.js +1 -0
  49. package/models/ods/run-events.js +4 -0
  50. package/package.json +7 -7
  51. package/test/mocha/advanced-query.js +7 -7
  52. package/test/mocha/export-gtfs.js +6 -1
  53. package/test/mocha/get-agencies.js +0 -2
  54. package/test/mocha/get-calendar-dates.js +0 -4
  55. package/test/mocha/import-gtfs.js +32 -5
  56. package/test/mocha/open-db.js +0 -1
@@ -8,12 +8,12 @@ jobs:
8
8
 
9
9
  strategy:
10
10
  matrix:
11
- node-version: [14.x, 16.x, 18.x]
11
+ node-version: [16.x, 18.x, 20.x]
12
12
 
13
13
  steps:
14
- - uses: actions/checkout@v1
14
+ - uses: actions/checkout@v3
15
15
  - name: Use Node.js ${{ matrix.node-version }}
16
- uses: actions/setup-node@v1
16
+ uses: actions/setup-node@v3
17
17
  with:
18
18
  node-version: ${{ matrix.node-version }}
19
19
  - name: npm install and test
package/CHANGELOG.md CHANGED
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [4.3.0] - 2023-05-04
9
+
10
+ ### Updated
11
+
12
+ - Updated Readme to add closeDb documentation
13
+ - Use node-stream-zip instead of unzipper
14
+
15
+ ### Added
16
+
17
+ - Support for prefixes when importing multiple GTFS files
18
+
19
+ ## [4.2.0] - 2023-04-13
20
+
21
+ ### Updated
22
+
23
+ - Add route_attributes to getShapesAsGeoJSON() function as geojson properties
24
+ - Add stop_attributes to getStopsAsGeoJSON() function as geojson properties
25
+ - Support for multi-column primary keys
26
+
8
27
  ## [4.1.1] - 2023-04-12
9
28
 
10
29
  ### Added
package/README.md CHANGED
@@ -176,11 +176,21 @@ Copy `config-sample.json` to `config.json` and then add your projects configurat
176
176
 
177
177
  For GTFS files that contain more than one agency, you only need to list each GTFS file once in the `agencies` array, not once per agency that it contains.
178
178
 
179
- To find an agency's GTFS file, visit [transitfeeds.com](http://transitfeeds.com). You can use the
180
- URL from the agency's website or you can use a URL generated from the transitfeeds.com
181
- API along with your API token.
179
+ To find an agency's GTFS file, visit [transitfeeds.com](http://transitfeeds.com).
182
180
 
183
- - Specify a download URL:
181
+ #### agencies options
182
+
183
+ | option | type | description |
184
+ | ----------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
185
+ | `url` | string | The URL to a zipped GTFS file. Required if `path` not present. |
186
+ | `path` | string | A path to a zipped GTFS file or a directory of unzipped .txt files. Required if `url` is not present. |
187
+ | `headers` | object | An object of HTTP headers in key:value format to use when fetching GTFS from the `url` specified. Optional. |
188
+ | `prefix` | string | A prefix to be added to every ID field maintain uniqueness when importing multiple GTFS from multiple agencies. Optional. |
189
+ | `exclude` | array | An array of GTFS file names (without `.txt`) to exclude when importing. Optional. |
190
+ | `realtimeUrls` | array | An array of GTFS-Realtime urls to import. Optional. |
191
+ | `realtimeHeaders` | array | An object of HTTP headers in key:value format to use when fetching GTFS-Realtime data from the `realtimeUrls` specified. Optional. |
192
+
193
+ - Specify a `url` to download GTFS:
184
194
 
185
195
  ```json
186
196
  {
@@ -192,7 +202,7 @@ API along with your API token.
192
202
  }
193
203
  ```
194
204
 
195
- - Specify a download URL with custom headers:
205
+ - Specify a download URL with custom headers using the `headers` field:
196
206
 
197
207
  ```json
198
208
  {
@@ -208,7 +218,7 @@ API along with your API token.
208
218
  }
209
219
  ```
210
220
 
211
- - Specify a path to a zipped GTFS file:
221
+ - Specify a `path` to a zipped GTFS file:
212
222
 
213
223
  ```json
214
224
  {
@@ -220,7 +230,7 @@ API along with your API token.
220
230
  }
221
231
  ```
222
232
 
223
- - Specify a path to an unzipped GTFS file:
233
+ - Specify a `path` to an unzipped GTFS file:
224
234
 
225
235
  ```json
226
236
  {
@@ -232,7 +242,7 @@ API along with your API token.
232
242
  }
233
243
  ```
234
244
 
235
- - Exclude files - if you don't want all GTFS files to be imported, you can specify an array of files to exclude.
245
+ - If you don't want all GTFS files to be imported, you can specify an array of files to `exclude`. This can save a lot of time for larger GTFS.
236
246
 
237
247
  ```json
238
248
  {
@@ -279,6 +289,23 @@ API along with your API token.
279
289
  }
280
290
  ```
281
291
 
292
+ - When importing multiple agencies their IDs may overlap. Specify a `prefix` to be added to every ID field to maintain uniqueness.
293
+
294
+ ```json
295
+ {
296
+ "agencies": [
297
+ {
298
+ "path": "/path/to/the/gtfs.zip",
299
+ "prefix": "A"
300
+ },
301
+ {
302
+ "path": "/path/to/the/othergtfs.zip",
303
+ "prefix": 10000
304
+ }
305
+ ]
306
+ }
307
+ ```
308
+
282
309
  ### csvOptions
283
310
 
284
311
  {Object} Add options to be passed to [`csv-parse`](https://csv.js.org/parse/) with the key `csvOptions`. This is an optional parameter.
@@ -506,13 +533,29 @@ Most query methods accept three optional arguments: `query`, `fields`, `sortBy`
506
533
 
507
534
  For more advanced queries, you can use `advancedQuery` or raw SQL queries using query method from [better-sqlite3](#raw-sqlite-query).
508
535
 
509
- ### Setup
536
+ ### Database Setup
510
537
 
511
- To use any of the query methods, first open the database before making any queries:
538
+ To use any of the query methods, first open the database using `openDb` before making any queries:
512
539
 
513
540
  ```js
514
541
  import { openDb } from 'gtfs';
542
+ import { readFile } from 'fs/promises';
543
+ const config = JSON.parse(
544
+ await readFile(new URL('./config.json', import.meta.url))
545
+ );
546
+ const db = openDb(config);
547
+ ```
548
+
549
+ If you no longer need a database (especially if using an in-memory database) you can use `closeDb`:
550
+
551
+ ```js
552
+ import { closeDb, openDb } from 'gtfs';
515
553
  const db = openDb(config);
554
+
555
+ // Do some stuff here
556
+
557
+ // Close database connection when done.
558
+ closeDb(db);
516
559
  ```
517
560
 
518
561
  ### Examples
@@ -520,7 +563,7 @@ const db = openDb(config);
520
563
  For example, to get a list of all routes with just `route_id`, `route_short_name` and `route_color` sorted by `route_short_name`:
521
564
 
522
565
  ```js
523
- import { openDb, getRoutes } from 'gtfs';
566
+ import { closeDb, openDb, getRoutes } from 'gtfs';
524
567
  import { readFile } from 'fs/promises';
525
568
  const config = JSON.parse(
526
569
  await readFile(new URL('./config.json', import.meta.url))
@@ -533,12 +576,14 @@ const routes = getRoutes(
533
576
  [['route_short_name', 'ASC']], // Sort by this field and direction
534
577
  { db: db } // Options for the query. Can specify which database to use if more than one are open
535
578
  );
579
+
580
+ closeDb(db);
536
581
  ```
537
582
 
538
583
  To get a list of all trip_ids for a specific route:
539
584
 
540
585
  ```js
541
- import { openDb, getTrips } from 'gtfs';
586
+ import { closeDb, openDb, getTrips } from 'gtfs';
542
587
  import { readFile } from 'fs/promises';
543
588
  const config = JSON.parse(
544
589
  await readFile(new URL('./config.json', import.meta.url))
@@ -551,12 +596,14 @@ const trips = getTrips(
551
596
  },
552
597
  ['trip_id']
553
598
  );
599
+
600
+ closeDb(db);
554
601
  ```
555
602
 
556
603
  To get a few stops by specific stop_ids:
557
604
 
558
605
  ```js
559
- import { openDb, getStops } from 'gtfs';
606
+ import { closeDb, openDb, getStops } from 'gtfs';
560
607
  import { readFile } from 'fs/promises';
561
608
  const config = JSON.parse(await readFile(new URL('./config.json', import.meta.url)));
562
609
 
@@ -570,6 +617,8 @@ const stops = getStops(
570
617
  ]
571
618
  }
572
619
  );
620
+
621
+ closeDb(db);
573
622
  ```
574
623
 
575
624
  ### Static GTFS Files
@@ -692,7 +741,7 @@ const stops = getStops({
692
741
 
693
742
  #### getStopsAsGeoJSON(query, options)
694
743
 
695
- Returns geoJSON object of stops that match query parameters. All valid queries for `getStops()` work for `getStopsAsGeoJSON()`.
744
+ Returns geoJSON object of stops that match query parameters. Stops will include all properties of each stop from stops.txt and stop_attributes.txt if present. All valid queries for `getStops()` work for `getStopsAsGeoJSON()`.
696
745
 
697
746
  ```js
698
747
  import { getStopsAsGeoJSON } from 'gtfs';
@@ -804,7 +853,7 @@ const shapes = getShapes({
804
853
 
805
854
  #### getShapesAsGeoJSON(query, options)
806
855
 
807
- Returns a geoJSON object of shapes that match query parameters. All valid queries for `getShapes()` work for `getShapesAsGeoJSON()`.
856
+ Returns a geoJSON object of shapes that match query parameters. Shapes will include all properties of each route from routes.txt and route_attributes.txt if present. All valid queries for `getShapes()` work for `getShapesAsGeoJSON()`.
808
857
 
809
858
  ```js
810
859
  import { getShapesAsGeoJSON } from 'gtfs';
package/lib/db.js CHANGED
@@ -4,21 +4,26 @@ import untildify from 'untildify';
4
4
  import { setDefaultConfig } from './utils.js';
5
5
  const dbs = {};
6
6
 
7
- const getOrCreateDbConnection = (sqlitePath) => {
8
- if (dbs[sqlitePath]) {
9
- return dbs[sqlitePath];
10
- }
11
-
7
+ function setupDb(sqlitePath) {
12
8
  const db = new Database(untildify(sqlitePath));
13
- setupDb(db);
14
-
9
+ db.pragma('journal_mode = OFF');
10
+ db.pragma('synchronous = OFF');
11
+ db.pragma('temp_store = MEMORY');
15
12
  dbs[sqlitePath] = db;
13
+
16
14
  return db;
17
- };
15
+ }
18
16
 
19
17
  export function openDb(config) {
18
+ // If config is passed, use that to open or return db
20
19
  if (config) {
21
- return getOrCreateDbConnection(setDefaultConfig(config).sqlitePath);
20
+ const { sqlitePath } = setDefaultConfig(config);
21
+
22
+ if (dbs[sqlitePath]) {
23
+ return dbs[sqlitePath];
24
+ }
25
+
26
+ return setupDb(sqlitePath);
22
27
  }
23
28
 
24
29
  // If only one db connection already exists, use it
@@ -36,12 +41,6 @@ export function openDb(config) {
36
41
  throw new Error('Unable to find database connection.');
37
42
  }
38
43
 
39
- export function setupDb(db) {
40
- db.pragma('journal_mode = OFF');
41
- db.pragma('synchronous = OFF');
42
- db.pragma('temp_store = MEMORY');
43
- }
44
-
45
44
  export function closeDb(db) {
46
45
  if (Object.keys(dbs).length === 0) {
47
46
  throw new Error(
package/lib/file-utils.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import path from 'node:path';
2
- import { createReadStream, existsSync } from 'node:fs';
2
+ import { existsSync } from 'node:fs';
3
3
  import { mkdir, readFile, rm } from 'node:fs/promises';
4
4
  import { omit, snakeCase } from 'lodash-es';
5
5
  import sanitize from 'sanitize-filename';
6
6
  import untildify from 'untildify';
7
- import { Extract } from 'unzipper';
7
+ import StreamZip from 'node-stream-zip';
8
8
 
9
9
  /*
10
10
  * Attempt to parse any config JSON file and read values from CLI.
@@ -91,13 +91,11 @@ export async function prepDirectory(exportPath) {
91
91
  /*
92
92
  * Unzip a zipfile into a specified directory
93
93
  */
94
- export function unzip(zipfilePath, exportPath) {
95
- /* eslint-disable new-cap */
96
- return createReadStream(zipfilePath)
97
- .pipe(Extract({ path: exportPath }))
98
- .on('entry', (entry) => entry.autodrain())
99
- .promise();
100
- /* eslint-enable new-cap */
94
+ export async function unzip(zipfilePath, exportPath) {
95
+ /* eslint-disable-next-line new-cap */
96
+ const zip = new StreamZip.async({ file: zipfilePath });
97
+ await zip.extract(null, exportPath);
98
+ await zip.close();
101
99
  }
102
100
 
103
101
  /*
@@ -14,6 +14,7 @@ import { shapesToGeoJSONFeatures } from '../geojson-utils.js';
14
14
  import shapes from '../../models/gtfs/shapes.js';
15
15
  import { getAgencies } from './agencies.js';
16
16
  import { getRoutes } from './routes.js';
17
+ import { getRouteAttributes } from '../gtfs-plus/route-attributes.js';
17
18
 
18
19
  function buildTripSubquery(query) {
19
20
  const whereClause = formatWhereClauses(query);
@@ -92,6 +93,12 @@ export function getShapesAsGeoJSON(query = {}, options = {}) {
92
93
  [],
93
94
  options
94
95
  );
96
+ const routeAttributes = getRouteAttributes(
97
+ { route_id: route.route_id },
98
+ [],
99
+ [],
100
+ options
101
+ );
95
102
 
96
103
  const agency = agencies.find(
97
104
  (agency) => agency.agency_id === route.agency_id
@@ -101,6 +108,7 @@ export function getShapesAsGeoJSON(query = {}, options = {}) {
101
108
  agency_name: agency ? agency.agency_name : undefined,
102
109
  shape_id: query.shape_id,
103
110
  ...route,
111
+ ...(routeAttributes?.[0] || []),
104
112
  };
105
113
  features.push(...shapesToGeoJSONFeatures(shapes, geojsonProperties));
106
114
  }
package/lib/gtfs/stops.js CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  import { stopsToGeoJSON } from '../geojson-utils.js';
13
13
  import stops from '../../models/gtfs/stops.js';
14
14
  import { getAgencies } from './agencies.js';
15
+ import { getStopAttributes } from '../gtfs-plus/stop-attributes.js';
15
16
 
16
17
  function buildTripSubquery(query) {
17
18
  const whereClause = formatWhereClauses(query);
@@ -89,12 +90,17 @@ export function getStopsAsGeoJSON(query = {}, options = {}) {
89
90
  .prepare(`SELECT * FROM routes WHERE route_id IN (${routeSubquery})`)
90
91
  .all(stop.stop_id);
91
92
 
93
+ const stopAttributes = getStopAttributes({ stop_id: stop.stop_id });
94
+
92
95
  stop.routes = orderBy(routes, (route) =>
93
96
  Number.parseInt(route.route_short_name, 10)
94
97
  );
95
98
  stop.agency_name = agencies[0].agency_name;
96
99
 
97
- return stop;
100
+ return {
101
+ ...stop,
102
+ ...(stopAttributes?.[0] || []),
103
+ };
98
104
  });
99
105
 
100
106
  // Exclude stops not part of any route
package/lib/import.js CHANGED
@@ -329,13 +329,23 @@ const createTables = (db) => {
329
329
  check = `CHECK( ${column.name} <= ${column.max} )`;
330
330
  }
331
331
 
332
- const primary = column.primary ? 'PRIMARY KEY' : '';
333
332
  const required = column.required ? 'NOT NULL' : '';
334
333
  const columnDefault = column.default ? 'DEFAULT ' + column.default : '';
335
334
  const columnCollation = column.nocase ? 'COLLATE NOCASE' : '';
336
- return `${column.name} ${column.type} ${check} ${primary} ${required} ${columnDefault} ${columnCollation}`;
335
+ return `${column.name} ${column.type} ${check} ${required} ${columnDefault} ${columnCollation}`;
337
336
  });
338
337
 
338
+ // Find Primary Key fields
339
+ const primaryColumns = model.schema.filter((column) => column.primary);
340
+
341
+ if (primaryColumns.length > 0) {
342
+ columns.push(
343
+ `PRIMARY KEY (${primaryColumns
344
+ .map((column) => column.name)
345
+ .join(', ')})`
346
+ );
347
+ }
348
+
339
349
  db.prepare(`DROP TABLE IF EXISTS ${model.filenameBase};`).run();
340
350
 
341
351
  db.prepare(
@@ -436,23 +446,32 @@ const importLines = (task, lines, model, totalLineCount) => {
436
446
  }
437
447
 
438
448
  const linesToImportCount = lines.length;
439
- const fieldNames = model.schema
440
- .filter((column) => column.name !== 'id')
441
- .map((column) => column.name);
449
+ const columns = model.schema.filter((column) => column.name !== 'id');
442
450
  const placeholders = [];
443
451
  const values = [];
444
452
 
445
453
  while (lines.length > 0) {
446
454
  const line = lines.pop();
447
- placeholders.push(`(${fieldNames.map(() => '?').join(', ')})`);
448
- values.push(...fieldNames.map((fieldName) => line[fieldName]));
455
+ placeholders.push(`(${columns.map(() => '?').join(', ')})`);
456
+ values.push(
457
+ ...columns.map((column) => {
458
+ if (task.prefix !== undefined && column.prefix === true) {
459
+ // Add prefixes to field values if needed
460
+ return `${task.prefix}${line[column.name]}`;
461
+ }
462
+
463
+ return line[column.name];
464
+ })
465
+ );
449
466
  }
450
467
 
451
468
  try {
452
469
  db.prepare(
453
470
  `INSERT ${task.ignoreDuplicates ? 'OR IGNORE' : ''} INTO ${
454
471
  model.filenameBase
455
- } (${fieldNames.join(', ')}) VALUES ${placeholders.join(',')}`
472
+ } (${columns
473
+ .map((column) => column.name)
474
+ .join(', ')}) VALUES ${placeholders.join(',')}`
456
475
  ).run(...values);
457
476
  } catch (error) {
458
477
  task.warn(
@@ -578,6 +597,7 @@ export async function importGtfs(initialConfig) {
578
597
  csvOptions: config.csvOptions || {},
579
598
  ignoreDuplicates: config.ignoreDuplicates,
580
599
  sqlitePath: config.sqlitePath,
600
+ prefix: agency.prefix,
581
601
  log,
582
602
  warn: logWarning,
583
603
  error: logError,
@@ -1,14 +1,11 @@
1
1
  const model = {
2
2
  filenameBase: 'agency',
3
3
  schema: [
4
- {
5
- name: 'id',
6
- type: 'integer',
7
- primary: true,
8
- },
9
4
  {
10
5
  name: 'agency_id',
11
6
  type: 'varchar(255)',
7
+ primary: true,
8
+ prefix: true,
12
9
  },
13
10
  {
14
11
  name: 'agency_name',
@@ -6,6 +6,7 @@ const model = {
6
6
  type: 'varchar(255)',
7
7
  required: true,
8
8
  primary: true,
9
+ prefix: true,
9
10
  },
10
11
  {
11
12
  name: 'area_name',
@@ -5,18 +5,23 @@ const model = {
5
5
  name: 'attribution_id',
6
6
  type: 'varchar(255)',
7
7
  primary: true,
8
+ required: true,
9
+ prefix: true,
8
10
  },
9
11
  {
10
12
  name: 'agency_id',
11
- type: 'varchar(255)',
13
+ type: 'varchar(255)',
14
+ prefix: true,
12
15
  },
13
16
  {
14
17
  name: 'route_id',
15
18
  type: 'varchar(255)',
19
+ prefix: true,
16
20
  },
17
21
  {
18
22
  name: 'trip_id',
19
23
  type: 'varchar(255)',
24
+ prefix: true,
20
25
  },
21
26
  {
22
27
  name: 'organization_name',
@@ -1,22 +1,18 @@
1
1
  const model = {
2
2
  filenameBase: 'calendar_dates',
3
3
  schema: [
4
- {
5
- name: 'id',
6
- type: 'integer',
7
- primary: true,
8
- },
9
4
  {
10
5
  name: 'service_id',
11
6
  type: 'varchar(255)',
12
7
  required: true,
13
- index: true,
8
+ primary: true,
9
+ prefix: true,
14
10
  },
15
11
  {
16
12
  name: 'date',
17
13
  type: 'integer',
18
14
  required: true,
19
- index: true,
15
+ primary: true,
20
16
  },
21
17
  {
22
18
  name: 'exception_type',
@@ -6,6 +6,7 @@ const model = {
6
6
  type: 'varchar(255)',
7
7
  required: true,
8
8
  primary: true,
9
+ prefix: true,
9
10
  },
10
11
  {
11
12
  name: 'monday',
@@ -6,6 +6,7 @@ const model = {
6
6
  type: 'varchar(255)',
7
7
  required: true,
8
8
  primary: true,
9
+ prefix: true,
9
10
  },
10
11
  {
11
12
  name: 'price',
@@ -33,6 +34,7 @@ const model = {
33
34
  {
34
35
  name: 'agency_id',
35
36
  type: 'varchar(255)',
37
+ prefix: true,
36
38
  },
37
39
  {
38
40
  name: 'transfer_duration',
@@ -4,23 +4,32 @@ const model = {
4
4
  {
5
5
  name: 'leg_group_id',
6
6
  type: 'varchar(255)',
7
+ prefix: true,
7
8
  },
8
9
  {
9
10
  name: 'network_id',
10
11
  type: 'varchar(255)',
12
+ primary: true,
13
+ prefix: true,
11
14
  },
12
15
  {
13
16
  name: 'from_area_id',
14
17
  type: 'varchar(255)',
18
+ primary: true,
19
+ prefix: true,
15
20
  },
16
21
  {
17
22
  name: 'to_area_id',
18
23
  type: 'varchar(255)',
24
+ primary: true,
25
+ prefix: true,
19
26
  },
20
27
  {
21
28
  name: 'fare_product_id',
22
29
  type: 'varchar(255)',
23
30
  required: true,
31
+ primary: true,
32
+ prefix: true,
24
33
  },
25
34
  ],
26
35
  };
@@ -6,11 +6,18 @@ const model = {
6
6
  type: 'varchar(255)',
7
7
  required: true,
8
8
  primary: true,
9
+ prefix: true,
9
10
  },
10
11
  {
11
12
  name: 'fare_product_name',
12
13
  type: 'varchar(255)',
13
14
  },
15
+ {
16
+ name: 'fare_media_id',
17
+ type: 'varchar(255)',
18
+ primary: true,
19
+ prefix: true,
20
+ },
14
21
  {
15
22
  name: 'amount',
16
23
  type: 'real',
@@ -1,31 +1,31 @@
1
1
  const model = {
2
2
  filenameBase: 'fare_rules',
3
3
  schema: [
4
- {
5
- name: 'id',
6
- type: 'integer',
7
- primary: true,
8
- },
9
4
  {
10
5
  name: 'fare_id',
11
6
  type: 'varchar(255)',
12
7
  required: true,
8
+ prefix: true,
13
9
  },
14
10
  {
15
11
  name: 'route_id',
16
12
  type: 'varchar(255)',
13
+ prefix: true,
17
14
  },
18
15
  {
19
16
  name: 'origin_id',
20
17
  type: 'varchar(255)',
18
+ prefix: true,
21
19
  },
22
20
  {
23
21
  name: 'destination_id',
24
22
  type: 'varchar(255)',
23
+ prefix: true,
25
24
  },
26
25
  {
27
26
  name: 'contains_id',
28
27
  type: 'varchar(255)',
28
+ prefix: true,
29
29
  },
30
30
  ],
31
31
  };
@@ -4,24 +4,31 @@ const model = {
4
4
  {
5
5
  name: 'from_leg_group_id',
6
6
  type: 'varchar(255)',
7
+ primary: true,
8
+ prefix: true,
7
9
  },
8
10
  {
9
11
  name: 'to_leg_group_id',
10
12
  type: 'varchar(255)',
13
+ primary: true,
14
+ prefix: true,
11
15
  },
12
16
  {
13
17
  name: 'transfer_count',
14
18
  type: 'integer',
15
19
  min: -1,
20
+ primary: true,
16
21
  },
17
22
  {
18
23
  name: 'transfer_id',
19
24
  type: 'varchar(255)',
25
+ prefix: true,
20
26
  },
21
27
  {
22
28
  name: 'duration_limit',
23
29
  type: 'integer',
24
30
  min: 0,
31
+ primary: true,
25
32
  },
26
33
  {
27
34
  name: 'duration_limit_type',
@@ -34,10 +41,13 @@ const model = {
34
41
  type: 'integer',
35
42
  min: 0,
36
43
  max: 2,
44
+ required: true,
37
45
  },
38
46
  {
39
47
  name: 'fare_product_id',
40
48
  type: 'varchar(255)',
49
+ primary: true,
50
+ prefix: true,
41
51
  },
42
52
  ],
43
53
  };