Files
XRLib/Assets/Scripts/UVC/Factory/Playback/PlaybackSQLiteService.cs

169 lines
6.9 KiB
C#
Raw Normal View History

2025-07-28 19:59:35 +09:00
using Cysharp.Threading.Tasks;
2025-07-22 19:58:14 +09:00
using SQLite4Unity3d;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
2025-07-28 19:59:35 +09:00
using UVC.Factory.Playback;
2025-07-22 19:58:14 +09:00
using UVC.Util;
namespace UVC.Factory
{
public class PlaybackSQLiteService
{
//#region Singleton
//private static readonly SQLiteService instance = new SQLiteService();
//public static SQLiteService Instance => instance;
//static SQLiteService() { }
//#endregion
private SQLiteConnection dbConnection;
public bool Connected { get => dbConnection != null; }
private string date;
public string Date { get => date; }
private string sqliteFileName;
public string SqliteFileName { get => sqliteFileName; }
public void Connect(string date, string sqliteFileName)
{
this.date = date;
this.sqliteFileName = sqliteFileName;
2025-07-28 19:59:35 +09:00
dbConnection = new SQLiteConnection(Path.Combine(PlaybackService.PlaybackFolderPath, date, sqliteFileName));
2025-07-22 19:58:14 +09:00
}
public void CloseDB()
{
dbConnection.Close();
dbConnection = null;
}
/// <summary>
/// 추가하기
/// </summary>
/// <param name="data"></param>
/// <param name="timeStamp">yyyy-MM-ddTHH:mm:ss.fffZ format string</param>
/// <param name="temp"></param>
/// <returns>데이터베이스에서 추가된 행 수</returns>
public int Insert(string data, string timeStamp, string temp = null)
{
var query = $"INSERT INTO realTime (data, timestamp, temp) VALUES ('{data}', '{timeStamp}', " + (temp == null ? "null" : "'" + temp + "'") + ");";
int changedRowLen = dbConnection.Execute(query);
return changedRowLen;
}
/// <summary>
/// selectTime보다 +- second 사이의 데이터 요청. selectTime, second 포함
/// second > 0 : selectTime <= data < selectTime + second
/// second < 0 : selectTime + second < data <= selectTime
/// </summary>
/// <param name="selectTime">yyyy-MM-ddTHH:mm:ss.fffZ format string</param>
/// <param name="second"></param>
/// <param name="orderAsc">true: 오래된 시간이 먼저, false: 최근 시간이 먼저</param>
/// <param name="limit"></param>
/// <returns></returns>
///
readonly string[] queryParts =
{
"SELECT * FROM realTime WHERE ",
"timestamp >= '",
"' AND timestamp < '",
"timestamp <= '",
"' AND timestamp > '",
" ORDER BY timestamp ",
" LIMIT ",
};
public async UniTask<List<PlaybackSQLiteDataEntity>> SelectBySecond(string selectTime, int second, bool orderAsc = true, int limit = 0)
{
2025-07-28 19:59:35 +09:00
bool isMainThread = PlayerLoopHelper.IsMainThread;
2025-07-22 19:58:14 +09:00
List<PlaybackSQLiteDataEntity> result = await UniTask.RunOnThreadPool(() =>
{
DateTime date = DateTimeUtil.UtcParse(selectTime).AddSeconds(second);
string targetTime = DateTimeUtil.FormatTime(date);
//Debug.Log($"SelectBySecondBaseInfo {selectTime} {second} {targetTime} {date}");
queryBuilder.Append(queryParts[0]);
//second가 selectTime 보다 더 미래면
if (second > 0)
{
queryBuilder.Append($"{queryParts[1]}{selectTime}{queryParts[2]}{targetTime}'");
}
else
{
//second가 selectTime 보다 더 과거면
queryBuilder.Append($"{queryParts[3]}{selectTime}{queryParts[4]}{targetTime}'");
}
queryBuilder.Append($"{queryParts[5]}{(orderAsc ? "asc" : "desc")}");
if (limit > 0)
queryBuilder.Append($"{queryParts[6]}{limit}");
queryBuilder.Append(";");
//Debug.Log($"SelectBySecond {query}");
var query = queryBuilder.ToString();
queryBuilder.Clear();
return dbConnection.Query<PlaybackSQLiteDataEntity>(query);
});
2025-07-28 19:59:35 +09:00
if (!isMainThread) await UniTask.SwitchToThreadPool();
2025-07-22 19:58:14 +09:00
return result;
}
/// <summary>
/// selectTime보다 +- second 사이의 데이터 요청. selectTime, second 포함
/// second > 0 : selectTime <= data < selectTime + second
/// second < 0 : selectTime + second < data <= selectTime
/// </summary>
/// <param name="selectTime">yyyy-MM-ddTHH:mm:ss.fffZ format string</param>
/// <param name="second"></param>
/// <param name="orderAsc">true: 오래된 시간이 먼저, false: 최근 시간이 먼저</param>
/// <param name="limit"></param>
/// <returns></returns>
///
StringBuilder queryBuilder = new();
public async UniTask<List<PlaybackSQLiteDataEntity>> SelectBySecondBaseInfo(string selectTime, int second, bool orderAsc = false, int limit = 1)
{
2025-07-28 19:59:35 +09:00
bool isMainThread = PlayerLoopHelper.IsMainThread;
2025-07-22 19:58:14 +09:00
List<PlaybackSQLiteDataEntity> result = await UniTask.RunOnThreadPool(() =>
{
DateTime date = DateTimeUtil.UtcParse(selectTime).AddSeconds(second);
string targetTime = DateTimeUtil.FormatTime(date);
//Debug.Log($"SelectBySecondBaseInfo {selectTime} {second} {targetTime} {date}");
queryBuilder.Append($"SELECT * FROM baseInfo WHERE ");
//second가 selectTime 보다 더 미래면
if (second > 0)
{
queryBuilder.Append($"timestamp >= '{selectTime}' AND timestamp < '{targetTime}'");
}
else
{
//second가 selectTime 보다 더 과거면
queryBuilder.Append($"timestamp <= '{selectTime}' AND timestamp > '{targetTime}'");
}
queryBuilder.Append($" ORDER BY timestamp {(orderAsc ? "asc" : "desc")}");
if (limit > 0) queryBuilder.Append($" LIMIT {limit}");
queryBuilder.Append(";");
//Debug.Log($"SelectBySecondBaseInfo {query}");
var query = queryBuilder.ToString();
queryBuilder.Clear();
return dbConnection.Query<PlaybackSQLiteDataEntity>(query);
});
2025-07-28 19:59:35 +09:00
if (!isMainThread) await UniTask.SwitchToThreadPool();
2025-07-22 19:58:14 +09:00
return result;
}
}
[System.Serializable]
public class PlaybackSQLiteDataEntity
{
public string data { get; set; }
[PrimaryKey]
public string timestamp { get; set; }
public DateTime timestampHungary { get => DateTimeUtil.UtcStringToKoreaDateTime(timestamp); }
public string temp { get; set; }
}
}