Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/main/java/org/mtransit/android/commons/data/Schedule.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.database.Cursor;
import android.text.TextUtils;

import androidx.annotation.Discouraged;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
Expand Down Expand Up @@ -464,6 +465,17 @@ public void setResetHeadsign() {
this.headsignValue = null;
}

@Discouraged(message = "should call getHeadsign()")
@Nullable
public String getHeadsignValue() {
return headsignValue;
}

@Discouraged(message = "should call setHeadsign()")
public void setHeadsignValue(@Nullable String headsignValue) {
this.headsignValue = headsignValue;
}

public boolean hasHeadsign() {
if (this.headsignType == Direction.HEADSIGN_TYPE_NO_PICKUP) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
@SuppressWarnings("WeakerAccess")
public class GTFSPOIProvider implements MTLog.Loggable {

private static final String TAG = GTFSPOIProvider.class.getSimpleName();
private static final String LOG_TAG = GTFSPOIProvider.class.getSimpleName();

@NonNull
@Override
public String getLogTag() {
return TAG;
return LOG_TAG;
}

public static void append(@NonNull UriMatcher uriMatcher, @NonNull String authority) {
Expand Down Expand Up @@ -125,15 +125,15 @@ public static Cursor getPOIFromDB(@NonNull GTFSProvider provider, @Nullable POIP
poiProjection = ArrayUtils.addAllNonNull(poiProjection, new String[]{POIProviderContract.Columns.T_POI_K_SCORE_META_OPT});
}
if (poiProjection.length != poiProjectionMap.size()) {
MTLog.w(TAG, "getPOIFromDB() > different projection sizes (%d VS %d)", poiProjection.length, poiProjectionMap.size());
MTLog.w(LOG_TAG, "getPOIFromDB() > different projection sizes (%d VS %d)", poiProjection.length, poiProjectionMap.size());
if (Constants.DEBUG) {
MTLog.w(TAG, "getPOIFromDB() > poiProjection: %d", poiProjection.length);
MTLog.w(LOG_TAG, "getPOIFromDB() > poiProjection: %d", poiProjection.length);
for (String string : poiProjection) {
MTLog.w(TAG, "getPOIFromDB() > poiProjection: - %s.", string);
MTLog.w(LOG_TAG, "getPOIFromDB() > poiProjection: - %s.", string);
}
MTLog.w(TAG, "getPOIFromDB() > poiProjectionMap: %d", poiProjectionMap.size());
MTLog.w(LOG_TAG, "getPOIFromDB() > poiProjectionMap: %d", poiProjectionMap.size());
for (Map.Entry<String, String> keyValue : poiProjectionMap.entrySet()) {
MTLog.w(TAG, "getPOIFromDB() > poiProjectionMap: - %s: %s.", keyValue.getKey(), keyValue.getValue());
MTLog.w(LOG_TAG, "getPOIFromDB() > poiProjectionMap: - %s: %s.", keyValue.getKey(), keyValue.getValue());
}
}
}
Expand All @@ -147,7 +147,7 @@ public static Cursor getPOIFromDB(@NonNull GTFSProvider provider, @Nullable POIP
}
return qb.query(provider.getReadDB(), poiProjection, selection, null, groupBy, null, sortOrder, null);
} catch (Exception e) {
MTLog.w(TAG, e, "Error while loading POIs '%s'!", poiFilter);
MTLog.w(LOG_TAG, e, "Error while loading POIs '%s'!", poiFilter);
return null;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.mtransit.android.commons.provider;

import static org.mtransit.android.commons.provider.gtfs.GTFSProviderDBHelperUtils.initDbTableWithRetry;

import android.annotation.SuppressLint;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
Expand All @@ -8,7 +10,6 @@
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

import org.mtransit.android.commons.FileUtils;
import org.mtransit.android.commons.MTLog;
import org.mtransit.android.commons.NotificationUtils;
import org.mtransit.android.commons.PackageManagerUtils;
Expand All @@ -19,9 +20,10 @@
import org.mtransit.commons.GTFSCommons;
import org.mtransit.commons.sql.SQLUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import kotlin.Unit;

public class GTFSProviderDbHelper extends MTSQLiteOpenHelper {

Expand All @@ -38,13 +40,21 @@ public String getLogTag() {
*/
public static final String DB_NAME = "gtfs_rts.db"; // do not change to avoid breaking compat w/ old modules

static final String T_STRINGS = GTFSCommons.T_STRINGS;
static final String T_STRINGS_K_ID = GTFSCommons.T_STRINGS_K_ID;
static final String T_STRINGS_K_STRING = GTFSCommons.T_STRINGS_K_STRING;
private static final String T_STRINGS_SQL_CREATE = GTFSCommons.getT_STRINGS_SQL_CREATE();
private static final String T_STRINGS_SQL_INSERT = GTFSCommons.getT_STRINGS_SQL_INSERT();
private static final String T_STRINGS_SQL_DROP = GTFSCommons.getT_STRINGS_SQL_DROP();

static final String T_ROUTE = GTFSCommons.T_ROUTE;
static final String T_ROUTE_K_ID = GTFSCommons.T_ROUTE_K_ID;
static final String T_ROUTE_K_SHORT_NAME = GTFSCommons.T_ROUTE_K_SHORT_NAME;
static final String T_ROUTE_K_LONG_NAME = GTFSCommons.T_ROUTE_K_LONG_NAME;
static final String T_ROUTE_K_COLOR = GTFSCommons.T_ROUTE_K_COLOR;
static final String T_ROUTE_K_ORIGINAL_ID_HASH = GTFSCommons.T_ROUTE_K_ORIGINAL_ID_HASH;
static final String T_ROUTE_K_TYPE = GTFSCommons.T_ROUTE_K_TYPE;
private static final int[] T_ROUTE_STRINGS_COLUMN_IDX = GTFSCommons.T_ROUTE_STRINGS_COLUMN_IDX;
private static final String T_ROUTE_SQL_CREATE = GTFSCommons.getT_ROUTE_SQL_CREATE();
private static final String T_ROUTE_SQL_INSERT = GTFSCommons.getT_ROUTE_SQL_INSERT();
private static final String T_ROUTE_SQL_DROP = GTFSCommons.getT_ROUTE_SQL_DROP();
Expand All @@ -54,6 +64,7 @@ public String getLogTag() {
static final String T_DIRECTION_K_HEADSIGN_TYPE = GTFSCommons.T_DIRECTION_K_HEADSIGN_TYPE;
static final String T_DIRECTION_K_HEADSIGN_VALUE = GTFSCommons.T_DIRECTION_K_HEADSIGN_VALUE; // really?
static final String T_DIRECTION_K_ROUTE_ID = GTFSCommons.T_DIRECTION_K_ROUTE_ID;
private static final int[] T_DIRECTION_STRINGS_COLUMN_IDX = GTFSCommons.T_DIRECTION_STRINGS_COLUMN_IDX;
private static final String T_DIRECTION_SQL_CREATE = GTFSCommons.getT_DIRECTION_SQL_CREATE();
private static final String T_DIRECTION_SQL_INSERT = GTFSCommons.getT_DIRECTION_SQL_INSERT();
private static final String T_DIRECTION_SQL_DROP = GTFSCommons.getT_DIRECTION_SQL_DROP();
Expand All @@ -66,6 +77,7 @@ public String getLogTag() {
static final String T_STOP_K_LNG = GTFSCommons.T_STOP_K_LNG;
static final String T_STOP_K_ACCESSIBLE = GTFSCommons.T_STOP_K_ACCESSIBLE;
static final String T_STOP_K_ORIGINAL_ID_HASH = GTFSCommons.T_STOP_K_ORIGINAL_ID_HASH;
private static final int[] T_STOP_STRINGS_COLUMN_IDX = GTFSCommons.T_STOP_STRINGS_COLUMN_IDX;
private static final String T_STOP_SQL_CREATE = GTFSCommons.getT_STOP_SQL_CREATE();
private static final String T_STOP_SQL_INSERT = GTFSCommons.getT_STOP_SQL_INSERT();
private static final String T_STOP_SQL_DROP = GTFSCommons.getT_STOP_SQL_DROP();
Expand Down Expand Up @@ -147,11 +159,12 @@ public boolean isDbExist(@NonNull Context context) {
return SqlUtils.isDbExist(context, DB_NAME);
}

@SuppressLint("MissingPermission") // no notification if not permitted (not requesting permission)
@SuppressLint("MissingPermission") // no notification if not permitted (not requesting permission for that)
private void initAllDbTables(@NonNull SQLiteDatabase db, boolean upgrade) {
MTLog.i(this, "Data: deploying DB...");
int nId = TimeUtils.currentTimeSec();
int nbTotalOperations = 7;
final int nId = TimeUtils.currentTimeSec();
final int nbTotalOperations = 8;
int progress = 0;
final NotificationManagerCompat nm = NotificationManagerCompat.from(this.context);
final boolean notifEnabled = nm.areNotificationsEnabled();
final NotificationCompat.Builder nb;
Expand All @@ -167,96 +180,40 @@ private void initAllDbTables(@NonNull SQLiteDatabase db, boolean upgrade) {
nb = null;
}
db.execSQL(SQLUtils.PRAGMA_AUTO_VACUUM_NONE);
if (notifEnabled) {
NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, 0);
}
initDbTableWithRetry(db, T_ROUTE, T_ROUTE_SQL_CREATE, T_ROUTE_SQL_INSERT, T_ROUTE_SQL_DROP, getRouteFiles());
if (notifEnabled) {
NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, 1);
}
initDbTableWithRetry(db, T_DIRECTION, T_DIRECTION_SQL_CREATE, T_DIRECTION_SQL_INSERT, T_DIRECTION_SQL_DROP, getDirectionFiles());
if (notifEnabled) {
NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, 2);
}
initDbTableWithRetry(db, T_STOP, T_STOP_SQL_CREATE, T_STOP_SQL_INSERT, T_STOP_SQL_DROP, getStopFiles());
if (notifEnabled) {
NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, 3);
}
initDbTableWithRetry(db, T_DIRECTION_STOPS, T_DIRECTION_STOPS_SQL_CREATE, T_DIRECTION_STOPS_SQL_INSERT, T_DIRECTION_STOPS_SQL_DROP, getDirectionStopsFiles());
if (notifEnabled) {
NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, 4);
}
initDbTableWithRetry(db, T_SERVICE_IDS, T_SERVICE_IDS_SQL_CREATE, T_SERVICE_IDS_SQL_INSERT, T_SERVICE_IDS_SQL_DROP, getServiceIdsFiles());
if (notifEnabled) {
NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, 5);
if (notifEnabled) NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, progress++);
final Map<Integer, String> allStrings = new HashMap<>();
if (FeatureFlags.F_EXPORT_STRINGS) {
initDbTableWithRetry(context, db, T_STRINGS, T_STRINGS_SQL_CREATE, T_STRINGS_SQL_INSERT, T_STRINGS_SQL_DROP, getStringsFiles(), null, null,
(id, string) -> {
allStrings.put(id, string);
return Unit.INSTANCE;
}
); // 1st
}
initDbTableWithRetry(db, T_SERVICE_DATES, T_SERVICE_DATES_SQL_CREATE, T_SERVICE_DATES_SQL_INSERT, T_SERVICE_DATES_SQL_DROP, getServiceDatesFiles());
if (notifEnabled) {
NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, 6);
if (notifEnabled) NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, progress++);
initDbTableWithRetry(context, db, T_ROUTE, T_ROUTE_SQL_CREATE, T_ROUTE_SQL_INSERT, T_ROUTE_SQL_DROP, getRouteFiles(), allStrings, T_ROUTE_STRINGS_COLUMN_IDX);
if (notifEnabled) NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, progress++);
initDbTableWithRetry(context, db, T_DIRECTION, T_DIRECTION_SQL_CREATE, T_DIRECTION_SQL_INSERT, T_DIRECTION_SQL_DROP, getDirectionFiles(), allStrings, T_DIRECTION_STRINGS_COLUMN_IDX);
if (notifEnabled) NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, progress++);
initDbTableWithRetry(context, db, T_STOP, T_STOP_SQL_CREATE, T_STOP_SQL_INSERT, T_STOP_SQL_DROP, getStopFiles(), allStrings, T_STOP_STRINGS_COLUMN_IDX);
if (notifEnabled) NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, progress++);
initDbTableWithRetry(context, db, T_DIRECTION_STOPS, T_DIRECTION_STOPS_SQL_CREATE, T_DIRECTION_STOPS_SQL_INSERT, T_DIRECTION_STOPS_SQL_DROP, getDirectionStopsFiles());
if (notifEnabled) NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, progress++);
if (FeatureFlags.F_EXPORT_SERVICE_ID_INTS) {
initDbTableWithRetry(context, db, T_SERVICE_IDS, T_SERVICE_IDS_SQL_CREATE, T_SERVICE_IDS_SQL_INSERT, T_SERVICE_IDS_SQL_DROP, getServiceIdsFiles());
}
if (notifEnabled) NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, progress++);
initDbTableWithRetry(context, db, T_SERVICE_DATES, T_SERVICE_DATES_SQL_CREATE, T_SERVICE_DATES_SQL_INSERT, T_SERVICE_DATES_SQL_DROP, getServiceDatesFiles());
if (notifEnabled) NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, progress++);
db.execSQL(T_ROUTE_DIRECTION_STOP_STATUS_SQL_CREATE);
if (notifEnabled) {
nb.setSmallIcon(android.R.drawable.stat_notify_sync_noanim); //
NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, 7);
NotificationUtils.setProgressAndNotify(nm, nb, nId, nbTotalOperations, progress);
nm.cancel(nId);
}
MTLog.i(this, "Data: deploying DB... DONE");
}

