Files
rog_app/lib/utils/database_helper.dart
2024-09-02 21:25:19 +09:00

368 lines
12 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:gifunavi/model/destination.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import '../model/rog.dart';
class DatabaseHelper {
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database? _database;
Future<Database> get database async => _database ??= await _initDatabase();
// データベース初期化:
//
// シングルトンパターンを使用してDatabaseHelperのインスタンスを管理しています。
// _initDatabase()メソッドでデータベースを初期化し、必要なテーブルを作成します。
//
Future<Database> _initDatabase() async {
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, 'rog.db');
// return await openDatabase(
// path,
// version: 1,
// onCreate: _onCreate,
// );
return openDatabase(
join(
await getDatabasesPath(),
'rog.db',
),
version: 1,
onCreate: _onCreate);
}
// DBを初期化する際に、必要なテーブルを作成します。
//
Future _onCreate(Database db, int version) async {
// destinationテーブル: 目的地の情報を保存(位置、名前、住所、連絡先情報など)。
await db.execute('''
CREATE TABLE destination(
location_id INTEGER PRIMARY KEY,
name TEXT,
address TEXT,
phone TEXT,
email TEXT,
webcontents TEXT,
videos TEXT,
category TEXT,
series INTEGER,
lat REAL,
lon REAL,
list_order INTEGER,
photos TEXT,
checkin_radious REAL,
sub_loc_id TEXT,
auto_checkin INTEGER,
selected INTEGER,
checkedin INTEGER,
cp REAL,
checkin_point REAL,
buy_point REAL,
hidden_location INTEGER,
checkin_image TEXT,
buypoint_image TEXT,
forced_checkin INTEGER,
recipt_times INTEGER,
tags TEXT
)
''');
// rogainingテーブル: ロゲイニングorienteering的なアクティビティの記録を保存。
await db.execute('''
CREATE TABLE rogaining(
rog_id INTEGER PRIMARY KEY AUTOINCREMENT,
course_id INTEGER,
location_id INTEGER,
user_id INTEGER,
lat REAL,
lon REAL,
time_stamp INTEGER,
image TEXT
)
''');
// rogテーブル: ロゲイニングのチェックポイント情報を保存。
await db.execute('''
CREATE TABLE rog(
id INTEGER PRIMARY KEY AUTOINCREMENT,
team_name TEXT,
event_code TEXT,
user_id INTEGER,
cp_number INTEGER,
checkintime INTEGER,
image TEXT,
rog_action_type INTEGER
)
''');
}
Future<List<Rog>> allRogianing() async {
Database db = await instance.database;
var rog = await db.query('rog');
List<Rog> roglist =
rog.isNotEmpty ? rog.map((e) => Rog.fromMap(e)).toList() : [];
//print("--------- $rog");
return roglist;
}
Future<List<Rog>> getRogainingByLatLon(double lat, double lon) async {
Database db = await instance.database;
var rog = await db.query('rog', where: "lat = $lat and lon= $lon");
List<Rog> roglist =
rog.isNotEmpty ? rog.map((e) => Rog.fromMap(e)).toList() : [];
return roglist;
}
Future clearSelection() async {
Database db = await instance.database;
Map<String, dynamic> rowClear = {"selected": false};
return await db.update("destination", rowClear);
}
Future<int> toggleSelecttion(Destination dest) async {
Database db = await instance.database;
bool val = !dest.selected!;
Map<String, dynamic> rowTarget = {"selected": val};
await clearSelection();
return await db.update("destination", rowTarget,
where: 'location_id = ?', whereArgs: [dest.location_id!]);
}
Future<int> deleteRogaining(int id) async {
Database db = await instance.database;
var rog = await db.delete('rog', where: "id = $id");
int ret = rog > 0 ? rog : -1;
return ret;
}
Future<void> deleteAllRogaining() async {
Database db = await instance.database;
await db.delete('rog');
}
Future<void> deleteAllRogainingExceptToday() async {
Database db = await instance.database;
// 今日の開始時刻をエポックミリ秒で取得
final now = DateTime.now();
final startOfDay = DateTime(now.year, now.month, now.day).millisecondsSinceEpoch;
// 今日チェックインしたもの以外を削除
await db.delete(
'rog',
where: 'checkintime < ?',
whereArgs: [startOfDay]
);
}
Future<bool> isRogAlreadyAvailable(int id) async {
Database db = await instance.database;
var rog = await db.query('rog', where: "id = $id");
return rog.isNotEmpty ? true : false;
}
Future<int?> latestGoal() async {
Database db = await instance.database;
return Sqflite.firstIntValue(
await db.rawQuery('SELECT MAX(checkintime) FROM rog'));
}
Future<int> insertRogaining(Rog rog) async {
Database db = await instance.database;
int? nextOrder =
Sqflite.firstIntValue(await db.rawQuery('SELECT MAX(id) FROM rog'));
nextOrder = nextOrder ?? 0;
nextOrder = nextOrder + 1;
rog.id = nextOrder;
int res = await db.insert(
'rog',
rog.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
//print("------ database helper insert $res-----------::::::::");
return res;
}
Future<List<Destination>> getDestinations() async {
Database db = await instance.database;
var dest = await db.query('destination', orderBy: 'list_order');
List<Destination> destList =
dest.isNotEmpty ? dest.map((e) => Destination.fromMap(e)).toList() : [];
//print("--------- $destList");
return destList;
}
Future<List<Destination>> getDestinationById(int id) async {
Database db = await instance.database;
var rog = await db.query('destination', where: "location_id = $id");
List<Destination> deslist =
rog.isNotEmpty ? rog.map((e) => Destination.fromMap(e)).toList() : [];
return deslist;
}
Future<List<Destination>> getDestinationByLatLon(
double lat, double lon) async {
Database db = await instance.database;
var dest = await db.query('destination',
where: "lat = $lat and lon= $lon", orderBy: 'list_order');
List<Destination> destList =
dest.isNotEmpty ? dest.map((e) => Destination.fromMap(e)).toList() : [];
return destList;
}
Future<int> deleteDestination(int locationId) async {
Database db = await instance.database;
var dest =
await db.delete('destination', where: "location_id = $locationId");
int ret = dest > 0 ? dest : -1;
//after deleting set correct order
await setOrder();
return ret;
}
Future<void> setOrder() async {
Database db = await instance.database;
var byOrder = await db.query('destination', orderBy: 'list_order');
List<Destination> desDb = byOrder.isNotEmpty
? byOrder.map((e) => Destination.fromMap(e)).toList()
: [];
int order = 1;
for (Destination d in desDb) {
Map<String, dynamic> rowTarget = {"list_order": order};
await db.update("destination", rowTarget,
where: 'location_id = ?', whereArgs: [d.location_id]);
order += 1;
}
}
Future<void> deleteAllDestinations() async {
Database db = await instance.database;
await db.delete('destination');
}
Future<void> deleteAllDestinationsExceptTodayCheckins() async {
Database db = await instance.database;
// 今日の開始時刻をエポックからのミリ秒で取得
final now = DateTime.now();
final startOfDay = DateTime(now.year, now.month, now.day).millisecondsSinceEpoch;
// 今日チェックインされ、buy_pointを持つ目的地を除いて全て削除
await db.rawDelete('''
DELETE FROM destination
WHERE location_id NOT IN (
SELECT d.location_id
FROM destination d
JOIN rog r ON d.location_id = r.cp_number
WHERE date(r.checkintime / 1000, 'unixepoch', 'localtime') = date('now', 'localtime')
AND d.buy_point > 0
AND d.checkedin = 1
)
''', [startOfDay]);
}
Future<bool> isAlreadyAvailable(int locationId) async {
Database db = await instance.database;
var dest =
await db.query('destination', where: "location_id = $locationId");
return dest.isNotEmpty ? true : false;
}
Future<int> insertDestination(Destination dest) async {
await deleteDestination(dest.location_id!);
Database db = await instance.database;
int? nextOrder = Sqflite.firstIntValue(
await db.rawQuery('SELECT MAX(list_order) FROM destination'));
nextOrder = nextOrder ?? 0;
nextOrder = nextOrder + 1;
dest.list_order = nextOrder;
int res = await db.insert(
'destination',
dest.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
//print("------ database helper insert ${dest.toMap()}-----------::::::::");
return res;
}
Future<int> updateCancelBuyPoint(Destination destination) async {
//print("---- updating puypint image in db -----");
Database db = await instance.database;
Map<String, dynamic> row = {"buy_point": 0};
return await db.update("destination", row,
where: 'location_id = ?', whereArgs: [destination.location_id!]);
}
Future<int> updateBuyPoint(Destination destination, String imageUrl) async {
//print("---- updating puypint image in db -----");
Database db = await instance.database;
Map<String, dynamic> row = {"buypoint_image": imageUrl};
return await db.update("destination", row,
where: 'location_id = ?', whereArgs: [destination.location_id!]);
}
Future<int> updateAction(Destination destination, bool checkin) async {
Database db = await instance.database;
int act = checkin == false ? 0 : 1;
Map<String, dynamic> row = {"checkedin": act};
return await db.update("destination", row,
where: 'location_id = ?', whereArgs: [destination.location_id!]);
}
Future<void> updateOrder(Destination d, int dir) async {
Database db = await instance.database;
var target = await db.query('destination',
where: "list_order = ${d.list_order! + dir}");
var dest =
await db.query('destination', where: "location_id = ${d.location_id}");
// print("--- target in db is $target");
// print("--- destine in db is $dest");
if (target.isNotEmpty) {
List<Destination> targetIndb = target.isNotEmpty
? target.map((e) => Destination.fromMap(e)).toList()
: [];
List<Destination> destIndb = dest.isNotEmpty
? dest.map((e) => Destination.fromMap(e)).toList()
: [];
Map<String, dynamic> rowTarget = {"list_order": d.list_order};
Map<String, dynamic> rowDes = {
"list_order": destIndb[0].list_order! + dir
};
// print("--- target destination is ${target_indb[0].location_id}");
// print("--- destine destination is is ${dest_indb[0].location_id}");
await db.update("destination", rowTarget,
where: 'location_id = ?', whereArgs: [targetIndb[0].location_id]);
await db.update("destination", rowDes,
where: 'location_id = ?', whereArgs: [destIndb[0].location_id]);
}
}
// Future<int?> getPending() async{
// Database db = await instance.database;
// return await Sqflite.firstIntValue(await db.rawQuery("SELECT COUNT(*) FROM incidents"));
// }
}