I've successfully implemented a comprehensive Room database layer with all recommended best practices. Here's everything that's been added:
- β Room Database 2.6.1
- β KSP (Kotlin Symbol Processing) 2.0.21
- β Kotlin Coroutines 1.8.0
- β KSP plugin for Room annotation processing
- β Room runtime, KTX, and compiler
- β Coroutines for async database operations
app/src/main/java/ug/global/temp/db/
βββ entities/ # Database Models
β βββ BaseEntity.kt (2.3KB) β Interface for common fields
β βββ User.kt (2.5KB) β Example user entity with best practices
β
βββ dao/ # Data Access Objects
β βββ BaseDao.kt (2.7KB) β Generic DAO with CRUD operations
β βββ UserDao.kt (8.5KB) β Complete example with 30+ query methods
β
βββ repository/ # Repository Pattern
β βββ BaseRepository.kt (2.9KB) β Generic repository
β βββ UserRepository.kt (7.8KB) β Business logic layer with validation
β
βββ database/ # Database Configuration
β βββ AppDatabase.kt (5.7KB) β Main database class with migrations
β βββ DatabaseHelper.kt (7.2KB) β Utilities (seed, backup, restore, stats)
β
βββ converters/ # Type Converters
βββ Converters.kt (3.1KB) β Handle Date, List, Map, Boolean
Total: 10 new files, ~40KB of production-ready code
- Insert (single, multiple, list)
- Update (single, multiple)
- Delete (single, multiple)
- Upsert (insert or update)
- All with suspend functions for coroutines
Query Operations:
- Get all users (Flow for reactive updates)
- Get user by ID, email, username, token
- Search by name/username/email
- Filtered queries (verified, active, by date)
- Count and exists checks
Update Operations:
- Update auth token
- Update email verification
- Update last login
- Update profile picture
- Soft delete/restore
Transaction Examples:
- Insert and return entity with generated ID
- Update with automatic timestamp
- Register user with validation
- Login/logout with token management
- Update profile
- Email verification
- Soft delete/restore
- Error handling with Result
- Seed database with sample data
- Clear all data
- Backup/restore database
- Get database stats (size, counts)
- Export to SQL
- Database file operations
- Date β Long (timestamp)
- List β String (comma-separated)
- Map<String, String> β String (JSON-like)
- Boolean β Int
Standard fields for all entities:
id- Primary keycreatedAt- Creation timestampupdatedAt- Last update timestampisDeleted- Soft delete flag
Comprehensive 400+ line guide covering:
- Quick start examples
- How to create entities
- How to create DAOs
- Using repositories
- Database operations (CRUD)
- Migrations (with examples)
- Best practices (DO/DON'T)
- Common patterns
- Troubleshooting
- Testing
-
util/Helpers.kt
- Added
getDatabase(context)helper - Added
getUserRepository(context)helper - Easy access from anywhere in the app
- Added
-
INDEX.md
- Added DATABASE_GUIDE.md to documentation index
- Updated for developers section
// Get repository
val userRepository = Helpers.getUserRepository(this)
// Insert user
lifecycleScope.launch {
val user = User(
email = "john@example.com",
username = "johndoe",
fullName = "John Doe"
)
val userId = userRepository.insert(user)
}
// Query with Flow (reactive)
lifecycleScope.launch {
userRepository.getAllUsers().collect { users ->
// UI updates automatically when data changes
updateUI(users)
}
}
// Business logic with validation
lifecycleScope.launch {
val result = userRepository.registerUser(
email = "user@example.com",
username = "username",
fullName = "Full Name"
)
result.onSuccess { user ->
Helpers.showToast(this@Activity, "User registered!")
}.onFailure { error ->
Helpers.showToast(this@Activity, error.message ?: "Error")
}
}Implemented clean architecture with clear separation:
βββββββββββββββββββββββββββββββββββ
β UI Layer (Activity/Fragment) β
ββββββββββββββ¬βββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββ
β Repository (Business Logic) β β Validation, data transformation
ββββββββββββββ¬βββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββ
β DAO (Database Access) β β SQL queries
ββββββββββββββ¬βββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββ
β Room Database (SQLite) β β Data storage
βββββββββββββββββββββββββββββββββββ
- β Suspend functions - All database ops use coroutines
- β Flow for reactive data - Auto-updates when data changes
- β Repository pattern - Business logic separation
- β Type safety - Compile-time SQL verification
- β Soft delete - Mark as deleted instead of permanent deletion
- β Timestamps - Track created/updated times
- β Indices - Fast queries on frequently searched fields
- β Transactions - Atomic operations
- β Error handling - Result for clean error management
- β Migration support - Schema versioning
- β Type converters - Handle complex types
- β Singleton pattern - Single database instance
1. Create Entity:
@Entity(tableName = "products", indices = [Index("sku", unique = true)])
data class Product(
@PrimaryKey(autoGenerate = true)
override val id: Long = 0,
val name: String,
val sku: String,
val price: Double,
override val createdAt: Date = Date(),
override val updatedAt: Date = Date(),
override val isDeleted: Boolean = false
) : BaseEntity2. Create DAO:
@Dao
interface ProductDao : BaseDao<Product> {
@Query("SELECT * FROM products WHERE isDeleted = 0")
fun getAllProducts(): Flow<List<Product>>
}3. Create Repository:
class ProductRepository(private val dao: ProductDao) : BaseRepository<Product>(dao) {
fun getAllProducts() = dao.getAllProducts()
}4. Add to AppDatabase:
@Database(entities = [User::class, Product::class], version = 2)
abstract class AppDatabase : RoomDatabase() {
abstract fun productDao(): ProductDao
}5. Use it:
val productRepo = ProductRepository(Helpers.getDatabase(this).productDao())- Email (unique, indexed)
- Username (unique, indexed)
- Full name, phone, bio
- Profile picture URL
- Auth token
- Email verification status
- Last login timestamp
- Created/Updated timestamps
- Soft delete flag
getDisplayName()- Returns full name or usernameisProfileComplete()- Check if all required fields filledisActive()- Check if user is verified and not deleted
seedDatabase()- Pre-populate with sample dataclearDatabase()- Remove all datagetDatabasePath()- Get database file locationgetDatabaseSize()- Get database file sizebackupDatabase()- Backup to external storagerestoreDatabase()- Restore from backupdeleteDatabase()- Delete database filegetDatabaseStats()- Get statistics (counts, size, etc.)exportToSQL()- Export data to SQL file
Check DATABASE_GUIDE.md for:
- Quick Start - Get up and running in 5 minutes
- Entity Creation - Step-by-step with examples
- DAO Queries - 20+ query patterns
- Repository Pattern - Business logic best practices
- Migrations - Handle schema changes safely
- Common Patterns - Real-world examples
- Troubleshooting - Solutions to common issues
- Testing - How to test database code
- β Complete CRUD operations
- β 30+ example queries
- β Search functionality
- β Filtering and sorting
- β Pagination support (via LIMIT)
- β Soft delete system
- β Timestamp tracking
- β Data validation
- β Error handling
- β Backup/restore
- β Database stats
- β Sample data seeding
- β Type-safe queries
- β Auto-completion in IDE
- β Compile-time verification
- β Easy to extend
- β Well documented
- β Best practices built-in
- β Example implementations
- β Comprehensive guide
-
Explore the code:
db/entities/User.kt- See entity structuredb/dao/UserDao.kt- See query examplesdb/repository/UserRepository.kt- See business logic
-
Read DATABASE_GUIDE.md - Complete usage guide
-
Try it out:
lifecycleScope.launch { // Seed sample data DatabaseHelper.seedDatabase(this@MainActivity) // Get all users userRepository.getAllUsers().collect { users -> Log.d("DB", "Users: ${users.size}") } } -
Create your own entities - Follow the patterns
-
Integrate with your API - Sync network data to database
You now have a production-ready Room database implementation with:
- β¨ 10 new files with 40KB+ of code
- β¨ Complete CRUD operations
- β¨ 30+ example query methods
- β¨ Business logic layer
- β¨ Database utilities
- β¨ Type converters
- β¨ 400+ lines of documentation
- β¨ Best practices throughout
- β¨ Easy to customize and extend
The database layer is complete and ready to use! π
Check DATABASE_GUIDE.md for complete usage instructions and examples.