private void initDbTableWithRetry(@NonNull SQLiteDatabase db, String table, String sqlCreate, String sqlInsert, String sqlDrop, int[] files) {
boolean success;
do {
try {
success = initDbTable(db, table, sqlCreate, sqlInsert, sqlDrop, files);
} catch (Exception e) {
MTLog.w(this, e, "Error while deploying DB table %s!", table);
success = false;
}
} while (!success);
}

private boolean initDbTable(@NonNull SQLiteDatabase db, String table, String sqlCreate, String sqlInsert, String sqlDrop, int[] files) {
try {
db.beginTransaction();
db.execSQL(sqlDrop); // drop if exists
db.execSQL(sqlCreate); // create if not exists
String line;
BufferedReader br = null;
InputStreamReader isr = null;
InputStream is = null;
for (int file : files) {
try {
is = this.context.getResources().openRawResource(file);
isr = new InputStreamReader(is, FileUtils.getUTF8());
br = new BufferedReader(isr, 8192);
while ((line = br.readLine()) != null) {
String sql = String.format(sqlInsert, line);
try {
db.execSQL(sql);
} catch (Exception e) {
MTLog.w(this, e, "ERROR while executing '%s' on database '%s' table '%s' file '%s'!", sql, DB_NAME, table, file);
throw e;
}
}
} catch (Exception e) {
MTLog.w(this, e, "ERROR while copying the database '%s' table '%s' file '%s'!", DB_NAME, table, file);
return false;
} finally {
FileUtils.closeQuietly(br);
FileUtils.closeQuietly(isr);
FileUtils.closeQuietly(is);
}
}
db.setTransactionSuccessful();
return true;
} catch (Exception e) {
MTLog.w(this, e, "ERROR while copying the database '%s' table '%s' file!", DB_NAME, table);
return false;
} finally {
SqlUtils.endTransactionQuietly(db);
}
}

