#nullable enable using Best.HTTP; using Cysharp.Threading.Tasks; using System; using System.Collections.Generic; using UnityEngine; using UVC.Data; using UVC.Network; namespace UVC.Factory.Playback { public class PlaybackRepository { private PlaybackSQLiteService? sqliteService = null; /// /// 서버에서 재생 목록 날짜 리스트를 요청합니다. /// /// 예시: /// /// var repo = new PlaybackRepository(); /// var dateList = await repo.RequestPlaybackDateList(); /// if (dateList != null) /// { /// foreach (var date in dateList.Keys) /// { /// Debug.Log($"날짜: {date}"); /// } /// } /// /// /// 성공 시 날짜별 재생 목록 딕셔너리, 실패 시 null public async UniTask>?> RequestPlaybackDateList() { //local //string path = System.IO.Path.Combine(Application.streamingAssetsPath, "playbackList.json"); //string json = System.IO.File.ReadAllText(path); //HttpResponseModel>> localData = JsonHelper.FromJson>>>(json); //return new EntityWithState>>(APIState.Loaded, localData.data); try { return await UniTask.RunOnThreadPool>?>(async () => { var response = await HttpRequester.RequestGet>>>(URLList.Get("playbackList")); if (response.message.ToLower() == "success") { return new Dictionary>(response.data); } return null; }); } catch (Exception e) { Debug.Log($"Exception {e.ToString()}"); return null; } } /// /// 서버에서 재생 데이터 파일을 다운로드합니다. /// /// 예시: /// /// var repo = new PlaybackRepository(); /// string fileName = "sample.db"; /// string savePath = Application.persistentDataPath + "/sample.db"; /// repo.DownloadPlaybackData( /// fileName, /// savePath, /// (current, total) => Debug.Log($"{current}/{total} bytes 다운로드 중"), /// () => Debug.Log("다운로드 완료"), /// (error) => Debug.LogError($"다운로드 실패: {error}") /// ); /// /// /// 다운로드할 파일명 /// 저장 경로 /// 다운로드 진행 콜백 (현재, 전체 바이트) /// 다운로드 완료 콜백 /// 다운로드 실패 콜백 (에러 메시지) /// 다운로드 요청 객체(필요시 Abort 등 제어 가능), 실패 시 null public HTTPRequest? DownloadPlaybackData(string fileName, string savePath, Action OnProgress, Action OnComplete, Action OnError) { try { return HttpRequester.Download($"{URLList.Get("playbackFile")}/{fileName}", savePath, OnComplete, OnProgress, OnError); } catch (Exception e) { Debug.Log($"Exception {e.ToString()}"); return null; } } /// /// selectTime보다 ±second 사이의 데이터를 조회합니다. selectTime, second 포함. /// /// 예시: /// /// var repo = new PlaybackRepository(); /// string date = "2024-07-29"; /// string sqlFileName = "sample.db"; /// string selectTime = "2024-07-29T12:00:00.000Z"; /// int second = 10; /// var list = await repo.SelectBySecondAsync(date, sqlFileName, selectTime, second, true, 5); /// foreach (var entity in list) /// { /// Debug.Log($"데이터: {entity.data}, 시간: {entity.timestamp}"); /// } /// /// /// 폴더명(날짜 등) /// SQLite 파일명 /// yyyy-MM-ddTHH:mm:ss.fffZ 형식의 기준 시간 /// ±초(양수: 미래, 음수: 과거) /// true: 오래된 시간부터, false: 최근 시간부터 /// 최대 조회 개수(0이면 제한 없음) /// 조회된 데이터 리스트 public async UniTask> SelectBySecondAsync(string date, string sqlFileName, string selectTime, int second, bool orderAsc = true, int limit = 0) { validationSqliteService(date, sqlFileName); return await sqliteService!.SelectBySecond(selectTime, second, orderAsc, limit); } /// /// baseInfo 테이블에서 selectTime보다 ±second 사이의 데이터를 조회합니다. selectTime, second 포함. /// /// 예시: /// /// var repo = new PlaybackRepository(); /// string date = "2024-07-29"; /// string sqlFileName = "sample.db"; /// string selectTime = "2024-07-29T12:00:00.000Z"; /// int second = -5; /// var list = await repo.SelectBySecondBaseInfo(date, sqlFileName, selectTime, second, false, 1); /// foreach (var entity in list) /// { /// Debug.Log($"데이터: {entity.data}, 시간: {entity.timestamp}"); /// } /// /// /// 폴더명(날짜 등) /// SQLite 파일명 /// yyyy-MM-ddTHH:mm:ss.fffZ 형식의 기준 시간 /// ±초(양수: 미래, 음수: 과거) /// true: 오래된 시간부터, false: 최근 시간부터 /// 최대 조회 개수 /// 조회된 데이터 리스트 public async UniTask> SelectBySecondBaseInfo(string date, string sqlFileName, string selectTime, int second = 59, bool orderAsc = true, int limit = 1) { validationSqliteService(date, sqlFileName); return await sqliteService!.SelectBySecondBaseInfo(selectTime, second, orderAsc, limit); } /// /// 내부적으로 SQLite 서비스가 올바른 파일에 연결되어 있는지 확인하고, 필요시 재연결합니다. /// /// 예시: /// /// // 일반적으로 직접 호출할 필요 없음(내부에서 자동 호출) /// validationSqliteService("2024-07-29", "sample.db"); /// /// /// 폴더명(날짜 등) /// SQLite 파일명 private void validationSqliteService(string date, string sqlFileName) { if (sqliteService == null) sqliteService = new PlaybackSQLiteService(); if (sqliteService.Connected) { if (sqliteService.Date != date || sqliteService.SqliteFileName != sqlFileName) { sqliteService.CloseDB(); } } sqliteService.Connect(date, sqlFileName); } } }