gtfs 4.15.8 → 4.15.9

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.
@@ -360,12 +360,7 @@ var bookingRules = {
360
360
  },
361
361
  {
362
362
  name: "prior_notice_last_time",
363
- type: "text"
364
- },
365
- {
366
- name: "prior_notice_last_timestamp",
367
- type: "integer",
368
- index: true
363
+ type: "time"
369
364
  },
370
365
  {
371
366
  name: "prior_notice_start_day",
@@ -374,12 +369,7 @@ var bookingRules = {
374
369
  },
375
370
  {
376
371
  name: "prior_notice_start_time",
377
- type: "text"
378
- },
379
- {
380
- name: "prior_notice_start_timestamp",
381
- type: "integer",
382
- index: true
372
+ type: "time"
383
373
  },
384
374
  {
385
375
  name: "prior_notice_service_id",
@@ -845,23 +835,15 @@ var frequencies = {
845
835
  },
846
836
  {
847
837
  name: "start_time",
848
- type: "text",
838
+ type: "time",
849
839
  required: true,
850
840
  primary: true
851
841
  },
852
- {
853
- name: "start_timestamp",
854
- type: "integer"
855
- },
856
842
  {
857
843
  name: "end_time",
858
- type: "text",
844
+ type: "time",
859
845
  required: true
860
846
  },
861
- {
862
- name: "end_timestamp",
863
- type: "integer"
864
- },
865
847
  {
866
848
  name: "headway_secs",
867
849
  type: "integer",
@@ -1228,21 +1210,11 @@ var stopTimes = {
1228
1210
  },
1229
1211
  {
1230
1212
  name: "arrival_time",
1231
- type: "text"
1232
- },
1233
- {
1234
- name: "arrival_timestamp",
1235
- type: "integer",
1236
- index: true
1213
+ type: "time"
1237
1214
  },
1238
1215
  {
1239
1216
  name: "departure_time",
1240
- type: "text"
1241
- },
1242
- {
1243
- name: "departure_timestamp",
1244
- type: "integer",
1245
- index: true
1217
+ type: "time"
1246
1218
  },
1247
1219
  {
1248
1220
  name: "location_group_id",
@@ -1277,12 +1249,7 @@ var stopTimes = {
1277
1249
  },
1278
1250
  {
1279
1251
  name: "start_pickup_drop_off_window",
1280
- type: "text"
1281
- },
1282
- {
1283
- name: "start_pickup_drop_off_window_timestamp",
1284
- type: "integer",
1285
- index: true
1252
+ type: "time"
1286
1253
  },
1287
1254
  {
1288
1255
  name: "pickup_type",
@@ -1432,12 +1399,12 @@ var timeframes = {
1432
1399
  },
1433
1400
  {
1434
1401
  name: "start_time",
1435
- type: "text",
1402
+ type: "time",
1436
1403
  primary: true
1437
1404
  },
1438
1405
  {
1439
1406
  name: "end_time",
1440
- type: "text",
1407
+ type: "time",
1441
1408
  primary: true
1442
1409
  },
1443
1410
  {
@@ -1710,19 +1677,11 @@ var timetables = {
1710
1677
  },
1711
1678
  {
1712
1679
  name: "start_time",
1713
- type: "text"
1714
- },
1715
- {
1716
- name: "start_timestamp",
1717
- type: "integer"
1680
+ type: "time"
1718
1681
  },
1719
1682
  {
1720
1683
  name: "end_time",
1721
- type: "text"
1722
- },
1723
- {
1724
- name: "end_timestamp",
1725
- type: "integer"
1684
+ type: "time"
1726
1685
  },
1727
1686
  {
1728
1687
  name: "timetable_label",
@@ -2162,21 +2121,11 @@ var boardAlight = {
2162
2121
  },
2163
2122
  {
2164
2123
  name: "service_arrival_time",
2165
- type: "text"
2166
- },
2167
- {
2168
- name: "service_arrival_timestamp",
2169
- type: "integer",
2170
- index: true
2124
+ type: "time"
2171
2125
  },
2172
2126
  {
2173
2127
  name: "service_departure_time",
2174
- type: "text"
2175
- },
2176
- {
2177
- name: "service_departure_timestamp",
2178
- type: "integer",
2179
- index: true
2128
+ type: "time"
2180
2129
  },
2181
2130
  {
2182
2131
  name: "source",
@@ -2243,21 +2192,11 @@ var riderTrip = {
2243
2192
  },
2244
2193
  {
2245
2194
  name: "boarding_time",
2246
- type: "text"
2247
- },
2248
- {
2249
- name: "boarding_timestamp",
2250
- type: "integer",
2251
- index: true
2195
+ type: "time"
2252
2196
  },
2253
2197
  {
2254
2198
  name: "alighting_time",
2255
- type: "text"
2256
- },
2257
- {
2258
- name: "alighting_timestamp",
2259
- type: "integer",
2260
- index: true
2199
+ type: "time"
2261
2200
  },
2262
2201
  {
2263
2202
  name: "rider_type",
@@ -2331,21 +2270,11 @@ var ridership = {
2331
2270
  },
2332
2271
  {
2333
2272
  name: "ridership_start_time",
2334
- type: "text"
2335
- },
2336
- {
2337
- name: "ridership_start_timestamp",
2338
- type: "integer",
2339
- index: true
2273
+ type: "time"
2340
2274
  },
2341
2275
  {
2342
2276
  name: "ridership_end_time",
2343
- type: "text"
2344
- },
2345
- {
2346
- name: "ridership_end_timestamp",
2347
- type: "integer",
2348
- index: true
2277
+ type: "time"
2349
2278
  },
2350
2279
  {
2351
2280
  name: "service_id",
@@ -2937,24 +2866,14 @@ var deadheadTimes = {
2937
2866
  },
2938
2867
  {
2939
2868
  name: "arrival_time",
2940
- type: "text",
2869
+ type: "time",
2941
2870
  required: true
2942
2871
  },
2943
- {
2944
- name: "arrival_timestamp",
2945
- type: "integer",
2946
- index: true
2947
- },
2948
2872
  {
2949
2873
  name: "departure_time",
2950
- type: "text",
2874
+ type: "time",
2951
2875
  required: true
2952
2876
  },
2953
- {
2954
- name: "departure_timestamp",
2955
- type: "integer",
2956
- index: true
2957
- },
2958
2877
  {
2959
2878
  name: "ops_location_id",
2960
2879
  type: "text",
@@ -3348,6 +3267,9 @@ function padLeadingZeros(time) {
3348
3267
  }
3349
3268
  return split.join(":");
3350
3269
  }
3270
+ function getTimestampColumnName(columnName) {
3271
+ return columnName.endsWith("time") ? `${columnName}stamp` : `${columnName}_timestamp`;
3272
+ }
3351
3273
 
3352
3274
  // src/lib/import-gtfs-realtime.ts
3353
3275
  function getNestedProperty(obj, defaultValue, path3) {
@@ -3562,35 +3484,22 @@ async function updateGtfsRealtimeData(task) {
3562
3484
  }
3563
3485
 
3564
3486
  // src/lib/import-gtfs.ts
3565
- var dateCache = {};
3566
- var calculateAndCacheDate = (value) => {
3567
- const cached = dateCache[value];
3568
- if (cached != null) {
3487
+ var timeCache = {};
3488
+ var formatAndCacheTime = (value) => {
3489
+ const cached = timeCache[value];
3490
+ if (cached !== void 0) {
3569
3491
  return cached;
3570
3492
  }
3571
- const seconds = calculateSecondsFromMidnight(value);
3572
- const date = padLeadingZeros(value);
3573
- const computed = [seconds, date];
3574
- dateCache[value] = computed;
3493
+ const timeAsSecondsFromMidnight = calculateSecondsFromMidnight(value);
3494
+ const timeAsString = padLeadingZeros(value);
3495
+ const computed = [timeAsSecondsFromMidnight, timeAsString];
3496
+ timeCache[value] = computed;
3575
3497
  return computed;
3576
3498
  };
3577
3499
  var getTextFiles = async (folderPath) => {
3578
3500
  const files = await readdir(folderPath);
3579
3501
  return files.filter((filename) => filename.slice(-3) === "txt");
3580
3502
  };
3581
- var TIME_COLUMN_NAMES = [
3582
- "start_time",
3583
- "end_time",
3584
- "arrival_time",
3585
- "departure_time",
3586
- "prior_notice_last_time",
3587
- "prior_notice_start_time",
3588
- "start_pickup_drop_off_window"
3589
- ];
3590
- var TIME_COLUMN_PAIRS = TIME_COLUMN_NAMES.map((name) => [
3591
- name,
3592
- name.endsWith("time") ? `${name}stamp` : `${name}_timestamp`
3593
- ]);
3594
3503
  var downloadGtfsFiles = async (task) => {
3595
3504
  if (!task.url) {
3596
3505
  throw new Error("No `url` specified in config");
@@ -3668,7 +3577,8 @@ var createGtfsTables = (db) => {
3668
3577
  if (!model.schema) {
3669
3578
  return;
3670
3579
  }
3671
- const columns = model.schema.map((column) => {
3580
+ const sqlColumnCreateStatements = [];
3581
+ for (const column of model.schema) {
3672
3582
  const checks = [];
3673
3583
  if (column.min !== void 0 && column.max) {
3674
3584
  checks.push(
@@ -3683,8 +3593,7 @@ var createGtfsTables = (db) => {
3683
3593
  checks.push(
3684
3594
  `(TYPEOF(${column.name}) = 'integer' OR ${column.name} IS NULL)`
3685
3595
  );
3686
- }
3687
- if (column.type === "real") {
3596
+ } else if (column.type === "real") {
3688
3597
  checks.push(
3689
3598
  `(TYPEOF(${column.name}) = 'real' OR ${column.name} IS NULL)`
3690
3599
  );
@@ -3693,17 +3602,24 @@ var createGtfsTables = (db) => {
3693
3602
  const columnDefault = column.default ? "DEFAULT " + column.default : "";
3694
3603
  const columnCollation = column.nocase ? "COLLATE NOCASE" : "";
3695
3604
  const checkClause = checks.length > 0 ? `CHECK(${checks.join(" AND ")})` : "";
3696
- return `${column.name} ${column.type} ${checkClause} ${required} ${columnDefault} ${columnCollation}`;
3697
- });
3605
+ sqlColumnCreateStatements.push(
3606
+ `${column.name} ${column.type} ${checkClause} ${required} ${columnDefault} ${columnCollation}`
3607
+ );
3608
+ if (column.type === "time") {
3609
+ sqlColumnCreateStatements.push(
3610
+ `${getTimestampColumnName(column.name)} INTEGER`
3611
+ );
3612
+ }
3613
+ }
3698
3614
  const primaryColumns = model.schema.filter((column) => column.primary);
3699
3615
  if (primaryColumns.length > 0) {
3700
- columns.push(
3701
- `PRIMARY KEY (${primaryColumns.map((column) => column.name).join(", ")})`
3616
+ sqlColumnCreateStatements.push(
3617
+ `PRIMARY KEY (${primaryColumns.map(({ name }) => name).join(", ")})`
3702
3618
  );
3703
3619
  }
3704
3620
  db.prepare(`DROP TABLE IF EXISTS ${model.filenameBase};`).run();
3705
3621
  db.prepare(
3706
- `CREATE TABLE ${model.filenameBase} (${columns.join(", ")});`
3622
+ `CREATE TABLE ${model.filenameBase} (${sqlColumnCreateStatements.join(", ")});`
3707
3623
  ).run();
3708
3624
  }
3709
3625
  };
@@ -3712,10 +3628,18 @@ var createGtfsIndexes = (db) => {
3712
3628
  if (!model.schema) {
3713
3629
  return;
3714
3630
  }
3715
- for (const column of model.schema.filter((column2) => column2.index)) {
3716
- db.prepare(
3717
- `CREATE INDEX idx_${model.filenameBase}_${column.name} ON ${model.filenameBase} (${column.name});`
3718
- ).run();
3631
+ for (const column of model.schema) {
3632
+ if (column.index) {
3633
+ db.prepare(
3634
+ `CREATE INDEX idx_${model.filenameBase}_${column.name} ON ${model.filenameBase} (${column.name});`
3635
+ ).run();
3636
+ }
3637
+ if (column.type === "time") {
3638
+ const timestampColumnName = getTimestampColumnName(column.name);
3639
+ db.prepare(
3640
+ `CREATE INDEX idx_${model.filenameBase}_${timestampColumnName} ON ${model.filenameBase} (${timestampColumnName});`
3641
+ ).run();
3642
+ }
3719
3643
  }
3720
3644
  }
3721
3645
  };
@@ -3724,11 +3648,13 @@ var formatGtfsLine = (line, model, totalLineCount) => {
3724
3648
  const formattedLine = {};
3725
3649
  const filenameBase = model.filenameBase;
3726
3650
  const filenameExtension = model.filenameExtension;
3727
- for (const columnSchema of model.schema) {
3728
- const { name, type, required, min, max } = columnSchema;
3651
+ for (const { name, type, required } of model.schema) {
3729
3652
  let value = line[name];
3730
3653
  if (value === "" || value === void 0 || value === null) {
3731
3654
  formattedLine[name] = null;
3655
+ if (type === "time") {
3656
+ formattedLine[getTimestampColumnName(name)] = null;
3657
+ }
3732
3658
  if (required) {
3733
3659
  throw new Error(
3734
3660
  `Missing required value in ${filenameBase}.${filenameExtension} for ${name} on line ${lineNumber}.`
@@ -3743,17 +3669,13 @@ var formatGtfsLine = (line, model, totalLineCount) => {
3743
3669
  `Invalid date in ${filenameBase}.${filenameExtension} for ${name} on line ${lineNumber}.`
3744
3670
  );
3745
3671
  }
3672
+ } else if (type === "time") {
3673
+ const [timeAsSecondsFromMidnight, timeAsString] = formatAndCacheTime(value);
3674
+ value = timeAsString;
3675
+ formattedLine[getTimestampColumnName(name)] = timeAsSecondsFromMidnight ?? null;
3746
3676
  }
3747
3677
  formattedLine[name] = value;
3748
3678
  }
3749
- for (const [timeColumnName, timestampColumnName] of TIME_COLUMN_PAIRS) {
3750
- const value = formattedLine[timeColumnName];
3751
- if (value) {
3752
- const [seconds, date] = calculateAndCacheDate(value);
3753
- formattedLine[timestampColumnName] = seconds;
3754
- formattedLine[timeColumnName] = date;
3755
- }
3756
- }
3757
3679
  return formattedLine;
3758
3680
  };
3759
3681
  var BATCH_SIZE = 1e5;
@@ -3780,11 +3702,23 @@ var importGtfsFiles = (db, task) => mapSeries2(
3780
3702
  return;
3781
3703
  }
3782
3704
  task.log(`Importing - ${filename}\r`);
3783
- const placeholder = model.schema.map(({ name }) => `@${name}`).join(", ");
3705
+ const columns = model.schema.flatMap((column) => {
3706
+ if (column.type === "time") {
3707
+ return [
3708
+ column,
3709
+ {
3710
+ name: getTimestampColumnName(column.name),
3711
+ type: "integer",
3712
+ index: true
3713
+ }
3714
+ ];
3715
+ }
3716
+ return column;
3717
+ });
3784
3718
  const prefixedColumns = new Set(
3785
- model.schema.filter((column) => column.prefix).map((column) => column.name)
3719
+ columns.filter((column) => column.prefix).map((column) => column.name)
3786
3720
  );
3787
- const prepareStatement = `INSERT ${task.ignoreDuplicates ? "OR IGNORE" : ""} INTO ${model.filenameBase} (${model.schema.map((column) => column.name).join(", ")}) VALUES (${placeholder})`;
3721
+ const prepareStatement = `INSERT ${task.ignoreDuplicates ? "OR IGNORE" : ""} INTO ${model.filenameBase} (${columns.map(({ name }) => name).join(", ")}) VALUES (${columns.map(({ name }) => `@${name}`).join(", ")})`;
3788
3722
  const insert = db.prepare(prepareStatement);
3789
3723
  const insertLines = db.transaction((lines) => {
3790
3724
  for (const [rowNumber, line] of Object.entries(lines)) {
@@ -3804,7 +3738,7 @@ var importGtfsFiles = (db, task) => mapSeries2(
3804
3738
  }
3805
3739
  } catch (error) {
3806
3740
  if (error.code === "SQLITE_CONSTRAINT_PRIMARYKEY") {
3807
- const primaryColumns = model.schema.filter(
3741
+ const primaryColumns = columns.filter(
3808
3742
  (column) => column.primary
3809
3743
  );
3810
3744
  task.logWarning(