gtfs 4.10.1 → 4.10.3
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.
- package/.github/workflows/nodejs.yml +1 -1
- package/@types/index.d.ts +5 -0
- package/CHANGELOG.md +22 -0
- package/README.md +27 -5
- package/lib/db.js +26 -0
- package/lib/gtfs.js +3 -1
- package/lib/import.js +30 -13
- package/models/gtfs-realtime/vehicle-positions.js +62 -0
- package/package.json +2 -2
- package/test/mocha/delete-db.js +62 -0
package/@types/index.d.ts
CHANGED
|
@@ -160,6 +160,11 @@ export function openDb(config: DbConfig): Database.Database;
|
|
|
160
160
|
*/
|
|
161
161
|
export function closeDb(db?: Database.Database): void;
|
|
162
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Deletes the specified database.
|
|
165
|
+
*/
|
|
166
|
+
export function deleteDb(db?: Database.Database): void;
|
|
167
|
+
|
|
163
168
|
/**
|
|
164
169
|
* Returns an array of agencies that match query parameters.
|
|
165
170
|
*/
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,28 @@ 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.10.3] - 2024-05-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Additional GTFS-RT vehiclePosition fields
|
|
13
|
+
- deleteDb method
|
|
14
|
+
|
|
15
|
+
### Updated
|
|
16
|
+
|
|
17
|
+
- Dependency updates
|
|
18
|
+
|
|
19
|
+
## [4.10.2] - 2024-04-02
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Better error message for `gtfsrealtime-update` command
|
|
24
|
+
- Support additional fields for vehiclePosition GTFS-Realtime data
|
|
25
|
+
|
|
26
|
+
### Updated
|
|
27
|
+
|
|
28
|
+
- Dependency updates
|
|
29
|
+
|
|
8
30
|
## [4.10.1] - 2024-03-29
|
|
9
31
|
|
|
10
32
|
### Updated
|
package/README.md
CHANGED
|
@@ -636,6 +636,20 @@ const db = openDb(config);
|
|
|
636
636
|
closeDb(db);
|
|
637
637
|
```
|
|
638
638
|
|
|
639
|
+
### Deleting a Database
|
|
640
|
+
|
|
641
|
+
You can use `deleteDb` to delete a sqlite3 database from the filesystem.
|
|
642
|
+
|
|
643
|
+
```js
|
|
644
|
+
import { deleteDb, openDb } from 'gtfs';
|
|
645
|
+
const db = openDb(config);
|
|
646
|
+
|
|
647
|
+
// Do some stuff here
|
|
648
|
+
|
|
649
|
+
// Delete the database
|
|
650
|
+
deleteDb(db);
|
|
651
|
+
```
|
|
652
|
+
|
|
639
653
|
### Examples
|
|
640
654
|
|
|
641
655
|
For example, to get a list of all routes with just `route_id`, `route_short_name` and `route_color` sorted by `route_short_name`:
|
|
@@ -1338,11 +1352,13 @@ const timetableNotesReferences = getTimetableNotesReferences({
|
|
|
1338
1352
|
|
|
1339
1353
|
### GTFS-Realtime
|
|
1340
1354
|
|
|
1341
|
-
In order to use GTFS-Realtime query methods, you must first
|
|
1355
|
+
In order to use GTFS-Realtime query methods, you must first run the [GTFS-Realtime update script or function](#gtfsrealtime-update-script) to pull data into your database.
|
|
1342
1356
|
|
|
1343
1357
|
#### getServiceAlerts(query, fields, sortBy, options)
|
|
1344
1358
|
|
|
1345
|
-
Returns an array of GTFS Realtime service alerts that match query parameters. [
|
|
1359
|
+
Returns an array of GTFS Realtime service alerts that match query parameters. Note that this does not refresh the data from GTFS-Realtime feeds, it only fetches what is stored in the database. In order to fetch the latest service alerts from GTFS-Realtime feeds and store in your database, use the [GTFS-Realtime update script or function](#gtfsrealtime-update-script).
|
|
1360
|
+
|
|
1361
|
+
[More details on Service Alerts](https://gtfs.org/realtime/feed-entities/service-alerts/)
|
|
1346
1362
|
|
|
1347
1363
|
```js
|
|
1348
1364
|
import { getServiceAlerts } from 'gtfs';
|
|
@@ -1353,7 +1369,9 @@ const serviceAlerts = getServiceAlerts();
|
|
|
1353
1369
|
|
|
1354
1370
|
#### getTripUpdates(query, fields, sortBy, options)
|
|
1355
1371
|
|
|
1356
|
-
Returns an array of GTFS Realtime trip updates that match query parameters. [
|
|
1372
|
+
Returns an array of GTFS Realtime trip updates that match query parameters. Note that this does not refresh the data from GTFS-Realtime feeds, it only fetches what is stored in the database. In order to fetch the latest trip updates from GTFS-Realtime feeds and store in your database, use the [GTFS-Realtime update script or function](#gtfsrealtime-update-script).
|
|
1373
|
+
|
|
1374
|
+
[More details on Trip Updates](https://gtfs.org/realtime/feed-entities/trip-updates/)
|
|
1357
1375
|
|
|
1358
1376
|
```js
|
|
1359
1377
|
import { getTripUpdates } from 'gtfs';
|
|
@@ -1364,7 +1382,9 @@ const tripUpdates = getTripUpdates();
|
|
|
1364
1382
|
|
|
1365
1383
|
#### getStopTimeUpdates(query, fields, sortBy, options)
|
|
1366
1384
|
|
|
1367
|
-
Returns an array of GTFS Realtime stop time updates that match query parameters. [
|
|
1385
|
+
Returns an array of GTFS Realtime stop time updates that match query parameters. Note that this does not refresh the data from GTFS-Realtime feeds, it only fetches what is stored in the database. In order to fetch the latest stop time updates from GTFS-Realtime feeds and store in your database, use the [GTFS-Realtime update script or function](#gtfsrealtime-update-script).
|
|
1386
|
+
|
|
1387
|
+
[More details on Stop Time Updates](https://gtfs.org/realtime/feed-entities/trip-updates/#stoptimeupdate)
|
|
1368
1388
|
|
|
1369
1389
|
```js
|
|
1370
1390
|
import { getStopTimeUpdates } from 'gtfs';
|
|
@@ -1375,7 +1395,9 @@ const stopTimeUpdates = getStopTimeUpdates();
|
|
|
1375
1395
|
|
|
1376
1396
|
#### getVehiclePositions(query, fields, sortBy, options)
|
|
1377
1397
|
|
|
1378
|
-
Returns an array of GTFS Realtime vehicle positions that match query parameters. [
|
|
1398
|
+
Returns an array of GTFS Realtime vehicle positions that match query parameters. Note that this does not refresh the data from GTFS-Realtime feeds, it only fetches what is stored in the database. In order to fetch the latest vehicle positions from GTFS-Realtime feeds and store in your database, use the [GTFS-Realtime update script or function](#gtfsrealtime-update-script).
|
|
1399
|
+
|
|
1400
|
+
[More details on Vehicle Positions](https://gtfs.org/realtime/feed-entities/vehicle-positions/)
|
|
1379
1401
|
|
|
1380
1402
|
```js
|
|
1381
1403
|
import { getVehiclePositions } from 'gtfs';
|
package/lib/db.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
1
3
|
import Database from 'better-sqlite3';
|
|
2
4
|
import untildify from 'untildify';
|
|
3
5
|
|
|
@@ -64,3 +66,27 @@ export function closeDb(db) {
|
|
|
64
66
|
db.close();
|
|
65
67
|
delete dbs[db.name];
|
|
66
68
|
}
|
|
69
|
+
|
|
70
|
+
export function deleteDb(db) {
|
|
71
|
+
if (Object.keys(dbs).length === 0) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
'No database connection. Call `openDb(config)` before using any methods.',
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!db) {
|
|
78
|
+
if (Object.keys(dbs).length > 1) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
'Multiple database connections. Pass the db you want to delete as a parameter to `deleteDb`.',
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
db = dbs[Object.keys(dbs)[0]];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
db.close();
|
|
88
|
+
|
|
89
|
+
fs.unlinkSync(db.name);
|
|
90
|
+
|
|
91
|
+
delete dbs[db.name];
|
|
92
|
+
}
|
package/lib/gtfs.js
CHANGED
|
@@ -67,7 +67,7 @@ import { getRunEvents } from './ods/run-events.js';
|
|
|
67
67
|
import { getRunsPieces } from './ods/runs-pieces.js';
|
|
68
68
|
|
|
69
69
|
// Expose database connection
|
|
70
|
-
import { openDb, closeDb } from './db.js';
|
|
70
|
+
import { deleteDb, openDb, closeDb } from './db.js';
|
|
71
71
|
|
|
72
72
|
// Advanced Query
|
|
73
73
|
import { advancedQuery } from './advancedQuery.js';
|
|
@@ -238,6 +238,8 @@ const _openDb = openDb;
|
|
|
238
238
|
export { _openDb as openDb };
|
|
239
239
|
const _closeDb = closeDb;
|
|
240
240
|
export { _closeDb as closeDb };
|
|
241
|
+
const _deleteDb = deleteDb;
|
|
242
|
+
export { _deleteDb as deleteDb };
|
|
241
243
|
|
|
242
244
|
const _advancedQuery = advancedQuery;
|
|
243
245
|
export { _advancedQuery as advancedQuery };
|
package/lib/import.js
CHANGED
|
@@ -107,22 +107,39 @@ function getDescendantProp(obj, desc, defaultvalue) {
|
|
|
107
107
|
return obj;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
const markRealtimeDataStale = (config
|
|
111
|
-
const
|
|
110
|
+
const markRealtimeDataStale = (config) => {
|
|
111
|
+
const log = _log(config);
|
|
112
|
+
const logError = _logError(config);
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
114
|
+
try {
|
|
115
|
+
const db = openDb(config);
|
|
116
|
+
|
|
117
|
+
log(`Marking GTFS-Realtime data as stale`);
|
|
118
|
+
db.prepare(`UPDATE vehicle_positions SET is_updated=0`).run();
|
|
119
|
+
db.prepare(`UPDATE trip_updates SET is_updated=0`).run();
|
|
120
|
+
db.prepare(`UPDATE stop_time_updates SET is_updated=0`).run();
|
|
121
|
+
db.prepare(`UPDATE service_alerts SET is_updated=0`).run();
|
|
122
|
+
db.prepare(`UPDATE service_alert_targets SET is_updated=0`).run();
|
|
123
|
+
log(`Marked GTFS-Realtime data as stale\r`, true);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (
|
|
126
|
+
error instanceof Error &&
|
|
127
|
+
error.code === 'SQLITE_ERROR' &&
|
|
128
|
+
error.message?.startsWith('no such table')
|
|
129
|
+
) {
|
|
130
|
+
logError(
|
|
131
|
+
'Run `gtfs-import` before running the `gtfsrealtime-update` command to set up tables.',
|
|
132
|
+
);
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
120
136
|
};
|
|
121
137
|
|
|
122
|
-
const cleanStaleRealtimeData = (config
|
|
138
|
+
const cleanStaleRealtimeData = (config) => {
|
|
139
|
+
const log = _log(config);
|
|
123
140
|
const db = openDb(config);
|
|
124
141
|
|
|
125
|
-
log(`Cleaning stale GTFS-RT data
|
|
142
|
+
log(`Cleaning stale GTFS-RT data`);
|
|
126
143
|
db.prepare(`DELETE FROM vehicle_positions WHERE is_updated=0`).run();
|
|
127
144
|
db.prepare(`DELETE FROM trip_updates WHERE is_updated=0`).run();
|
|
128
145
|
db.prepare(`DELETE FROM stop_time_updates WHERE is_updated=0`).run();
|
|
@@ -708,7 +725,7 @@ export async function updateGtfsRealtime(initialConfig) {
|
|
|
708
725
|
)} using SQLite database at ${config.sqlitePath}`,
|
|
709
726
|
);
|
|
710
727
|
|
|
711
|
-
markRealtimeDataStale(config
|
|
728
|
+
markRealtimeDataStale(config);
|
|
712
729
|
|
|
713
730
|
await Promise.all(
|
|
714
731
|
config.agencies.map(async (agency) => {
|
|
@@ -729,7 +746,7 @@ export async function updateGtfsRealtime(initialConfig) {
|
|
|
729
746
|
}),
|
|
730
747
|
);
|
|
731
748
|
|
|
732
|
-
cleanStaleRealtimeData(config
|
|
749
|
+
cleanStaleRealtimeData(config);
|
|
733
750
|
log(
|
|
734
751
|
`Completed GTFS-Realtime refresh for ${pluralize(
|
|
735
752
|
'agencies',
|
|
@@ -39,6 +39,12 @@ const model = {
|
|
|
39
39
|
source: 'vehicle.position.speed',
|
|
40
40
|
default: null,
|
|
41
41
|
},
|
|
42
|
+
{
|
|
43
|
+
name: 'current_stop_sequence',
|
|
44
|
+
type: 'integer',
|
|
45
|
+
source: 'vehicle.currentStopSequence',
|
|
46
|
+
default: null,
|
|
47
|
+
},
|
|
42
48
|
{
|
|
43
49
|
name: 'trip_id',
|
|
44
50
|
type: 'varchar(255)',
|
|
@@ -46,6 +52,44 @@ const model = {
|
|
|
46
52
|
source: 'vehicle.trip.tripId',
|
|
47
53
|
default: null,
|
|
48
54
|
},
|
|
55
|
+
{
|
|
56
|
+
name: 'trip_start_date',
|
|
57
|
+
type: 'varchar(255)',
|
|
58
|
+
index: true,
|
|
59
|
+
source: 'vehicle.trip.startDate',
|
|
60
|
+
default: null,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'trip_start_time',
|
|
64
|
+
type: 'varchar(255)',
|
|
65
|
+
index: true,
|
|
66
|
+
source: 'vehicle.trip.startTime',
|
|
67
|
+
default: null,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'congestion_level',
|
|
71
|
+
type: 'varchar(255)',
|
|
72
|
+
source: 'vehicle.congestionLevel',
|
|
73
|
+
default: null,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'occupancy_status',
|
|
77
|
+
type: 'varchar(255)',
|
|
78
|
+
source: 'vehicle.occupancyStatus',
|
|
79
|
+
default: null,
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'occupancy_percentage',
|
|
83
|
+
type: 'integer',
|
|
84
|
+
source: 'vehicle.occupancyPercentage',
|
|
85
|
+
default: null,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'vehicle_stop_status',
|
|
89
|
+
type: 'varchar(255)',
|
|
90
|
+
source: 'vehicle.vehicleStopStatus',
|
|
91
|
+
default: null,
|
|
92
|
+
},
|
|
49
93
|
{
|
|
50
94
|
name: 'vehicle_id',
|
|
51
95
|
type: 'varchar(255)',
|
|
@@ -53,6 +97,24 @@ const model = {
|
|
|
53
97
|
source: 'vehicle.vehicle.id',
|
|
54
98
|
default: null,
|
|
55
99
|
},
|
|
100
|
+
{
|
|
101
|
+
name: 'vehicle_label',
|
|
102
|
+
type: 'varchar(255)',
|
|
103
|
+
source: 'vehicle.vehicle.label',
|
|
104
|
+
default: null,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'vehicle_license_plate',
|
|
108
|
+
type: 'varchar(255)',
|
|
109
|
+
source: 'vehicle.vehicle.licensePlate',
|
|
110
|
+
default: null,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'vehicle_wheelchair_accessible',
|
|
114
|
+
type: 'varchar(255)',
|
|
115
|
+
source: 'vehicle.vehicle.wheelchairAccessible',
|
|
116
|
+
default: null,
|
|
117
|
+
},
|
|
56
118
|
{
|
|
57
119
|
name: 'timestamp',
|
|
58
120
|
type: 'varchar(255)',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtfs",
|
|
3
|
-
"version": "4.10.
|
|
3
|
+
"version": "4.10.3",
|
|
4
4
|
"description": "Import GTFS transit data into SQLite and query routes, stops, times, fares and more",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"transit",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@turf/helpers": "^6.5.0",
|
|
80
|
-
"better-sqlite3": "^
|
|
80
|
+
"better-sqlite3": "^10.0.0",
|
|
81
81
|
"csv-parse": "^5.5.5",
|
|
82
82
|
"csv-stringify": "^6.4.6",
|
|
83
83
|
"gtfs-realtime-bindings": "^1.1.1",
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* eslint-env mocha */
|
|
2
|
+
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
|
|
5
|
+
import config from '../test-config.js';
|
|
6
|
+
import { deleteDb, openDb, importGtfs } from '../../index.js';
|
|
7
|
+
|
|
8
|
+
const db2Config = {
|
|
9
|
+
agencies: [
|
|
10
|
+
{
|
|
11
|
+
...config.agencies[0],
|
|
12
|
+
exclude: ['shapes'],
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
verbose: false,
|
|
16
|
+
sqlitePath: './tmpdb2',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const db3Config = {
|
|
20
|
+
agencies: [
|
|
21
|
+
{
|
|
22
|
+
...config.agencies[0],
|
|
23
|
+
exclude: ['shapes'],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
verbose: false,
|
|
27
|
+
sqlitePath: './tmpdb3',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
describe('openDb():', () => {
|
|
31
|
+
before(async () => {});
|
|
32
|
+
|
|
33
|
+
after(() => {
|
|
34
|
+
// Delete extra databases
|
|
35
|
+
fs.rmSync(db2Config.sqlitePath, { force: true });
|
|
36
|
+
fs.rmSync(db3Config.sqlitePath, { force: true });
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should allow deleting a database', async () => {
|
|
40
|
+
const db2 = openDb(db2Config);
|
|
41
|
+
await importGtfs(db2Config);
|
|
42
|
+
|
|
43
|
+
const db3 = openDb(db3Config);
|
|
44
|
+
await importGtfs(db3Config);
|
|
45
|
+
|
|
46
|
+
db2.name.should.equal('./tmpdb2');
|
|
47
|
+
db3.name.should.equal('./tmpdb3');
|
|
48
|
+
|
|
49
|
+
fs.existsSync(db2Config.sqlitePath).should.equal(true);
|
|
50
|
+
fs.existsSync(db3Config.sqlitePath).should.equal(true);
|
|
51
|
+
|
|
52
|
+
deleteDb(db2);
|
|
53
|
+
|
|
54
|
+
fs.existsSync(db2Config.sqlitePath).should.equal(false);
|
|
55
|
+
fs.existsSync(db3Config.sqlitePath).should.equal(true);
|
|
56
|
+
|
|
57
|
+
deleteDb(db3);
|
|
58
|
+
|
|
59
|
+
fs.existsSync(db2Config.sqlitePath).should.equal(false);
|
|
60
|
+
fs.existsSync(db3Config.sqlitePath).should.equal(false);
|
|
61
|
+
});
|
|
62
|
+
});
|