/**
* Override if multiple {@link GTFSProviderDbHelper} implementations in same app.
*/
Expand All @@ -272,6 +229,21 @@ private int[] getServiceIdsFiles() {
}
}

/**
* Override if multiple {@link GTFSProviderDbHelper} implementations in same app.
*/
private int[] getStringsFiles() {
if (GTFSCurrentNextProvider.hasCurrentData(context)) {
if (GTFSCurrentNextProvider.isNextData(context)) {
return new int[]{R.raw.next_gtfs_strings};
} else { // CURRENT = default
return new int[]{R.raw.current_gtfs_strings};
}
} else {
return new int[]{R.raw.gtfs_strings};
}
}

/**
* Override if multiple {@link GTFSProviderDbHelper} implementations in same app.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@

public class GTFSRDSProvider implements MTLog.Loggable {

private static final String TAG = GTFSRDSProvider.class.getSimpleName();
private static final String LOG_TAG = GTFSRDSProvider.class.getSimpleName();

@NonNull
@Override
public String getLogTag() {
return TAG;
return LOG_TAG;
}

protected static final int ROUTES = 1;
Expand Down Expand Up @@ -223,13 +223,13 @@ public static Cursor queryS(@NonNull GTFSProvider provider, @NonNull Uri uri, @N
if (TextUtils.isEmpty(sortOrder)) {
sortOrder = provider.getSortOrder(uri);
}
Cursor cursor = qb.query(provider.getReadDB(), projection, selection, selectionArgs, null, null, sortOrder, null);
final Cursor cursor = qb.query(provider.getReadDB(), projection, selection, selectionArgs, null, null, sortOrder, null);
if (cursor != null) {
cursor.setNotificationUri(provider.requireContextCompat().getContentResolver(), uri);
}
return cursor;
} catch (Exception e) {
MTLog.w(TAG, e, "Error while resolving query '%s'!", uri);
MTLog.w(LOG_TAG, e, "Error while resolving query '%s'!", uri);
return null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
import org.mtransit.android.commons.data.Schedule;
import org.mtransit.android.commons.data.ScheduleTimestamps;
import org.mtransit.android.commons.provider.agency.AgencyUtils;
import org.mtransit.commons.FeatureFlags;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

Expand Down Expand Up @@ -48,7 +49,7 @@ static ScheduleTimestamps getScheduleTimestamps(@NonNull GTFSProvider provider,
final TimeZone timeZone = TimeZone.getTimeZone(AgencyUtils.getRDSAgencyTimeZone(context));
final Calendar startsAt = TimeUtils.getNewCalendar(timeZone, startsAtInMs);
startsAt.add(Calendar.DATE, -1); // starting yesterday
HashSet<Schedule.Timestamp> dayTimestamps;
Set<Schedule.Timestamp> dayTimestamps;
String lookupDayTime;
String lookupDayDate;
int dataRequests = 0;
Expand Down Expand Up @@ -106,6 +107,9 @@ static ScheduleTimestamps getScheduleTimestamps(@NonNull GTFSProvider provider,
}
startsAt.add(Calendar.DATE, +1); // NEXT DAY
}
if (FeatureFlags.F_EXPORT_STRINGS) {
allTimestamps = GTFSStringsUtils.updateStrings(allTimestamps, provider);
}
ScheduleTimestamps scheduleTimestamps = new ScheduleTimestamps(rds.getUUID(), startsAtInMs, endsAtInMs);
scheduleTimestamps.setSourceLabel(GTFSProvider.getSOURCE_LABEL(provider.requireContextCompat()));
scheduleTimestamps.setTimestampsAndSort(allTimestamps);
Expand Down
Loading