2019-06-27 17:29:40 -07:00
|
|
|
// https://github.com/tekartik/sqflite/blob/master/sqflite/doc/migration_example.md
|
2019-04-24 00:27:23 -07:00
|
|
|
import 'dart:io';
|
2019-07-25 09:26:13 -07:00
|
|
|
import 'dart:convert';
|
2019-04-24 00:27:23 -07:00
|
|
|
import 'package:path/path.dart';
|
|
|
|
import 'package:sqflite/sqflite.dart';
|
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
|
|
|
|
class DatabaseHelper {
|
2019-06-27 17:29:40 -07:00
|
|
|
static final String _databaseName = "LibreGpsParser.db";
|
|
|
|
static final int _databaseVersion = 4;
|
|
|
|
|
|
|
|
static final String table = 'gmaplocations';
|
|
|
|
static final String weatherTable = 'weather';
|
|
|
|
|
|
|
|
static final String columnMapLocation = 'mapLocation';
|
|
|
|
static final String columnLatLong = 'latLong';
|
|
|
|
static final String columnLnlTime = 'lnlTime';
|
|
|
|
static final String columnViewTime = 'viewTime';
|
|
|
|
static final String columnElev = 'elev';
|
|
|
|
static final String columnElevTime = 'elevTime';
|
|
|
|
static final String columnWeatherID = 'weatherID';
|
|
|
|
static final String columnTimeOffSet = 'timeOffSet';
|
|
|
|
static final String columnTimeOffSetTime = 'timeOffSetTime';
|
|
|
|
|
|
|
|
static final String columnWeatherWeatherID = 'weatherID';
|
|
|
|
static final String columnWeather = 'weather';
|
|
|
|
static final String columnWeatherForecast = 'weatherForecast';
|
|
|
|
static final String columnNotes = 'notes';
|
|
|
|
|
|
|
|
// is the timeOffSet automatically set by consulting teleport api
|
|
|
|
// (not manually set by spinner)
|
|
|
|
static final String columnIsAutoTimeOffset = 'isAutoTimeOffset';
|
2019-04-24 00:27:23 -07:00
|
|
|
|
|
|
|
// make this a singleton class
|
|
|
|
DatabaseHelper._privateConstructor();
|
|
|
|
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
|
|
|
|
|
|
|
|
// only have a single app-wide reference to the database
|
|
|
|
static Database _database;
|
|
|
|
Future<Database> get database async {
|
|
|
|
if (_database != null) return _database;
|
|
|
|
// lazily instantiate the db the first time it is accessed
|
|
|
|
_database = await _initDatabase();
|
|
|
|
return _database;
|
|
|
|
}
|
2019-06-27 17:29:40 -07:00
|
|
|
|
2019-04-24 00:27:23 -07:00
|
|
|
// this opens the database (and creates it if it doesn't exist)
|
|
|
|
_initDatabase() async {
|
|
|
|
Directory documentsDirectory = await getApplicationDocumentsDirectory();
|
2019-06-27 17:29:40 -07:00
|
|
|
String path = join(
|
|
|
|
documentsDirectory.path,
|
|
|
|
_databaseName
|
|
|
|
);
|
|
|
|
return await openDatabase(
|
|
|
|
path,
|
|
|
|
version: _databaseVersion,
|
|
|
|
onCreate: _onCreate,
|
|
|
|
onUpgrade: _onUpgrade,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// sqflite seems to be able to figure out the versions
|
|
|
|
// automatically?
|
|
|
|
// you can only ADD one column at a time?
|
|
|
|
Future _onUpgrade(Database db, int oldVersion, int newVersion) async {
|
|
|
|
if ((oldVersion == 1) || (oldVersion == 2)) {
|
|
|
|
await db.execute('''ALTER TABLE $table ADD $columnIsAutoTimeOffset INT''');
|
|
|
|
await db.execute('''ALTER TABLE $table ADD $columnNotes TEXT''');
|
|
|
|
} else if (oldVersion == 3) {
|
|
|
|
await db.execute('''ALTER TABLE $table ADD $columnNotes TEXT''');
|
|
|
|
}
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// SQL code to create the database table
|
|
|
|
Future _onCreate(Database db, int version) async {
|
|
|
|
await db.execute('''
|
|
|
|
CREATE TABLE $table (
|
|
|
|
$columnMapLocation VARCHAR UNIQUE,
|
|
|
|
$columnLatLong TEXT,
|
|
|
|
$columnLnlTime INT,
|
|
|
|
$columnViewTime INT,
|
|
|
|
$columnElev INT,
|
|
|
|
$columnElevTime INT,
|
2019-06-27 17:29:40 -07:00
|
|
|
$columnWeatherID INT,
|
|
|
|
$columnTimeOffSet INT,
|
|
|
|
$columnTimeOffSetTime INT,
|
|
|
|
$columnIsAutoTimeOffset INT,
|
|
|
|
$columnNotes TEXT
|
2019-04-24 00:27:23 -07:00
|
|
|
)
|
|
|
|
''');
|
|
|
|
await db.execute('''
|
|
|
|
CREATE TABLE $weatherTable (
|
2019-06-27 17:29:40 -07:00
|
|
|
$columnWeatherWeatherID INT UNIQUE ON CONFLICT REPLACE,
|
2019-04-24 00:27:23 -07:00
|
|
|
$columnWeather TEXT,
|
|
|
|
$columnWeatherForecast TEXT
|
|
|
|
)
|
|
|
|
''');
|
|
|
|
}
|
2019-06-27 17:29:40 -07:00
|
|
|
|
2019-04-24 00:27:23 -07:00
|
|
|
Future<int> insert(Map<String, dynamic> row) async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
return await db.insert(table, row);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<int> insertWeatherRow(Map<String, dynamic> row) async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
return await db.insert(weatherTable, row);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<List<Map<String, dynamic>>> queryAllRows() async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
return await db.query(table);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<int> queryRowCount() async {
|
|
|
|
Database db = await instance.database;
|
2019-06-27 17:29:40 -07:00
|
|
|
return Sqflite.firstIntValue(
|
|
|
|
await db.rawQuery('SELECT COUNT(*) FROM $table'));
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<int> queryRowExists(String mapLocation) async {
|
2019-06-27 17:29:40 -07:00
|
|
|
String depostrophedMapLocation = mapLocation.replaceAll('\'', '\'\'');
|
2019-04-24 00:27:23 -07:00
|
|
|
Database db = await instance.database;
|
2019-06-27 17:29:40 -07:00
|
|
|
return Sqflite.firstIntValue(await db.rawQuery(
|
|
|
|
'SELECT EXISTS (SELECT $columnMapLocation FROM $table WHERE $columnMapLocation=\'$depostrophedMapLocation\')'));
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<int> queryWeatherIDExists(int weatherID) async {
|
|
|
|
Database db = await instance.database;
|
2019-06-27 17:29:40 -07:00
|
|
|
return Sqflite.firstIntValue(await db.rawQuery(
|
|
|
|
'SELECT EXISTS (SELECT $columnWeatherWeatherID FROM $weatherTable WHERE $columnWeatherWeatherID=\'$weatherID\')'));
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<String> queryNewestMapLocation() async {
|
|
|
|
Database db = await instance.database;
|
2019-06-27 17:29:40 -07:00
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnMapLocation FROM $table ORDER BY $columnViewTime DESC LIMIT 1');
|
|
|
|
return (result.length == 0)
|
|
|
|
? 'Plataea\nGreece\nhttps://maps.app.goo.gl/1NW9z'
|
|
|
|
: result[0]['mapLocation'];
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
|
|
|
|
2019-06-27 17:29:40 -07:00
|
|
|
Future<String> querySecondNewestMapLocation() async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnMapLocation FROM $table ORDER BY $columnViewTime DESC LIMIT 2');
|
|
|
|
return (result.length == 2)
|
|
|
|
? result[1]['mapLocation']
|
|
|
|
: 'none';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-04-24 00:27:23 -07:00
|
|
|
Future<List<String>> sortedMapLocations() async {
|
|
|
|
Database db = await instance.database;
|
2019-06-27 17:29:40 -07:00
|
|
|
var result = await db.rawQuery(
|
|
|
|
'SELECT $columnMapLocation FROM $table ORDER BY $columnViewTime DESC');
|
|
|
|
List<String> resultList = List<String>();
|
2019-04-24 00:27:23 -07:00
|
|
|
for (var i = 0; i < result.length; i++) {
|
2019-06-27 17:29:40 -07:00
|
|
|
resultList.add(result[i]['mapLocation']);
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
2019-06-27 17:29:40 -07:00
|
|
|
return resultList;
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<String> queryLatNLong(String mapLocation) async {
|
|
|
|
Database db = await instance.database;
|
2019-06-27 17:29:40 -07:00
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnLatLong FROM $table WHERE $columnMapLocation = ?',
|
|
|
|
[mapLocation]);
|
2019-04-24 00:27:23 -07:00
|
|
|
return (result[0]['latLong'] == null) ? 'NA' : result[0]['latLong'];
|
|
|
|
}
|
|
|
|
|
2019-06-27 17:29:40 -07:00
|
|
|
Future<String> queryNotes(String mapLocation) async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnNotes FROM $table WHERE $columnMapLocation = ?',
|
|
|
|
[mapLocation]);
|
|
|
|
return result[0]['notes'] ?? '';
|
|
|
|
}
|
|
|
|
|
2019-04-24 00:27:23 -07:00
|
|
|
Future<String> queryWeather(int weatherID) async {
|
|
|
|
Database db = await instance.database;
|
2019-06-27 17:29:40 -07:00
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnWeather FROM $weatherTable WHERE $columnWeatherWeatherID = ?',
|
|
|
|
[weatherID]);
|
|
|
|
return (result.length > 0) ? result[0]['weather'] : 'NA';
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<String> queryWeatherForeCast(int weatherID) async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnWeatherForecast FROM $weatherTable WHERE $columnWeatherWeatherID = ?',
|
|
|
|
[weatherID]);
|
|
|
|
return result[0]['weatherForecast'] ?? 'NA';
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<int> queryElevation(String mapLocation) async {
|
|
|
|
Database db = await instance.database;
|
2019-06-27 17:29:40 -07:00
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnElev FROM $table WHERE $columnMapLocation = ?',
|
|
|
|
[mapLocation]);
|
2019-04-24 00:27:23 -07:00
|
|
|
return result[0]['elev'];
|
|
|
|
}
|
|
|
|
|
2019-06-27 17:29:40 -07:00
|
|
|
Future<int> queryIsAutoTimeOffSet(String mapLocation) async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnIsAutoTimeOffset FROM $table WHERE $columnMapLocation = ?',
|
|
|
|
[mapLocation]);
|
|
|
|
return result[0]['isAutoTimeOffset'] ?? 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<int> queryTimeOffSetTime(String mapLocation) async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnTimeOffSetTime FROM $table WHERE $columnMapLocation = ?',
|
|
|
|
[mapLocation]);
|
|
|
|
return result[0]['timeOffSetTime'] ??
|
|
|
|
-1; // returns -1 if result[0]['timeOffSetTime'] is null
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<int> queryTimeOffSet(String mapLocation) async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnTimeOffSet FROM $table WHERE $columnMapLocation = ?',
|
|
|
|
[mapLocation]);
|
|
|
|
return result[0]['timeOffSet'] ??
|
|
|
|
-1; // returns -1 if result[0]['timeOffSet'] is null
|
|
|
|
}
|
|
|
|
|
2019-04-24 00:27:23 -07:00
|
|
|
Future<int> queryWeatherID(String mapLocation) async {
|
|
|
|
Database db = await instance.database;
|
2019-06-27 17:29:40 -07:00
|
|
|
List<Map> result = await db.rawQuery(
|
|
|
|
'SELECT $columnWeatherID FROM $table WHERE $columnMapLocation = ?',
|
|
|
|
[mapLocation]);
|
2019-04-24 00:27:23 -07:00
|
|
|
return result[0]['weatherID'];
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<int> update(Map<String, dynamic> row) async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
String mapLocation = row[columnMapLocation];
|
2019-06-27 17:29:40 -07:00
|
|
|
return await db.update(table, row,
|
|
|
|
where: '$columnMapLocation = ?', whereArgs: [mapLocation]);
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<int> updateWeathTbl(Map<String, dynamic> row) async {
|
|
|
|
Database db = await instance.database;
|
|
|
|
int weatherID = row[columnWeatherWeatherID];
|
2019-06-27 17:29:40 -07:00
|
|
|
return await db.update(weatherTable, row,
|
|
|
|
where: '$columnWeatherWeatherID = ?', whereArgs: [weatherID]);
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<int> delete(String ml) async {
|
|
|
|
Database db = await instance.database;
|
2019-06-27 17:29:40 -07:00
|
|
|
return await db
|
|
|
|
.delete(table, where: '$columnMapLocation = ?', whereArgs: [ml]);
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|
2019-07-25 09:26:13 -07:00
|
|
|
|
|
|
|
Future<String> queryDBExport() async{
|
|
|
|
Database db = await instance.database;
|
|
|
|
List<Map> result = await db.rawQuery('SELECT $columnMapLocation,$columnNotes,$columnIsAutoTimeOffset,$columnTimeOffSet FROM $table');
|
|
|
|
return(jsonEncode(result));
|
|
|
|
}
|
2019-04-24 00:27:23 -07:00
|
|
|
}
|