gtfs 4.15.7 → 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",
@@ -2524,7 +2453,7 @@ var tripUpdates = {
2524
2453
  extension: "gtfs-realtime",
2525
2454
  schema: [
2526
2455
  {
2527
- name: "update_id",
2456
+ name: "id",
2528
2457
  type: "text",
2529
2458
  required: true,
2530
2459
  primary: true,
@@ -2688,7 +2617,7 @@ var vehiclePositions = {
2688
2617
  extension: "gtfs-realtime",
2689
2618
  schema: [
2690
2619
  {
2691
- name: "update_id",
2620
+ name: "id",
2692
2621
  type: "text",
2693
2622
  required: true,
2694
2623
  primary: true,
@@ -2927,39 +2856,24 @@ var deadheadTimes = {
2927
2856
  nonstandard: true,
2928
2857
  extension: "ods",
2929
2858
  schema: [
2930
- {
2931
- name: "id",
2932
- type: "integer",
2933
- primary: true,
2934
- prefix: true
2935
- },
2936
2859
  {
2937
2860
  name: "deadhead_id",
2938
2861
  type: "text",
2939
2862
  required: true,
2940
2863
  index: true,
2864
+ primary: true,
2941
2865
  prefix: true
2942
2866
  },
2943
2867
  {
2944
2868
  name: "arrival_time",
2945
- type: "text",
2869
+ type: "time",
2946
2870
  required: true
2947
2871
  },
2948
- {
2949
- name: "arrival_timestamp",
2950
- type: "integer",
2951
- index: true
2952
- },
2953
2872
  {
2954
2873
  name: "departure_time",
2955
- type: "text",
2874
+ type: "time",
2956
2875
  required: true
2957
2876
  },
2958
- {
2959
- name: "departure_timestamp",
2960
- type: "integer",
2961
- index: true
2962
- },
2963
2877
  {
2964
2878
  name: "ops_location_id",
2965
2879
  type: "text",
@@ -2974,6 +2888,7 @@ var deadheadTimes = {
2974
2888
  name: "location_sequence",
2975
2889
  type: "integer",
2976
2890
  required: true,
2891
+ primary: true,
2977
2892
  min: 0,
2978
2893
  index: true
2979
2894
  },
@@ -3352,6 +3267,9 @@ function padLeadingZeros(time) {
3352
3267
  }
3353
3268
  return split.join(":");
3354
3269
  }
3270
+ function getTimestampColumnName(columnName) {
3271
+ return columnName.endsWith("time") ? `${columnName}stamp` : `${columnName}_timestamp`;
3272
+ }
3355
3273
 
3356
3274
  // src/lib/import-gtfs-realtime.ts
3357
3275
  function getNestedProperty(obj, defaultValue, path3) {
@@ -3566,35 +3484,22 @@ async function updateGtfsRealtimeData(task) {
3566
3484
  }
3567
3485
 
3568
3486
  // src/lib/import-gtfs.ts
3569
- var dateCache = {};
3570
- var calculateAndCacheDate = (value) => {
3571
- const cached = dateCache[value];
3572
- if (cached != null) {
3487
+ var timeCache = {};
3488
+ var formatAndCacheTime = (value) => {
3489
+ const cached = timeCache[value];
3490
+ if (cached !== void 0) {
3573
3491
  return cached;
3574
3492
  }
3575
- const seconds = calculateSecondsFromMidnight(value);
3576
- const date = padLeadingZeros(value);
3577
- const computed = [seconds, date];
3578
- dateCache[value] = computed;
3493
+ const timeAsSecondsFromMidnight = calculateSecondsFromMidnight(value);
3494
+ const timeAsString = padLeadingZeros(value);
3495
+ const computed = [timeAsSecondsFromMidnight, timeAsString];
3496
+ timeCache[value] = computed;
3579
3497
  return computed;
3580
3498
  };
3581
3499
  var getTextFiles = async (folderPath) => {
3582
3500
  const files = await readdir(folderPath);
3583
3501
  return files.filter((filename) => filename.slice(-3) === "txt");
3584
3502
  };
3585
- var TIME_COLUMN_NAMES = [
3586
- "start_time",
3587
- "end_time",
3588
- "arrival_time",
3589
- "departure_time",
3590
- "prior_notice_last_time",
3591
- "prior_notice_start_time",
3592
- "start_pickup_drop_off_window"
3593
- ];
3594
- var TIME_COLUMN_PAIRS = TIME_COLUMN_NAMES.map((name) => [
3595
- name,
3596
- name.endsWith("time") ? `${name}stamp` : `${name}_timestamp`
3597
- ]);
3598
3503
  var downloadGtfsFiles = async (task) => {
3599
3504
  if (!task.url) {
3600
3505
  throw new Error("No `url` specified in config");
@@ -3672,7 +3577,8 @@ var createGtfsTables = (db) => {
3672
3577
  if (!model.schema) {
3673
3578
  return;
3674
3579
  }
3675
- const columns = model.schema.map((column) => {
3580
+ const sqlColumnCreateStatements = [];
3581
+ for (const column of model.schema) {
3676
3582
  const checks = [];
3677
3583
  if (column.min !== void 0 && column.max) {
3678
3584
  checks.push(
@@ -3687,8 +3593,7 @@ var createGtfsTables = (db) => {
3687
3593
  checks.push(
3688
3594
  `(TYPEOF(${column.name}) = 'integer' OR ${column.name} IS NULL)`
3689
3595
  );
3690
- }
3691
- if (column.type === "real") {
3596
+ } else if (column.type === "real") {
3692
3597
  checks.push(
3693
3598
  `(TYPEOF(${column.name}) = 'real' OR ${column.name} IS NULL)`
3694
3599
  );
@@ -3697,17 +3602,24 @@ var createGtfsTables = (db) => {
3697
3602
  const columnDefault = column.default ? "DEFAULT " + column.default : "";
3698
3603
  const columnCollation = column.nocase ? "COLLATE NOCASE" : "";
3699
3604
  const checkClause = checks.length > 0 ? `CHECK(${checks.join(" AND ")})` : "";
3700
- return `${column.name} ${column.type} ${checkClause} ${required} ${columnDefault} ${columnCollation}`;
3701
- });
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
+ }
3702
3614
  const primaryColumns = model.schema.filter((column) => column.primary);
3703
3615
  if (primaryColumns.length > 0) {
3704
- columns.push(
3705
- `PRIMARY KEY (${primaryColumns.map((column) => column.name).join(", ")})`
3616
+ sqlColumnCreateStatements.push(
3617
+ `PRIMARY KEY (${primaryColumns.map(({ name }) => name).join(", ")})`
3706
3618
  );
3707
3619
  }
3708
3620
  db.prepare(`DROP TABLE IF EXISTS ${model.filenameBase};`).run();
3709
3621
  db.prepare(
3710
- `CREATE TABLE ${model.filenameBase} (${columns.join(", ")});`
3622
+ `CREATE TABLE ${model.filenameBase} (${sqlColumnCreateStatements.join(", ")});`
3711
3623
  ).run();
3712
3624
  }
3713
3625
  };
@@ -3716,10 +3628,18 @@ var createGtfsIndexes = (db) => {
3716
3628
  if (!model.schema) {
3717
3629
  return;
3718
3630
  }
3719
- for (const column of model.schema.filter((column2) => column2.index)) {
3720
- db.prepare(
3721
- `CREATE INDEX idx_${model.filenameBase}_${column.name} ON ${model.filenameBase} (${column.name});`
3722
- ).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
+ }
3723
3643
  }
3724
3644
  }
3725
3645
  };
@@ -3728,11 +3648,13 @@ var formatGtfsLine = (line, model, totalLineCount) => {
3728
3648
  const formattedLine = {};
3729
3649
  const filenameBase = model.filenameBase;
3730
3650
  const filenameExtension = model.filenameExtension;
3731
- for (const columnSchema of model.schema) {
3732
- const { name, type, required, min, max } = columnSchema;
3651
+ for (const { name, type, required } of model.schema) {
3733
3652
  let value = line[name];
3734
3653
  if (value === "" || value === void 0 || value === null) {
3735
3654
  formattedLine[name] = null;
3655
+ if (type === "time") {
3656
+ formattedLine[getTimestampColumnName(name)] = null;
3657
+ }
3736
3658
  if (required) {
3737
3659
  throw new Error(
3738
3660
  `Missing required value in ${filenameBase}.${filenameExtension} for ${name} on line ${lineNumber}.`
@@ -3747,17 +3669,13 @@ var formatGtfsLine = (line, model, totalLineCount) => {
3747
3669
  `Invalid date in ${filenameBase}.${filenameExtension} for ${name} on line ${lineNumber}.`
3748
3670
  );
3749
3671
  }
3672
+ } else if (type === "time") {
3673
+ const [timeAsSecondsFromMidnight, timeAsString] = formatAndCacheTime(value);
3674
+ value = timeAsString;
3675
+ formattedLine[getTimestampColumnName(name)] = timeAsSecondsFromMidnight ?? null;
3750
3676
  }
3751
3677
  formattedLine[name] = value;
3752
3678
  }
3753
- for (const [timeColumnName, timestampColumnName] of TIME_COLUMN_PAIRS) {
3754
- const value = formattedLine[timeColumnName];
3755
- if (value) {
3756
- const [seconds, date] = calculateAndCacheDate(value);
3757
- formattedLine[timestampColumnName] = seconds;
3758
- formattedLine[timeColumnName] = date;
3759
- }
3760
- }
3761
3679
  return formattedLine;
3762
3680
  };
3763
3681
  var BATCH_SIZE = 1e5;
@@ -3784,12 +3702,23 @@ var importGtfsFiles = (db, task) => mapSeries2(
3784
3702
  return;
3785
3703
  }
3786
3704
  task.log(`Importing - ${filename}\r`);
3787
- const columns = model.schema.filter((column) => column.name !== "id");
3788
- const placeholder = columns.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
+ });
3789
3718
  const prefixedColumns = new Set(
3790
- columns.filter((col) => col.prefix).map((col) => col.name)
3719
+ columns.filter((column) => column.prefix).map((column) => column.name)
3791
3720
  );
3792
- const prepareStatement = `INSERT ${task.ignoreDuplicates ? "OR IGNORE" : ""} INTO ${model.filenameBase} (${columns.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(", ")})`;
3793
3722
  const insert = db.prepare(prepareStatement);
3794
3723
  const insertLines = db.transaction((lines) => {
3795
3724
  for (const [rowNumber, line] of Object.entries(lines)) {
@@ -3809,7 +3738,7 @@ var importGtfsFiles = (db, task) => mapSeries2(
3809
3738
  }
3810
3739
  } catch (error) {
3811
3740
  if (error.code === "SQLITE_CONSTRAINT_PRIMARYKEY") {
3812
- const primaryColumns = model.schema.filter(
3741
+ const primaryColumns = columns.filter(
3813
3742
  (column) => column.primary
3814
3743
  );
3815
3744
  task.logWarning(