Skip to content

Commit 54aff02

Browse files
author
Landon Reed
authored
Merge pull request #141 from conveyal/some-stuff
Export improvements, proper schedule_exception handling and more tests
2 parents f943ea6 + 7450569 commit 54aff02

32 files changed

+1163
-637
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ language: java
44
jdk:
55
- oraclejdk8
66

7+
addons:
8+
postgresql: "9.6"
9+
710
# Replace Travis's default Maven installation step with a no-op.
811
# This avoids redundantly pre-running 'mvn install -DskipTests' every time.
912
install: true

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ A gtfs-lib GTFSFeed object should faithfully represent the contents of a single
1616

1717
## Usage
1818

19-
gtfs-lib can be used as a Java library or run via the command line.
19+
gtfs-lib can be used as a Java library or run via the command line. If using this library with PostgreSQL for persistence, you must use at least version 9.6 of PostgreSQL.
2020

2121
### Library (maven)
2222

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.conveyal.gtfs.loader;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
import java.sql.PreparedStatement;
7+
import java.sql.SQLException;
8+
9+
/**
10+
* Avoid Java's "effectively final" nonsense when using prepared statements in foreach loops.
11+
* Automatically push execute batches of prepared statements before the batch gets too big.
12+
* TODO there's probably something like this in an Apache Commons util library
13+
*/
14+
public class BatchTracker {
15+
private static final Logger LOG = LoggerFactory.getLogger(BatchTracker.class);
16+
17+
private final String recordType;
18+
private PreparedStatement preparedStatement;
19+
private int currentBatchSize = 0;
20+
private int totalRecordsProcessed = 0;
21+
22+
public BatchTracker(String recordType, PreparedStatement preparedStatement) {
23+
this.preparedStatement = preparedStatement;
24+
this.recordType = recordType;
25+
}
26+
27+
public void addBatch() throws SQLException {
28+
preparedStatement.addBatch();
29+
currentBatchSize += 1;
30+
if (currentBatchSize > JdbcGtfsLoader.INSERT_BATCH_SIZE) {
31+
preparedStatement.executeBatch();
32+
totalRecordsProcessed += currentBatchSize;
33+
currentBatchSize = 0;
34+
}
35+
}
36+
37+
public void executeRemaining() throws SQLException {
38+
if (currentBatchSize > 0) {
39+
totalRecordsProcessed += currentBatchSize;
40+
preparedStatement.executeBatch();
41+
currentBatchSize = 0;
42+
}
43+
// Avoid reuse, signal that this was cleanly closed.
44+
preparedStatement = null;
45+
LOG.info(String.format("Inserted %d %s records", totalRecordsProcessed, recordType));
46+
}
47+
48+
public void finalize () {
49+
if (preparedStatement != null || currentBatchSize > 0) {
50+
throw new RuntimeException("BUG: It looks like someone did not call executeRemaining on a BatchTracker.");
51+
}
52+
}
53+
}

src/main/java/com/conveyal/gtfs/loader/DoubleField.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.conveyal.gtfs.loader;
22

3-
import com.conveyal.gtfs.error.NewGTFSErrorType;
43
import com.conveyal.gtfs.storage.StorageException;
54

65
import java.sql.JDBCType;
@@ -17,13 +16,17 @@
1716
public class DoubleField extends Field {
1817

1918
private double minValue;
20-
2119
private double maxValue;
20+
// This field dictates how many decimal places this field should be rounded to when exporting to a GTFS.
21+
// The place where the rounding happens during exports is in Table.commaSeparatedNames.
22+
// A value less than 0 indicates that no rounding should happen.
23+
private int outputPrecision;
2224

23-
public DoubleField (String name, Requirement requirement, double minValue, double maxValue) {
25+
public DoubleField (String name, Requirement requirement, double minValue, double maxValue, int outputPrecision) {
2426
super(name, requirement);
2527
this.minValue = minValue;
2628
this.maxValue = maxValue;
29+
this.outputPrecision = outputPrecision;
2730
}
2831

2932
private double validate(String string) {
@@ -63,4 +66,20 @@ public String getSqlTypeName () {
6366
return "double precision";
6467
}
6568

69+
/**
70+
* When outputting to csv, round fields that have been created with an outputPrecision > -1 to avoid excessive
71+
* precision.
72+
*/
73+
@Override
74+
public String getColumnExpression(String prefix, boolean csvOutput) {
75+
String columnName = super.getColumnExpression(prefix, csvOutput);
76+
if (!csvOutput || this.outputPrecision < 0) return columnName;
77+
return String.format(
78+
"round(%s::DECIMAL, %d) as %s",
79+
columnName,
80+
this.outputPrecision,
81+
name
82+
);
83+
}
84+
6685
}

src/main/java/com/conveyal/gtfs/loader/Field.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,13 @@ public Field permitEmptyValue () {
140140
public boolean isEmptyValuePermitted() {
141141
return this.emptyValuePermitted;
142142
}
143+
144+
/**
145+
* Get the expression used to select this column from the database based on the prefix. The csvOutput parameter is
146+
* needed in overriden method implementations that have special ways of outputting certain fields. The prefix
147+
* parameter is assumed to be either null or a string in the format: `schema.`
148+
*/
149+
public String getColumnExpression(String prefix, boolean csvOutput) {
150+
return prefix != null ? String.format("%s%s", prefix, name) : name;
151+
}
143152
}

0 commit comments

Comments
 (0)