import 'dart:io'; import 'package:drift/drift.dart'; import 'package:drift/native.dart'; import 'package:flutter/foundation.dart'; import 'package:niogu_app/core/database/daos/campaign_dao.dart'; import 'package:niogu_app/core/database/daos/category_dao.dart'; import 'package:niogu_app/core/database/daos/customer_address_dao.dart'; import 'package:niogu_app/core/database/daos/customer_dao.dart'; import 'package:niogu_app/core/database/daos/order_dao.dart'; import 'package:niogu_app/core/database/daos/order_item_dao.dart'; import 'package:niogu_app/core/database/daos/outlet_campaign_dao.dart'; import 'package:niogu_app/core/database/daos/outlet_dao.dart'; import 'package:niogu_app/core/database/daos/outlet_inventory_dao.dart'; import 'package:niogu_app/core/database/daos/product_dao.dart'; import 'package:niogu_app/core/database/daos/product_like_dao.dart'; import 'package:niogu_app/core/database/daos/product_review_dao.dart'; import 'package:niogu_app/core/database/daos/product_variant_dao.dart'; import 'package:niogu_app/core/database/daos/purchase_dao.dart'; import 'package:niogu_app/core/database/daos/purchase_item_dao.dart'; import 'package:niogu_app/core/database/daos/raw_material_dao.dart'; import 'package:niogu_app/core/database/daos/stock_card_dao.dart'; import 'package:niogu_app/core/database/daos/supplier_dao.dart'; import 'package:niogu_app/core/database/daos/sync_queue_dao.dart'; import 'package:niogu_app/core/database/daos/tenant_dao.dart'; import 'package:niogu_app/core/database/daos/tenant_payment_method_dao.dart'; import 'package:niogu_app/core/database/daos/transaction_dao.dart'; import 'package:niogu_app/core/database/daos/unit_dao.dart'; import 'package:niogu_app/core/database/daos/receipt_item_dao.dart'; import 'package:niogu_app/core/database/daos/user_dao.dart'; import 'package:niogu_app/core/database/tables/campaigns.dart'; import 'package:niogu_app/core/database/tables/categories.dart'; import 'package:niogu_app/core/database/tables/customer_addresses.dart'; import 'package:niogu_app/core/database/tables/customers.dart'; import 'package:niogu_app/core/database/tables/order_items.dart'; import 'package:niogu_app/core/database/tables/orders.dart'; import 'package:niogu_app/core/database/tables/outlet_campaigns.dart'; import 'package:niogu_app/core/database/tables/outlet_inventories.dart'; import 'package:niogu_app/core/database/tables/outlets.dart'; import 'package:niogu_app/core/database/tables/product_likes.dart'; import 'package:niogu_app/core/database/tables/product_reviews.dart'; import 'package:niogu_app/core/database/tables/product_variants.dart'; import 'package:niogu_app/core/database/tables/products.dart'; import 'package:niogu_app/core/database/tables/purchase_items.dart'; import 'package:niogu_app/core/database/tables/purchases.dart'; import 'package:niogu_app/core/database/tables/raw_materials.dart'; import 'package:niogu_app/core/database/tables/receipt_items.dart'; import 'package:niogu_app/core/database/tables/stock_cards.dart'; import 'package:niogu_app/core/database/tables/suppliers.dart'; import 'package:niogu_app/core/database/tables/sync_queues.dart'; import 'package:niogu_app/core/database/tables/tenant_payment_methods.dart'; import 'package:niogu_app/core/database/tables/tenants.dart'; import 'package:niogu_app/core/database/tables/transactions.dart'; import 'package:niogu_app/core/database/tables/units.dart'; import 'package:niogu_app/core/database/tables/users.dart'; import 'package:niogu_app/core/system/system_secure.dart'; import 'package:niogu_app/core/utils/string_list_converter.dart'; import 'package:niogu_app/core/utils/string_map_converter.dart'; import 'package:niogu_app/core/system/system_setting.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; import 'package:uuid/uuid.dart'; part 'app_database.g.dart'; @DriftDatabase( tables: [ Tenants, TenantPaymentMethods, Users, Customers, CustomerAddresses, Outlets, Categories, Units, Products, ProductVariants, ProductReviews, ProductLikes, RawMaterials, OutletInventories, ReceiptItems, StockCards, Orders, OrderItems, Purchases, PurchaseItems, Suppliers, Transactions, Campaigns, OutletCampaigns, SyncQueues ], daos: [ TenantDao, TenantPaymentMethodDao, UserDao, CustomerDao, CustomerAddressDao, OutletDao, CategoryDao, UnitDao, ProductDao, ProductVariantDao, ProductReviewDao, ProductLikeDao, RawMaterialDao, OutletInventoryDao, ReceiptItemDao, StockCardDao, OrderDao, OrderItemDao, SupplierDao, PurchaseDao, PurchaseItemDao, TransactionDao, CampaignDao, OutletCampaignDao, SyncQueueDao ], ) class AppDatabase extends _$AppDatabase { AppDatabase() : super(_openConnection()); @override // TODO: implement schemaVersion int get schemaVersion => 1; TenantDao get tenantDao => TenantDao(this); TenantPaymentMethodDao get tenantPaymentMethodDao => TenantPaymentMethodDao(this); UserDao get userDao => UserDao(this); CustomerDao get customerDao => CustomerDao(this); CustomerAddressDao get customerAddressDao => CustomerAddressDao(this); OutletDao get outletDao => OutletDao(this); CategoryDao get categoryDao => CategoryDao(this); UnitDao get unitDao => UnitDao(this); ProductDao get productDao => ProductDao(this); ProductVariantDao get productVariantDao => ProductVariantDao(this); ProductReviewDao get productReviewDao => ProductReviewDao(this); ProductLikeDao get productLikeDao => ProductLikeDao(this); RawMaterialDao get rawMaterialDao => RawMaterialDao(this); OutletInventoryDao get outletInventoryDao => OutletInventoryDao(this); ReceiptItemDao get receiptItemDao => ReceiptItemDao(this); StockCardDao get stockCardDao => StockCardDao(this); OrderDao get orderDao => OrderDao(this); OrderItemDao get orderItemDao => OrderItemDao(this); PurchaseDao get purchaseDao => PurchaseDao(this); PurchaseItemDao get purchaseItemDao => PurchaseItemDao(this); SupplierDao get supplierDao => SupplierDao(this); CampaignDao get campaignDao => CampaignDao(this); OutletCampaignDao get outletCampaignDao => OutletCampaignDao(this); SyncQueueDao get syncQueueDao => SyncQueueDao(this); @override // TODO: implement migration MigrationStrategy get migration => MigrationStrategy( onCreate: (m) async { await m.createAll(); await customStatement( 'CREATE UNIQUE INDEX outlet_email_unique_active ON outlets(email) WHERE deleted_at IS NULL', ); await customStatement( 'CREATE UNIQUE INDEX outlet_phone_unique_active ON outlets(phone_number) WHERE deleted_at IS NULL', ); await customStatement( 'CREATE UNIQUE INDEX users_email_unique_active ON users(email) WHERE deleted_at IS NULL', ); await customStatement( 'CREATE UNIQUE INDEX users_phone_unique_active ON users(phone_number) WHERE deleted_at IS NULL', ); await customStatement( 'CREATE INDEX IF NOT EXISTS idx_products_created_at ON products (created_at)', ); await customStatement( 'CREATE INDEX IF NOT EXISTS idx_products_deleted_at ON products (deleted_at)', ); await customStatement( 'CREATE INDEX IF NOT EXISTS idx_outlet_inventories_lookup ON outlet_inventories (item_type, item_id)', ); await customStatement( 'CREATE INDEX IF NOT EXISTS idx_outlet_inventories_deleted_at ON outlet_inventories (deleted_at)', ); await customStatement( 'CREATE INDEX IF NOT EXISTS idx_transaction_lookup ON transactions (reference_type, reference_id)', ); }, onUpgrade: (m, from, to) async { // Handle database upgrades if needed }, ); } LazyDatabase _openConnection() { return LazyDatabase(() async { final tenantCode = await SystemSetting.getTenantCode(); final dbFolder = await getApplicationDocumentsDirectory(); final file = File(path.join(dbFolder.path, 'NIOGU_$tenantCode.sqlite')); var databaseKey = await SystemSecure.getDatabaseKey(tenantCode!); if (databaseKey == null) { await SystemSecure.generateDatabaseKey(tenantCode); databaseKey = await SystemSecure.getDatabaseKey(tenantCode); } return NativeDatabase.createInBackground( file, setup: (database) { database.execute('PRAGMA foreign_keys = ON'); database.execute("PRAGMA key = '$databaseKey';"); }, logStatements: kDebugMode, ); }); }