827 lines
24 KiB
Dart
827 lines
24 KiB
Dart
import 'dart:io';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:path_provider/path_provider.dart';
|
|
import 'package:path/path.dart' as p;
|
|
import 'package:drift/drift.dart';
|
|
import 'package:drift/native.dart';
|
|
import 'package:drift/drift.dart' as drift;
|
|
import 'package:search_engine/services/config_service.dart';
|
|
import 'package:search_engine/services/mimir_service.dart';
|
|
|
|
part 'database.g.dart';
|
|
|
|
class Draft {
|
|
final String id;
|
|
final String title;
|
|
final DateTime date;
|
|
final int activity;
|
|
final String thumbnail;
|
|
final int draft;
|
|
final String locale;
|
|
final String country;
|
|
final String city;
|
|
final String? body;
|
|
final String? pdf;
|
|
final String languagesCode;
|
|
final Map<String, dynamic>? searchResultData;
|
|
final int position;
|
|
final int length;
|
|
|
|
Draft({
|
|
required this.id,
|
|
required this.title,
|
|
required this.date,
|
|
required this.activity,
|
|
required this.thumbnail,
|
|
required this.draft,
|
|
required this.locale,
|
|
required this.country,
|
|
required this.city,
|
|
this.body,
|
|
this.pdf,
|
|
required this.languagesCode,
|
|
this.searchResultData,
|
|
this.position = 0,
|
|
this.length = 0,
|
|
});
|
|
}
|
|
|
|
class Messages extends Table {
|
|
TextColumn get id => text()();
|
|
|
|
TextColumn get country => text()();
|
|
|
|
TextColumn get city => text()();
|
|
|
|
DateTimeColumn get date => dateTime()();
|
|
|
|
IntColumn get activity => integer()();
|
|
|
|
IntColumn get draft => integer()();
|
|
|
|
TextColumn get thumbnail => text()();
|
|
|
|
@override
|
|
Set<Column> get primaryKey => {id};
|
|
}
|
|
|
|
@TableIndex(name: 'title_index', columns: {#title})
|
|
@TableIndex(name: 'body_index', columns: {#body})
|
|
@TableIndex(name: 'message_id_index', columns: {#messageId})
|
|
class Translations extends Table {
|
|
TextColumn get messageId => text()();
|
|
|
|
TextColumn get title => text()();
|
|
|
|
TextColumn get body => text()();
|
|
|
|
TextColumn get languagesCode => text()();
|
|
|
|
TextColumn get pdf => text().nullable()();
|
|
|
|
@override
|
|
Set<Column> get primaryKey => {messageId, languagesCode};
|
|
}
|
|
|
|
class Favorites extends Table {
|
|
TextColumn get id => text()();
|
|
|
|
@override
|
|
Set<Column> get primaryKey => {id};
|
|
}
|
|
|
|
@DriftDatabase(tables: [Messages, Translations, Favorites])
|
|
class AppDatabase extends _$AppDatabase {
|
|
AppDatabase() : super(_createConnection());
|
|
|
|
static DatabaseConnection _createConnection() {
|
|
return DatabaseConnection.delayed(Future(() async {
|
|
final dbFolder = await getApplicationDocumentsDirectory();
|
|
final filePath = p.join(dbFolder.path, 'LGCC_Search/internal/db.sqlite');
|
|
|
|
final file = File(filePath);
|
|
final database = NativeDatabase(file,
|
|
logStatements: false, cachePreparedStatements: true);
|
|
|
|
return DatabaseConnection(database);
|
|
}));
|
|
}
|
|
|
|
@override
|
|
int get schemaVersion => 1;
|
|
|
|
Future<void> addMessages(List<Draft> drafts) async {
|
|
if (drafts.isEmpty) {
|
|
return; // No hay nada que insertar
|
|
}
|
|
|
|
try {
|
|
// Preparar las listas para mensajes y traducciones
|
|
List<MessagesCompanion> messagesList = [];
|
|
List<TranslationsCompanion> translationsList = [];
|
|
|
|
// Validar y preparar los datos
|
|
for (final draft in drafts) {
|
|
// Validar que el ID no esté vacío
|
|
if (draft.id.isEmpty) {
|
|
if (kDebugMode) {
|
|
print('Saltando mensaje con ID vacío');
|
|
}
|
|
continue;
|
|
}
|
|
|
|
// Preparar el mensaje
|
|
messagesList.add(MessagesCompanion(
|
|
id: Value(draft.id),
|
|
country: Value(draft.country),
|
|
city: Value(draft.city),
|
|
date: Value(draft.date),
|
|
activity: Value(draft.activity),
|
|
thumbnail: Value(draft.thumbnail),
|
|
draft: Value(draft.draft),
|
|
));
|
|
|
|
// Preparar la traducción
|
|
translationsList.add(TranslationsCompanion(
|
|
messageId: Value(draft.id),
|
|
body: Value(draft.body ?? ''),
|
|
languagesCode: Value(draft.languagesCode),
|
|
title: Value(draft.title),
|
|
pdf: Value(draft.pdf ?? ''),
|
|
));
|
|
}
|
|
|
|
// Ejecutar las inserciones en una transacción para garantizar la atomicidad
|
|
await transaction(() async {
|
|
// Insertar mensajes con manejo de conflictos
|
|
for (var message in messagesList) {
|
|
await into(messages).insert(
|
|
message,
|
|
onConflict: DoUpdate(
|
|
(old) => MessagesCompanion(
|
|
country: message.country,
|
|
city: message.city,
|
|
date: message.date,
|
|
activity: message.activity,
|
|
thumbnail: message.thumbnail,
|
|
draft: message.draft,
|
|
),
|
|
target: [messages.id],
|
|
),
|
|
);
|
|
}
|
|
|
|
// Insertar traducciones con manejo de conflictos
|
|
for (var translation in translationsList) {
|
|
await into(translations).insert(
|
|
translation,
|
|
onConflict: DoUpdate(
|
|
(old) => TranslationsCompanion(
|
|
title: translation.title,
|
|
body: translation.body,
|
|
pdf: translation.pdf,
|
|
),
|
|
target: [translations.messageId, translations.languagesCode],
|
|
),
|
|
);
|
|
}
|
|
});
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error al insertar mensajes en la base de datos: $e');
|
|
}
|
|
// Reintento con enfoque más seguro en caso de error
|
|
try {
|
|
// Insertar uno por uno para identificar registros problemáticos
|
|
for (int i = 0; i < drafts.length; i++) {
|
|
final draft = drafts[i];
|
|
try {
|
|
// Insertar mensaje
|
|
await into(messages).insert(
|
|
MessagesCompanion(
|
|
id: Value(draft.id),
|
|
country: Value(draft.country),
|
|
city: Value(draft.city),
|
|
date: Value(draft.date),
|
|
activity: Value(draft.activity),
|
|
thumbnail: Value(draft.thumbnail),
|
|
draft: Value(draft.draft),
|
|
),
|
|
onConflict: DoUpdate(
|
|
(old) => MessagesCompanion(
|
|
country: Value(draft.country),
|
|
city: Value(draft.city),
|
|
date: Value(draft.date),
|
|
activity: Value(draft.activity),
|
|
thumbnail: Value(draft.thumbnail),
|
|
draft: Value(draft.draft),
|
|
),
|
|
target: [messages.id],
|
|
),
|
|
);
|
|
|
|
// Insertar traducción
|
|
await into(translations).insert(
|
|
TranslationsCompanion(
|
|
messageId: Value(draft.id),
|
|
body: Value(draft.body ?? ''),
|
|
languagesCode: Value(draft.languagesCode),
|
|
title: Value(draft.title),
|
|
pdf: Value(draft.pdf ?? ''),
|
|
),
|
|
onConflict: DoUpdate(
|
|
(old) => TranslationsCompanion(
|
|
title: Value(draft.title),
|
|
body: Value(draft.body ?? ''),
|
|
pdf: Value(draft.pdf ?? ''),
|
|
),
|
|
target: [translations.messageId, translations.languagesCode],
|
|
),
|
|
);
|
|
} catch (innerError) {
|
|
if (kDebugMode) {
|
|
print(
|
|
'Error al insertar mensaje #$i (ID: ${draft.id}): $innerError');
|
|
}
|
|
// Continuar con el siguiente registro
|
|
}
|
|
}
|
|
} catch (fallbackError) {
|
|
if (kDebugMode) {
|
|
print('Error en el proceso de recuperación: $fallbackError');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<List<Map<String, dynamic>>> getPdfList() async {
|
|
final locale = await ConfigService.getLocale();
|
|
try {
|
|
final queryResult = await customSelect(
|
|
"SELECT pdf, id, t.title, date, m.country, activity FROM messages LEFT JOIN translations ON messages.id = translations.message_id WHERE pdf <> '' AND locale = '$locale'",
|
|
readsFrom: {messages}).map((row) {
|
|
return {
|
|
'pdf': row.read<String>('pdf'),
|
|
'title': row.read<String>('title')
|
|
};
|
|
}).get();
|
|
return queryResult;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error fetching PDF list: $e');
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
Future<List<Draft>> getMessages(bool isDraft, [String? localeParam]) async {
|
|
final locale = localeParam ?? await ConfigService.getLocale();
|
|
if (locale.isEmpty) {
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
// Consulta SQL optimizada sin usar INDEXED BY
|
|
final queryResult = await customSelect(
|
|
"""
|
|
SELECT DISTINCT
|
|
m.id,
|
|
m.date,
|
|
m.activity,
|
|
m.thumbnail,
|
|
m.draft,
|
|
m.country,
|
|
m.city,
|
|
t.languages_code as locale,
|
|
t.title,
|
|
t.pdf,
|
|
t.languages_code
|
|
FROM
|
|
messages m
|
|
JOIN translations t ON m.id = t.message_id
|
|
WHERE
|
|
m.draft = ?
|
|
AND t.languages_code = ?
|
|
ORDER BY m.date DESC
|
|
LIMIT 20
|
|
""",
|
|
variables: [
|
|
Variable<int>(isDraft ? 1 : 0),
|
|
Variable.withString(locale),
|
|
],
|
|
readsFrom: {messages, translations},
|
|
).map((row) {
|
|
return Draft(
|
|
id: row.read<String>('id'),
|
|
title: row.read<String>('title'),
|
|
date: row.read<DateTime>('date'),
|
|
activity: row.read<int>('activity'),
|
|
thumbnail: row.read<String>('thumbnail'),
|
|
draft: row.read<int>('draft'),
|
|
locale: row.read<String>('locale'),
|
|
country: row.read<String>('country'),
|
|
city: row.read<String>('city'),
|
|
// Cargar el cuerpo solo cuando sea necesario para mejorar el rendimiento
|
|
body: '',
|
|
pdf: row.read<String?>('pdf') ?? '',
|
|
languagesCode: row.read<String>('languages_code'),
|
|
);
|
|
}).get();
|
|
|
|
return queryResult;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error fetching messages: $e');
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Nuevo método para cargar el cuerpo de un mensaje específico cuando sea necesario
|
|
Future<String> getMessageBody(String messageId, String languageCode) async {
|
|
try {
|
|
final result = await customSelect(
|
|
"""
|
|
SELECT body
|
|
FROM translations
|
|
WHERE message_id = ? AND languages_code = ?
|
|
""",
|
|
variables: [
|
|
Variable.withString(messageId),
|
|
Variable.withString(languageCode),
|
|
],
|
|
).getSingleOrNull();
|
|
|
|
return result?.read<String?>('body') ?? '';
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error fetching message body: $e');
|
|
}
|
|
return '';
|
|
}
|
|
}
|
|
|
|
Future<List<Draft>> getYearActivities(String year, String month) async {
|
|
final locale = await ConfigService.getLocale();
|
|
try {
|
|
final queryResult = await customSelect(
|
|
"SELECT DISTINCT m.id, t.title, m.date, m.activity, m.thumbnail, m.draft, t.languages_code as locale, m.country, m.city, t.body, t.pdf, t.languages_code, strftime('%Y', datetime(m.date, 'unixepoch')) AS year, strftime('%m', datetime(m.date, 'unixepoch')) AS month "
|
|
"FROM messages m JOIN translations t ON m.id = t.message_id "
|
|
"WHERE strftime('%Y', datetime(m.date, 'unixepoch')) = ? AND strftime('%m', datetime(m.date, 'unixepoch')) = ? AND t.languages_code = ? "
|
|
"ORDER BY m.date DESC, m.activity DESC",
|
|
variables: [
|
|
Variable.withString(year),
|
|
Variable.withString(month),
|
|
Variable.withString(locale)
|
|
],
|
|
readsFrom: {messages, translations},
|
|
).map((row) {
|
|
final id = row.read<String>('id');
|
|
final title = row.read<String>('title');
|
|
final date = row.read<DateTime>('date');
|
|
final activity = row.read<int>('activity');
|
|
final thumbnail = row.read<String>('thumbnail');
|
|
final draft = row.read<int>('draft');
|
|
final locale = row.read<String>('locale');
|
|
final country = row.read<String>('country');
|
|
final city = row.read<String>('city');
|
|
final body = row.read<String?>('body') ?? '';
|
|
final pdf = row.read<String?>('pdf') ?? '';
|
|
final languagesCode = row.read<String>('languages_code');
|
|
return Draft(
|
|
id: id,
|
|
title: title,
|
|
date: date,
|
|
activity: activity,
|
|
thumbnail: thumbnail,
|
|
draft: draft,
|
|
locale: locale,
|
|
country: country,
|
|
city: city,
|
|
body: body,
|
|
pdf: pdf,
|
|
languagesCode: languagesCode,
|
|
);
|
|
}).get();
|
|
|
|
return queryResult;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error fetching activities: $e');
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
Future<List<String>> getMonths(String year) async {
|
|
try {
|
|
final queryResult = await customSelect(
|
|
"SELECT DISTINCT strftime('%m', datetime(date, 'unixepoch')) AS month FROM messages WHERE strftime('%Y', datetime(date, 'unixepoch')) = ? ORDER BY month ASC",
|
|
variables: [Variable.withString(year)],
|
|
readsFrom: {messages},
|
|
).map((row) {
|
|
return row.read<String>('month');
|
|
}).get();
|
|
|
|
return queryResult;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error fetching months: $e');
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
Future<void> toggleFavorite(String id) async {
|
|
final result = await customSelect(
|
|
'SELECT COUNT(*) AS count FROM favorites WHERE id = ?',
|
|
variables: [Variable.withString(id)],
|
|
).getSingle();
|
|
|
|
final isFavorite = result.read<int>('count') > 0;
|
|
|
|
if (isFavorite) {
|
|
delete(favorites).delete(FavoritesCompanion(id: Value(id)));
|
|
} else {
|
|
into(favorites).insert(
|
|
FavoritesCompanion(id: Value(id)),
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<bool> checkFavorite(String id) async {
|
|
final result = await customSelect(
|
|
'SELECT DISTINCT COUNT(*) AS count FROM favorites WHERE id = ?',
|
|
variables: [Variable.withString(id)],
|
|
).getSingle();
|
|
final isFavorite = result.read<int>('count') > 0;
|
|
return isFavorite;
|
|
}
|
|
|
|
Future<List<String>> getFavorites() async {
|
|
final result = await customSelect('SELECT DISTINCT id FROM favorites')
|
|
.map((row) => row.read<String>('id'))
|
|
.get();
|
|
return result;
|
|
}
|
|
|
|
// Método para obtener los años disponibles en la base de datos
|
|
Future<List<String>> getAvailableYears() async {
|
|
try {
|
|
final queryResult = await customSelect(
|
|
"SELECT DISTINCT strftime('%Y', datetime(date, 'unixepoch')) AS year FROM messages ORDER BY year DESC",
|
|
readsFrom: {messages},
|
|
).map((row) {
|
|
return row.read<String>('year');
|
|
}).get();
|
|
|
|
return queryResult;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error fetching available years: $e');
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Método para obtener mensajes filtrados por año y mes
|
|
Future<List<Draft>> getFilteredMessages(String year, String month,
|
|
[String? localeParam]) async {
|
|
final locale = localeParam ?? await ConfigService.getLocale();
|
|
if (locale.isEmpty) {
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
final queryResult = await customSelect(
|
|
"""
|
|
SELECT DISTINCT
|
|
m.id,
|
|
m.date,
|
|
m.activity,
|
|
m.thumbnail,
|
|
m.draft,
|
|
m.country,
|
|
m.city,
|
|
t.languages_code as locale,
|
|
t.title,
|
|
t.pdf,
|
|
t.languages_code
|
|
FROM
|
|
messages m
|
|
JOIN translations t ON m.id = t.message_id
|
|
WHERE
|
|
strftime('%Y', datetime(m.date, 'unixepoch')) = ?
|
|
AND strftime('%m', datetime(m.date, 'unixepoch')) = ?
|
|
AND t.languages_code = ?
|
|
ORDER BY m.date DESC
|
|
""",
|
|
variables: [
|
|
Variable.withString(year),
|
|
Variable.withString(month),
|
|
Variable.withString(locale),
|
|
],
|
|
readsFrom: {messages, translations},
|
|
).map((row) {
|
|
return Draft(
|
|
id: row.read<String>('id'),
|
|
title: row.read<String>('title'),
|
|
date: row.read<DateTime>('date'),
|
|
activity: row.read<int>('activity'),
|
|
thumbnail: row.read<String>('thumbnail'),
|
|
draft: row.read<int>('draft'),
|
|
locale: row.read<String>('locale'),
|
|
country: row.read<String>('country'),
|
|
city: row.read<String>('city'),
|
|
body: '',
|
|
pdf: row.read<String?>('pdf') ?? '',
|
|
languagesCode: row.read<String>('languages_code'),
|
|
);
|
|
}).get();
|
|
|
|
return queryResult;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error fetching filtered messages: $e');
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Método para obtener todos los mensajes (borradores y no borradores)
|
|
Future<List<Draft>> getAllMessages([String? localeParam, int? limit]) async {
|
|
final locale = localeParam ?? await ConfigService.getLocale();
|
|
if (locale.isEmpty) {
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
// Consulta SQL optimizada para obtener todos los mensajes
|
|
var query = """
|
|
SELECT DISTINCT
|
|
m.id,
|
|
m.date,
|
|
m.activity,
|
|
m.thumbnail,
|
|
m.draft,
|
|
m.country,
|
|
m.city,
|
|
t.languages_code as locale,
|
|
t.title,
|
|
t.body,
|
|
t.pdf,
|
|
t.languages_code
|
|
FROM
|
|
messages m
|
|
JOIN translations t ON m.id = t.message_id
|
|
WHERE
|
|
t.languages_code = ?
|
|
ORDER BY m.date DESC
|
|
""";
|
|
|
|
// Añadir límite si se especifica
|
|
if (limit != null) {
|
|
query += " LIMIT $limit";
|
|
}
|
|
|
|
final queryResult = await customSelect(
|
|
query,
|
|
variables: [
|
|
Variable.withString(locale),
|
|
],
|
|
readsFrom: {messages, translations},
|
|
).map((row) {
|
|
return Draft(
|
|
id: row.read<String>('id'),
|
|
title: row.read<String>('title'),
|
|
date: row.read<DateTime>('date'),
|
|
activity: row.read<int>('activity'),
|
|
thumbnail: row.read<String>('thumbnail'),
|
|
draft: row.read<int>('draft'),
|
|
locale: row.read<String>('locale'),
|
|
country: row.read<String>('country'),
|
|
city: row.read<String>('city'),
|
|
body: row.read<String?>('body') ?? '',
|
|
pdf: row.read<String?>('pdf') ?? '',
|
|
languagesCode: row.read<String>('languages_code'),
|
|
);
|
|
}).get();
|
|
|
|
return queryResult;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error fetching all messages: $e');
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
Future<List<Draft>> searchMessages(String query, String languagesCode) async {
|
|
try {
|
|
final mimirService = MimirService();
|
|
await mimirService.initialize();
|
|
|
|
// Buscar en Mimir para obtener los IDs relevantes y metadatos
|
|
final searchResult = await mimirService.search(query, languagesCode);
|
|
|
|
// Extraer IDs de los resultados
|
|
List<Map<String, dynamic>> searchResultsData = searchResult['results'];
|
|
List<String> docIds =
|
|
searchResultsData.map((doc) => doc['id'] as String).toList();
|
|
|
|
if (docIds.isEmpty) {
|
|
return [];
|
|
}
|
|
|
|
// Convertir los IDs en una cadena para la consulta SQL
|
|
final String idList = docIds.map((id) => "'$id'").join(',');
|
|
|
|
// Buscar los documentos completos en la base de datos
|
|
final queryResult = await customSelect(
|
|
'''
|
|
SELECT DISTINCT
|
|
m.id,
|
|
m.date,
|
|
m.activity,
|
|
m.thumbnail,
|
|
m.draft,
|
|
m.country,
|
|
m.city,
|
|
t.languages_code as locale,
|
|
t.title,
|
|
t.pdf,
|
|
t.languages_code,
|
|
t.body
|
|
FROM
|
|
messages m
|
|
JOIN translations t ON m.id = t.message_id
|
|
WHERE
|
|
m.id IN ($idList) AND t.languages_code = ?
|
|
ORDER BY m.date DESC
|
|
''',
|
|
variables: [Variable.withString(languagesCode)],
|
|
readsFrom: {messages, translations},
|
|
).map((row) {
|
|
final String id = row.read<String>('id');
|
|
|
|
// Buscar los datos del resultado de búsqueda correspondiente
|
|
Map<String, dynamic>? resultData;
|
|
for (var data in searchResultsData) {
|
|
if (data['id'] == id) {
|
|
resultData = data;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return Draft(
|
|
id: id,
|
|
title: row.read<String>('title'),
|
|
date: row.read<DateTime>('date'),
|
|
activity: row.read<int>('activity'),
|
|
thumbnail: row.read<String>('thumbnail'),
|
|
draft: row.read<int>('draft'),
|
|
locale: row.read<String>('locale'),
|
|
country: row.read<String>('country'),
|
|
city: row.read<String>('city'),
|
|
body: row.read<String?>('body'),
|
|
pdf: row.read<String?>('pdf') ?? '',
|
|
languagesCode: row.read<String>('languages_code'),
|
|
searchResultData: {
|
|
...resultData ?? {},
|
|
'allResultIds': docIds,
|
|
'mimirSearchResult': searchResult,
|
|
},
|
|
);
|
|
}).get();
|
|
|
|
return queryResult;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error searching messages: $e');
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Método para obtener todos los PDFs disponibles
|
|
Future<List<Draft>> getAvailablePdfs(String locale) async {
|
|
try {
|
|
final query = """
|
|
SELECT DISTINCT
|
|
m.id,
|
|
m.date,
|
|
m.activity,
|
|
m.thumbnail,
|
|
m.draft,
|
|
m.country,
|
|
m.city,
|
|
t.languages_code as locale,
|
|
t.title,
|
|
t.pdf,
|
|
t.languages_code
|
|
FROM
|
|
messages m
|
|
JOIN translations t ON m.id = t.message_id
|
|
WHERE
|
|
t.languages_code = ?
|
|
AND t.pdf IS NOT NULL
|
|
AND t.pdf != ''
|
|
ORDER BY m.date DESC
|
|
""";
|
|
|
|
final queryResult = await customSelect(
|
|
query,
|
|
variables: [
|
|
Variable.withString(locale),
|
|
],
|
|
readsFrom: {messages, translations},
|
|
).map((row) {
|
|
return Draft(
|
|
id: row.read<String>('id'),
|
|
title: row.read<String>('title'),
|
|
date: row.read<DateTime>('date'),
|
|
activity: row.read<int>('activity'),
|
|
thumbnail: row.read<String>('thumbnail'),
|
|
draft: row.read<int>('draft'),
|
|
locale: row.read<String>('locale'),
|
|
country: row.read<String>('country'),
|
|
city: row.read<String>('city'),
|
|
body: '',
|
|
pdf: row.read<String?>('pdf') ?? '',
|
|
languagesCode: row.read<String>('languages_code'),
|
|
);
|
|
}).get();
|
|
|
|
return queryResult;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error fetching available PDFs: $e');
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Método para obtener mensajes por IDs
|
|
Future<List<Draft>> getMessagesByIds(List<String> ids, String locale) async {
|
|
if (ids.isEmpty) return [];
|
|
|
|
try {
|
|
// Convertir la lista de IDs a un formato que pueda usarse en la consulta SQL
|
|
final String idList = ids.map((id) => "'$id'").join(',');
|
|
|
|
final queryResult = await customSelect(
|
|
'''
|
|
SELECT DISTINCT
|
|
m.id,
|
|
m.date,
|
|
m.activity,
|
|
m.thumbnail,
|
|
m.draft,
|
|
m.country,
|
|
m.city,
|
|
t.languages_code as locale,
|
|
t.title,
|
|
t.body,
|
|
t.pdf,
|
|
t.languages_code
|
|
FROM
|
|
messages m
|
|
JOIN translations t ON m.id = t.message_id
|
|
WHERE
|
|
m.id IN ($idList) AND t.languages_code = ?
|
|
ORDER BY m.date DESC
|
|
''',
|
|
variables: [Variable.withString(locale)],
|
|
readsFrom: {messages, translations},
|
|
).map((row) {
|
|
return Draft(
|
|
id: row.read<String>('id'),
|
|
title: row.read<String>('title'),
|
|
date: row.read<DateTime>('date'),
|
|
activity: row.read<int>('activity'),
|
|
thumbnail: row.read<String>('thumbnail'),
|
|
draft: row.read<int>('draft'),
|
|
locale: row.read<String>('locale'),
|
|
country: row.read<String>('country'),
|
|
city: row.read<String>('city'),
|
|
body: row.read<String?>('body') ?? '',
|
|
pdf: row.read<String?>('pdf') ?? '',
|
|
languagesCode: row.read<String>('languages_code'),
|
|
);
|
|
}).get();
|
|
|
|
if (kDebugMode) {
|
|
print(
|
|
'Encontrados ${queryResult.length} mensajes de ${ids.length} IDs');
|
|
}
|
|
|
|
return queryResult;
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error obteniendo mensajes por IDs: $e');
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
}
|