..
This commit is contained in:
@@ -4,44 +4,61 @@ import 'package:drift/native.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
part 'ephemeral_database.g.dart'; // (나중에 생성될 파일)
|
||||
part 'ephemeral_database.g.dart';
|
||||
|
||||
// 테이블 정의: 미디어 메타데이터
|
||||
// 기존 MediaItems 테이블
|
||||
class MediaItems extends Table {
|
||||
TextColumn get id => text()(); // UUID
|
||||
TextColumn get id => text()();
|
||||
TextColumn get senderId => text()();
|
||||
TextColumn get senderName => text()();
|
||||
TextColumn get type => text()(); // 'IMAGE', 'VIDEO', 'AUDIO'
|
||||
TextColumn get filePath => text()(); // 로컬 저장 경로
|
||||
TextColumn get type => text()();
|
||||
TextColumn get filePath => text()();
|
||||
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||
|
||||
@override
|
||||
Set<Column> get primaryKey => {id};
|
||||
}
|
||||
|
||||
@DriftDatabase(tables: [MediaItems])
|
||||
// [추가] 패킷 로그 테이블 (재전송용)
|
||||
class PacketLogs extends Table {
|
||||
IntColumn get seq => integer()(); // 순번 (Primary Key)
|
||||
TextColumn get payload => text()(); // JSON 데이터
|
||||
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||
|
||||
@override
|
||||
Set<Column> get primaryKey => {seq};
|
||||
}
|
||||
|
||||
@DriftDatabase(tables: [MediaItems, PacketLogs]) // [수정] PacketLogs 추가
|
||||
class EphemeralDatabase extends _$EphemeralDatabase {
|
||||
// 싱글톤이 아닌 인스턴스로 관리 (방 만들 때 생성, 나갈 때 close)
|
||||
EphemeralDatabase(QueryExecutor e) : super(e);
|
||||
|
||||
@override
|
||||
int get schemaVersion => 1;
|
||||
int get schemaVersion => 2; // [수정] 버전 업 (기존 앱 삭제 후 설치 권장)
|
||||
|
||||
// 팩토리: 파일 기반 DB 생성
|
||||
static Future<EphemeralDatabase> create(String roomName) async {
|
||||
final dbFolder = await getApplicationDocumentsDirectory();
|
||||
// 방 이름이나 ID로 파일명 구분
|
||||
final file = File(p.join(dbFolder.path, 'room_$roomName.sqlite'));
|
||||
return EphemeralDatabase(NativeDatabase(file));
|
||||
}
|
||||
|
||||
// CRUD 쿼리
|
||||
Future<List<MediaItem>> getAllMedia() => select(mediaItems).get();
|
||||
Future<int> insertMedia(MediaItemsCompanion entry) => into(mediaItems).insert(entry);
|
||||
|
||||
// [핵심] 방 폭파 시 데이터 삭제
|
||||
// [추가] 패킷 저장
|
||||
Future<int> logPacket(int seq, String json) {
|
||||
return into(packetLogs).insert(PacketLogsCompanion(
|
||||
seq: Value(seq),
|
||||
payload: Value(json),
|
||||
));
|
||||
}
|
||||
|
||||
// [추가] 특정 범위의 패킷 가져오기 (재전송 요청 시 사용)
|
||||
Future<List<PacketLog>> getPacketsInRange(int fromSeq, int toSeq) {
|
||||
return (select(packetLogs)..where((tbl) => tbl.seq.isBetweenValues(fromSeq, toSeq))).get();
|
||||
}
|
||||
|
||||
Future<void> wipeData() async {
|
||||
await close(); // DB 연결 종료
|
||||
// 실제 파일 삭제 로직은 Manager에서 수행 (DB 파일 자체를 날림)
|
||||
await close();
|
||||
}
|
||||
}
|
||||
@@ -351,15 +351,229 @@ class MediaItemsCompanion extends UpdateCompanion<MediaItem> {
|
||||
}
|
||||
}
|
||||
|
||||
class $PacketLogsTable extends PacketLogs
|
||||
with TableInfo<$PacketLogsTable, PacketLog> {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
$PacketLogsTable(this.attachedDatabase, [this._alias]);
|
||||
static const VerificationMeta _seqMeta = const VerificationMeta('seq');
|
||||
@override
|
||||
late final GeneratedColumn<int> seq = GeneratedColumn<int>(
|
||||
'seq', aliasedName, false,
|
||||
type: DriftSqlType.int, requiredDuringInsert: false);
|
||||
static const VerificationMeta _payloadMeta =
|
||||
const VerificationMeta('payload');
|
||||
@override
|
||||
late final GeneratedColumn<String> payload = GeneratedColumn<String>(
|
||||
'payload', aliasedName, false,
|
||||
type: DriftSqlType.string, requiredDuringInsert: true);
|
||||
static const VerificationMeta _createdAtMeta =
|
||||
const VerificationMeta('createdAt');
|
||||
@override
|
||||
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
|
||||
'created_at', aliasedName, false,
|
||||
type: DriftSqlType.dateTime,
|
||||
requiredDuringInsert: false,
|
||||
defaultValue: currentDateAndTime);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [seq, payload, createdAt];
|
||||
@override
|
||||
String get aliasedName => _alias ?? actualTableName;
|
||||
@override
|
||||
String get actualTableName => $name;
|
||||
static const String $name = 'packet_logs';
|
||||
@override
|
||||
VerificationContext validateIntegrity(Insertable<PacketLog> instance,
|
||||
{bool isInserting = false}) {
|
||||
final context = VerificationContext();
|
||||
final data = instance.toColumns(true);
|
||||
if (data.containsKey('seq')) {
|
||||
context.handle(
|
||||
_seqMeta, seq.isAcceptableOrUnknown(data['seq']!, _seqMeta));
|
||||
}
|
||||
if (data.containsKey('payload')) {
|
||||
context.handle(_payloadMeta,
|
||||
payload.isAcceptableOrUnknown(data['payload']!, _payloadMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_payloadMeta);
|
||||
}
|
||||
if (data.containsKey('created_at')) {
|
||||
context.handle(_createdAtMeta,
|
||||
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta));
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {seq};
|
||||
@override
|
||||
PacketLog map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||
return PacketLog(
|
||||
seq: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.int, data['${effectivePrefix}seq'])!,
|
||||
payload: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.string, data['${effectivePrefix}payload'])!,
|
||||
createdAt: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
$PacketLogsTable createAlias(String alias) {
|
||||
return $PacketLogsTable(attachedDatabase, alias);
|
||||
}
|
||||
}
|
||||
|
||||
class PacketLog extends DataClass implements Insertable<PacketLog> {
|
||||
final int seq;
|
||||
final String payload;
|
||||
final DateTime createdAt;
|
||||
const PacketLog(
|
||||
{required this.seq, required this.payload, required this.createdAt});
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['seq'] = Variable<int>(seq);
|
||||
map['payload'] = Variable<String>(payload);
|
||||
map['created_at'] = Variable<DateTime>(createdAt);
|
||||
return map;
|
||||
}
|
||||
|
||||
PacketLogsCompanion toCompanion(bool nullToAbsent) {
|
||||
return PacketLogsCompanion(
|
||||
seq: Value(seq),
|
||||
payload: Value(payload),
|
||||
createdAt: Value(createdAt),
|
||||
);
|
||||
}
|
||||
|
||||
factory PacketLog.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return PacketLog(
|
||||
seq: serializer.fromJson<int>(json['seq']),
|
||||
payload: serializer.fromJson<String>(json['payload']),
|
||||
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'seq': serializer.toJson<int>(seq),
|
||||
'payload': serializer.toJson<String>(payload),
|
||||
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||
};
|
||||
}
|
||||
|
||||
PacketLog copyWith({int? seq, String? payload, DateTime? createdAt}) =>
|
||||
PacketLog(
|
||||
seq: seq ?? this.seq,
|
||||
payload: payload ?? this.payload,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
);
|
||||
PacketLog copyWithCompanion(PacketLogsCompanion data) {
|
||||
return PacketLog(
|
||||
seq: data.seq.present ? data.seq.value : this.seq,
|
||||
payload: data.payload.present ? data.payload.value : this.payload,
|
||||
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('PacketLog(')
|
||||
..write('seq: $seq, ')
|
||||
..write('payload: $payload, ')
|
||||
..write('createdAt: $createdAt')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(seq, payload, createdAt);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
(other is PacketLog &&
|
||||
other.seq == this.seq &&
|
||||
other.payload == this.payload &&
|
||||
other.createdAt == this.createdAt);
|
||||
}
|
||||
|
||||
class PacketLogsCompanion extends UpdateCompanion<PacketLog> {
|
||||
final Value<int> seq;
|
||||
final Value<String> payload;
|
||||
final Value<DateTime> createdAt;
|
||||
const PacketLogsCompanion({
|
||||
this.seq = const Value.absent(),
|
||||
this.payload = const Value.absent(),
|
||||
this.createdAt = const Value.absent(),
|
||||
});
|
||||
PacketLogsCompanion.insert({
|
||||
this.seq = const Value.absent(),
|
||||
required String payload,
|
||||
this.createdAt = const Value.absent(),
|
||||
}) : payload = Value(payload);
|
||||
static Insertable<PacketLog> custom({
|
||||
Expression<int>? seq,
|
||||
Expression<String>? payload,
|
||||
Expression<DateTime>? createdAt,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (seq != null) 'seq': seq,
|
||||
if (payload != null) 'payload': payload,
|
||||
if (createdAt != null) 'created_at': createdAt,
|
||||
});
|
||||
}
|
||||
|
||||
PacketLogsCompanion copyWith(
|
||||
{Value<int>? seq, Value<String>? payload, Value<DateTime>? createdAt}) {
|
||||
return PacketLogsCompanion(
|
||||
seq: seq ?? this.seq,
|
||||
payload: payload ?? this.payload,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (seq.present) {
|
||||
map['seq'] = Variable<int>(seq.value);
|
||||
}
|
||||
if (payload.present) {
|
||||
map['payload'] = Variable<String>(payload.value);
|
||||
}
|
||||
if (createdAt.present) {
|
||||
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('PacketLogsCompanion(')
|
||||
..write('seq: $seq, ')
|
||||
..write('payload: $payload, ')
|
||||
..write('createdAt: $createdAt')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _$EphemeralDatabase extends GeneratedDatabase {
|
||||
_$EphemeralDatabase(QueryExecutor e) : super(e);
|
||||
$EphemeralDatabaseManager get managers => $EphemeralDatabaseManager(this);
|
||||
late final $MediaItemsTable mediaItems = $MediaItemsTable(this);
|
||||
late final $PacketLogsTable packetLogs = $PacketLogsTable(this);
|
||||
@override
|
||||
Iterable<TableInfo<Table, Object?>> get allTables =>
|
||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [mediaItems];
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [mediaItems, packetLogs];
|
||||
}
|
||||
|
||||
typedef $$MediaItemsTableCreateCompanionBuilder = MediaItemsCompanion Function({
|
||||
@@ -548,10 +762,147 @@ typedef $$MediaItemsTableProcessedTableManager = ProcessedTableManager<
|
||||
),
|
||||
MediaItem,
|
||||
PrefetchHooks Function()>;
|
||||
typedef $$PacketLogsTableCreateCompanionBuilder = PacketLogsCompanion Function({
|
||||
Value<int> seq,
|
||||
required String payload,
|
||||
Value<DateTime> createdAt,
|
||||
});
|
||||
typedef $$PacketLogsTableUpdateCompanionBuilder = PacketLogsCompanion Function({
|
||||
Value<int> seq,
|
||||
Value<String> payload,
|
||||
Value<DateTime> createdAt,
|
||||
});
|
||||
|
||||
class $$PacketLogsTableFilterComposer
|
||||
extends Composer<_$EphemeralDatabase, $PacketLogsTable> {
|
||||
$$PacketLogsTableFilterComposer({
|
||||
required super.$db,
|
||||
required super.$table,
|
||||
super.joinBuilder,
|
||||
super.$addJoinBuilderToRootComposer,
|
||||
super.$removeJoinBuilderFromRootComposer,
|
||||
});
|
||||
ColumnFilters<int> get seq => $composableBuilder(
|
||||
column: $table.seq, builder: (column) => ColumnFilters(column));
|
||||
|
||||
ColumnFilters<String> get payload => $composableBuilder(
|
||||
column: $table.payload, builder: (column) => ColumnFilters(column));
|
||||
|
||||
ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
||||
column: $table.createdAt, builder: (column) => ColumnFilters(column));
|
||||
}
|
||||
|
||||
class $$PacketLogsTableOrderingComposer
|
||||
extends Composer<_$EphemeralDatabase, $PacketLogsTable> {
|
||||
$$PacketLogsTableOrderingComposer({
|
||||
required super.$db,
|
||||
required super.$table,
|
||||
super.joinBuilder,
|
||||
super.$addJoinBuilderToRootComposer,
|
||||
super.$removeJoinBuilderFromRootComposer,
|
||||
});
|
||||
ColumnOrderings<int> get seq => $composableBuilder(
|
||||
column: $table.seq, builder: (column) => ColumnOrderings(column));
|
||||
|
||||
ColumnOrderings<String> get payload => $composableBuilder(
|
||||
column: $table.payload, builder: (column) => ColumnOrderings(column));
|
||||
|
||||
ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
||||
column: $table.createdAt, builder: (column) => ColumnOrderings(column));
|
||||
}
|
||||
|
||||
class $$PacketLogsTableAnnotationComposer
|
||||
extends Composer<_$EphemeralDatabase, $PacketLogsTable> {
|
||||
$$PacketLogsTableAnnotationComposer({
|
||||
required super.$db,
|
||||
required super.$table,
|
||||
super.joinBuilder,
|
||||
super.$addJoinBuilderToRootComposer,
|
||||
super.$removeJoinBuilderFromRootComposer,
|
||||
});
|
||||
GeneratedColumn<int> get seq =>
|
||||
$composableBuilder(column: $table.seq, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<String> get payload =>
|
||||
$composableBuilder(column: $table.payload, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<DateTime> get createdAt =>
|
||||
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
||||
}
|
||||
|
||||
class $$PacketLogsTableTableManager extends RootTableManager<
|
||||
_$EphemeralDatabase,
|
||||
$PacketLogsTable,
|
||||
PacketLog,
|
||||
$$PacketLogsTableFilterComposer,
|
||||
$$PacketLogsTableOrderingComposer,
|
||||
$$PacketLogsTableAnnotationComposer,
|
||||
$$PacketLogsTableCreateCompanionBuilder,
|
||||
$$PacketLogsTableUpdateCompanionBuilder,
|
||||
(
|
||||
PacketLog,
|
||||
BaseReferences<_$EphemeralDatabase, $PacketLogsTable, PacketLog>
|
||||
),
|
||||
PacketLog,
|
||||
PrefetchHooks Function()> {
|
||||
$$PacketLogsTableTableManager(_$EphemeralDatabase db, $PacketLogsTable table)
|
||||
: super(TableManagerState(
|
||||
db: db,
|
||||
table: table,
|
||||
createFilteringComposer: () =>
|
||||
$$PacketLogsTableFilterComposer($db: db, $table: table),
|
||||
createOrderingComposer: () =>
|
||||
$$PacketLogsTableOrderingComposer($db: db, $table: table),
|
||||
createComputedFieldComposer: () =>
|
||||
$$PacketLogsTableAnnotationComposer($db: db, $table: table),
|
||||
updateCompanionCallback: ({
|
||||
Value<int> seq = const Value.absent(),
|
||||
Value<String> payload = const Value.absent(),
|
||||
Value<DateTime> createdAt = const Value.absent(),
|
||||
}) =>
|
||||
PacketLogsCompanion(
|
||||
seq: seq,
|
||||
payload: payload,
|
||||
createdAt: createdAt,
|
||||
),
|
||||
createCompanionCallback: ({
|
||||
Value<int> seq = const Value.absent(),
|
||||
required String payload,
|
||||
Value<DateTime> createdAt = const Value.absent(),
|
||||
}) =>
|
||||
PacketLogsCompanion.insert(
|
||||
seq: seq,
|
||||
payload: payload,
|
||||
createdAt: createdAt,
|
||||
),
|
||||
withReferenceMapper: (p0) => p0
|
||||
.map((e) => (e.readTable(table), BaseReferences(db, table, e)))
|
||||
.toList(),
|
||||
prefetchHooksCallback: null,
|
||||
));
|
||||
}
|
||||
|
||||
typedef $$PacketLogsTableProcessedTableManager = ProcessedTableManager<
|
||||
_$EphemeralDatabase,
|
||||
$PacketLogsTable,
|
||||
PacketLog,
|
||||
$$PacketLogsTableFilterComposer,
|
||||
$$PacketLogsTableOrderingComposer,
|
||||
$$PacketLogsTableAnnotationComposer,
|
||||
$$PacketLogsTableCreateCompanionBuilder,
|
||||
$$PacketLogsTableUpdateCompanionBuilder,
|
||||
(
|
||||
PacketLog,
|
||||
BaseReferences<_$EphemeralDatabase, $PacketLogsTable, PacketLog>
|
||||
),
|
||||
PacketLog,
|
||||
PrefetchHooks Function()>;
|
||||
|
||||
class $EphemeralDatabaseManager {
|
||||
final _$EphemeralDatabase _db;
|
||||
$EphemeralDatabaseManager(this._db);
|
||||
$$MediaItemsTableTableManager get mediaItems =>
|
||||
$$MediaItemsTableTableManager(_db, _db.mediaItems);
|
||||
$$PacketLogsTableTableManager get packetLogs =>
|
||||
$$PacketLogsTableTableManager(_db, _db.packetLogs);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user