android-sdd 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/dist/index.js +143 -0
  2. package/package.json +27 -0
  3. package/skills/Android Ecosystem/Baseline Profile Generator/SKILL.md +277 -0
  4. package/skills/Android Ecosystem/Glance/SKILL.md +315 -0
  5. package/skills/Android Platform/Configuration/SKILL.md +201 -0
  6. package/skills/Android Platform/Filesystem/SKILL.md +216 -0
  7. package/skills/Android Platform/Lifecycle/SKILL.md +233 -0
  8. package/skills/Android Platform/Manifest/SKILL.md +226 -0
  9. package/skills/Android Platform/Process Death Recovery/SKILL.md +214 -0
  10. package/skills/Android Platform/Resources/SKILL.md +234 -0
  11. package/skills/Android Platform/SavedStateHandle/SKILL.md +217 -0
  12. package/skills/Android Platform/State Restoration/SKILL.md +210 -0
  13. package/skills/Architecture/Bounded Context/SKILL.md +207 -0
  14. package/skills/Architecture/Clean Architecture/SKILL.md +229 -0
  15. package/skills/Architecture/Domain Modeling/SKILL.md +236 -0
  16. package/skills/Architecture/Entity Design/SKILL.md +243 -0
  17. package/skills/Architecture/Feature Isolation/SKILL.md +216 -0
  18. package/skills/Architecture/MVI/SKILL.md +224 -0
  19. package/skills/Architecture/MVVM/SKILL.md +198 -0
  20. package/skills/Architecture/Modularization/SKILL.md +194 -0
  21. package/skills/Architecture/Offline First/SKILL.md +249 -0
  22. package/skills/Architecture/Repository Pattern/SKILL.md +216 -0
  23. package/skills/Architecture/Side Effect Management/SKILL.md +278 -0
  24. package/skills/Architecture/State Management/SKILL.md +229 -0
  25. package/skills/Architecture/Unidirectional Data Flow/SKILL.md +196 -0
  26. package/skills/Architecture/Use Case Design/SKILL.md +244 -0
  27. package/skills/Architecture/Value Object/SKILL.md +226 -0
  28. package/skills/Build Infrastructure/Build Orchestration/SKILL.md +257 -0
  29. package/skills/Build Infrastructure/Dependency Compatibility Resolver/SKILL.md +259 -0
  30. package/skills/Build Infrastructure/Environment Validator/SKILL.md +311 -0
  31. package/skills/Build System/Build Cache/SKILL.md +233 -0
  32. package/skills/Build System/Build Flavor Strategy/SKILL.md +171 -0
  33. package/skills/Build System/Build Variant/SKILL.md +215 -0
  34. package/skills/Build System/Convention Plugin/SKILL.md +288 -0
  35. package/skills/Build System/Dependency Management/SKILL.md +261 -0
  36. package/skills/Build System/Gradle/SKILL.md +284 -0
  37. package/skills/Build System/Incremental Build/SKILL.md +199 -0
  38. package/skills/Build System/KAPT/SKILL.md +198 -0
  39. package/skills/Build System/KSP/SKILL.md +263 -0
  40. package/skills/Build System/Module Dependency Graph Validation/SKILL.md +223 -0
  41. package/skills/Build System/Specialized/C++/SKILL.md +308 -0
  42. package/skills/Build System/Specialized/JNI/SKILL.md +306 -0
  43. package/skills/Build System/Specialized/NDK/SKILL.md +264 -0
  44. package/skills/Build System/Version Catalog/SKILL.md +304 -0
  45. package/skills/Concurrency/Background Processing/SKILL.md +185 -0
  46. package/skills/Concurrency/Channel/SKILL.md +207 -0
  47. package/skills/Concurrency/Coroutine/SKILL.md +200 -0
  48. package/skills/Concurrency/Flow/SKILL.md +179 -0
  49. package/skills/Concurrency/Mutex Strategy/SKILL.md +185 -0
  50. package/skills/Concurrency/SharedFlow/SKILL.md +171 -0
  51. package/skills/Concurrency/StateFlow/SKILL.md +175 -0
  52. package/skills/Concurrency/Structured Concurrency/SKILL.md +197 -0
  53. package/skills/Concurrency/Synchronization Policy/SKILL.md +192 -0
  54. package/skills/Core Language/Annotation Processing/SKILL.md +224 -0
  55. package/skills/Core Language/DSL/SKILL.md +186 -0
  56. package/skills/Core Language/Extension Functions Design/SKILL.md +191 -0
  57. package/skills/Core Language/Immutability/SKILL.md +156 -0
  58. package/skills/Core Language/KMP/SKILL.md +182 -0
  59. package/skills/Core Language/Kotlin/SKILL.md +187 -0
  60. package/skills/Core Language/Reactive State Management/SKILL.md +228 -0
  61. package/skills/Core Language/Reactive Streams/SKILL.md +235 -0
  62. package/skills/Core Language/Serialization/SKILL.md +191 -0
  63. package/skills/Data Layer/Cache Strategy/SKILL.md +261 -0
  64. package/skills/Data Layer/Conflict Resolution/SKILL.md +248 -0
  65. package/skills/Data Layer/DAO/SKILL.md +225 -0
  66. package/skills/Data Layer/DTO Mapping/SKILL.md +269 -0
  67. package/skills/Data Layer/DataStore/SKILL.md +264 -0
  68. package/skills/Data Layer/Database Versioning Strategy/SKILL.md +215 -0
  69. package/skills/Data Layer/Encrypted Database/SKILL.md +212 -0
  70. package/skills/Data Layer/File Storage/SKILL.md +247 -0
  71. package/skills/Data Layer/Indexing/SKILL.md +184 -0
  72. package/skills/Data Layer/Key-Value Store Strategy/SKILL.md +185 -0
  73. package/skills/Data Layer/Merge Strategy/SKILL.md +240 -0
  74. package/skills/Data Layer/Migration/SKILL.md +243 -0
  75. package/skills/Data Layer/Paging/SKILL.md +264 -0
  76. package/skills/Data Layer/Proto DataStore/SKILL.md +250 -0
  77. package/skills/Data Layer/Room/SKILL.md +244 -0
  78. package/skills/Data Layer/SQLite/SKILL.md +255 -0
  79. package/skills/Data Layer/Sync Engine/SKILL.md +268 -0
  80. package/skills/Dependency Injection/Dagger/SKILL.md +283 -0
  81. package/skills/Dependency Injection/Hilt/SKILL.md +345 -0
  82. package/skills/Dependency Injection/Koin/SKILL.md +282 -0
  83. package/skills/Developer Experience/Detekt/SKILL.md +272 -0
  84. package/skills/Developer Experience/Lint Rule/SKILL.md +281 -0
  85. package/skills/Google Ecosystem/Analytics/SKILL.md +281 -0
  86. package/skills/Google Ecosystem/Crashlytics/SKILL.md +234 -0
  87. package/skills/Google Ecosystem/Firebase/SKILL.md +200 -0
  88. package/skills/Google Ecosystem/Firebase Messaging/SKILL.md +266 -0
  89. package/skills/Media/Audio/SKILL.md +257 -0
  90. package/skills/Media/Camera/SKILL.md +229 -0
  91. package/skills/Media/CameraX/SKILL.md +295 -0
  92. package/skills/Media/ExoPlayer/SKILL.md +258 -0
  93. package/skills/Media/Video/SKILL.md +228 -0
  94. package/skills/Meta Skills/Domain Error Model/SKILL.md +238 -0
  95. package/skills/Meta Skills/Error Handling/SKILL.md +255 -0
  96. package/skills/Meta Skills/Error Mapping/SKILL.md +232 -0
  97. package/skills/Meta Skills/Failure Strategy/SKILL.md +294 -0
  98. package/skills/Meta Skills/Migration Strategy/SKILL.md +305 -0
  99. package/skills/Meta Skills/User Friendly Errors/SKILL.md +334 -0
  100. package/skills/Navigation/Deep Navigation/SKILL.md +209 -0
  101. package/skills/Navigation/Navigation/SKILL.md +215 -0
  102. package/skills/Navigation/Nested Navigation/SKILL.md +214 -0
  103. package/skills/Networking/API Contract/SKILL.md +220 -0
  104. package/skills/Networking/Authentication/SKILL.md +210 -0
  105. package/skills/Networking/Certificate Pinning/SKILL.md +167 -0
  106. package/skills/Networking/Fallback Strategy/SKILL.md +182 -0
  107. package/skills/Networking/Ktor/SKILL.md +219 -0
  108. package/skills/Networking/Multipart Upload/SKILL.md +213 -0
  109. package/skills/Networking/OkHttp/SKILL.md +193 -0
  110. package/skills/Networking/REST/SKILL.md +178 -0
  111. package/skills/Networking/Rate Limiting/SKILL.md +170 -0
  112. package/skills/Networking/Retrofit/SKILL.md +241 -0
  113. package/skills/Networking/Retry-Backoff/SKILL.md +181 -0
  114. package/skills/Networking/Server-Sent Events (SSE)/SKILL.md +196 -0
  115. package/skills/Networking/WebSocket/SKILL.md +224 -0
  116. package/skills/Observability/Crash Reporting/SKILL.md +219 -0
  117. package/skills/Observability/Logging/SKILL.md +168 -0
  118. package/skills/Observability/Metrics/SKILL.md +227 -0
  119. package/skills/Observability/Structured Logging/SKILL.md +234 -0
  120. package/skills/Performance/ANR Prevention/SKILL.md +192 -0
  121. package/skills/Performance/Allocation Optimization/SKILL.md +179 -0
  122. package/skills/Performance/App Startup/SKILL.md +183 -0
  123. package/skills/Performance/Baseline Profile/SKILL.md +205 -0
  124. package/skills/Performance/Battery Optimization/SKILL.md +192 -0
  125. package/skills/Performance/Benchmark/SKILL.md +182 -0
  126. package/skills/Performance/Bitmap Optimization/SKILL.md +178 -0
  127. package/skills/Performance/Compose Optimization/SKILL.md +187 -0
  128. package/skills/Performance/Heap Management/SKILL.md +184 -0
  129. package/skills/Performance/Macrobenchmark/SKILL.md +214 -0
  130. package/skills/Performance/Memory Leak Prevention/SKILL.md +218 -0
  131. package/skills/Performance/Rendering Performance/SKILL.md +205 -0
  132. package/skills/Performance/Startup Optimization/SKILL.md +219 -0
  133. package/skills/Security/Biometric/SKILL.md +224 -0
  134. package/skills/Security/Certificate Transparency/SKILL.md +158 -0
  135. package/skills/Security/Cryptography/SKILL.md +244 -0
  136. package/skills/Security/Encrypted Storage/SKILL.md +273 -0
  137. package/skills/Security/Frida Detection/SKILL.md +230 -0
  138. package/skills/Security/Hook Detection/SKILL.md +197 -0
  139. package/skills/Security/Keystore/SKILL.md +272 -0
  140. package/skills/Security/Network Security Config/SKILL.md +186 -0
  141. package/skills/Security/Obfuscation/SKILL.md +226 -0
  142. package/skills/Security/Proguard/SKILL.md +202 -0
  143. package/skills/Security/R8/SKILL.md +234 -0
  144. package/skills/Security/Reverse Engineering Resistance/SKILL.md +267 -0
  145. package/skills/Security/Root Detection/SKILL.md +220 -0
  146. package/skills/Security/Secure Networking/SKILL.md +220 -0
  147. package/skills/System Integration/AlarmManager/SKILL.md +182 -0
  148. package/skills/System Integration/App Widget/SKILL.md +182 -0
  149. package/skills/System Integration/Deep Link/SKILL.md +187 -0
  150. package/skills/System Integration/Foreground Service/SKILL.md +212 -0
  151. package/skills/System Integration/Notification/SKILL.md +237 -0
  152. package/skills/System Integration/WorkManager/SKILL.md +256 -0
  153. package/skills/System Integration/clipboard/SKILL.md +155 -0
  154. package/skills/System Integration/share-intent/SKILL.md +182 -0
  155. package/skills/Testing/Compose Testing/SKILL.md +296 -0
  156. package/skills/Testing/Espresso/SKILL.md +292 -0
  157. package/skills/Testing/Fake Data/SKILL.md +245 -0
  158. package/skills/Testing/Integration Testing/SKILL.md +288 -0
  159. package/skills/Testing/Mocking/SKILL.md +229 -0
  160. package/skills/Testing/Snapshot Testing/SKILL.md +259 -0
  161. package/skills/Testing/UI Testing/SKILL.md +293 -0
  162. package/skills/Testing/Unit Testing/SKILL.md +309 -0
  163. package/skills/UI System/Bottom Sheet Patterns/SKILL.md +279 -0
  164. package/skills/UI System/Compose/SKILL.md +296 -0
  165. package/skills/UI System/Compose Animation/SKILL.md +281 -0
  166. package/skills/UI System/Compose Multiplatform/SKILL.md +261 -0
  167. package/skills/UI System/Compose Navigation/SKILL.md +255 -0
  168. package/skills/UI System/Compose Performance/SKILL.md +274 -0
  169. package/skills/UI System/Design System/SKILL.md +217 -0
  170. package/skills/UI System/Empty State Strategy/SKILL.md +208 -0
  171. package/skills/UI System/Keyboard Navigation/SKILL.md +214 -0
  172. package/skills/UI System/Loading Strategy/SKILL.md +254 -0
  173. package/skills/UI System/Material 3/SKILL.md +279 -0
  174. package/skills/UI System/RTL/SKILL.md +179 -0
  175. package/src/index.ts +182 -0
  176. package/tsconfig.json +19 -0
@@ -0,0 +1,244 @@
1
+ ---
2
+ name: room
3
+ description: >
4
+ Room database setup, configuration, and best practices for Android.
5
+ Load this skill when setting up Room, defining entities, configuring
6
+ the database class, handling migrations, or integrating Room with
7
+ repositories and coroutines/Flow.
8
+ ---
9
+
10
+ # Room
11
+
12
+ ## Overview
13
+ Room is Android's SQLite abstraction library. It provides compile-time SQL verification, coroutine/Flow support, and migration tooling. Room is the standard local database solution for Android and works as the offline-first data source in a Repository pattern.
14
+
15
+ ---
16
+
17
+ ## Core Principles
18
+
19
+ - Room operations must always run on **Dispatchers.IO** — never main thread
20
+ - Expose **Flow** from DAOs for observable queries — never suspend for reactive data
21
+ - Use **suspend** for one-shot write operations (insert, update, delete)
22
+ - Never expose entities outside the data layer — map to domain models in Repository
23
+ - Always define **indices** on columns used in WHERE and JOIN clauses
24
+
25
+ ---
26
+
27
+ ## Setup
28
+
29
+ ```toml
30
+ # libs.versions.toml
31
+ [versions]
32
+ room = "2.6.1"
33
+
34
+ [libraries]
35
+ room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
36
+ room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
37
+ room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
38
+
39
+ [plugins]
40
+ ksp = { id = "com.google.devtools.ksp", version = "2.0.0-1.0.21" }
41
+ ```
42
+
43
+ ```kotlin
44
+ // build.gradle.kts
45
+ plugins {
46
+ alias(libs.plugins.ksp)
47
+ }
48
+
49
+ dependencies {
50
+ implementation(libs.room.runtime)
51
+ implementation(libs.room.ktx)
52
+ ksp(libs.room.compiler)
53
+ }
54
+
55
+ // ✅ Schema export — for migration verification
56
+ ksp {
57
+ arg("room.schemaLocation", "$projectDir/schemas")
58
+ arg("room.incremental", "true")
59
+ }
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Entity
65
+
66
+ ```kotlin
67
+ // ✅ Entity — maps to a database table
68
+ @Entity(
69
+ tableName = "users",
70
+ indices = [
71
+ Index(value = ["email"], unique = true),
72
+ Index(value = ["status"])
73
+ ]
74
+ )
75
+ data class UserEntity(
76
+ @PrimaryKey val id: String,
77
+ @ColumnInfo(name = "full_name") val name: String,
78
+ @ColumnInfo(name = "email") val email: String,
79
+ @ColumnInfo(name = "status") val status: String,
80
+ @ColumnInfo(name = "created_at") val createdAt: Long,
81
+ @ColumnInfo(name = "updated_at") val updatedAt: Long
82
+ )
83
+
84
+ // ✅ Embedded object
85
+ data class Address(
86
+ val street: String,
87
+ val city: String,
88
+ val country: String
89
+ )
90
+
91
+ @Entity(tableName = "users")
92
+ data class UserEntity(
93
+ @PrimaryKey val id: String,
94
+ val name: String,
95
+ @Embedded val address: Address
96
+ )
97
+
98
+ // ✅ Relation — one-to-many
99
+ data class UserWithOrders(
100
+ @Embedded val user: UserEntity,
101
+ @Relation(
102
+ parentColumn = "id",
103
+ entityColumn = "user_id"
104
+ )
105
+ val orders: List<OrderEntity>
106
+ )
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Database Class
112
+
113
+ ```kotlin
114
+ // ✅ Database definition
115
+ @Database(
116
+ entities = [
117
+ UserEntity::class,
118
+ OrderEntity::class,
119
+ ProductEntity::class
120
+ ],
121
+ version = 3,
122
+ exportSchema = true // always true — needed for migration testing
123
+ )
124
+ @TypeConverters(Converters::class)
125
+ abstract class AppDatabase : RoomDatabase() {
126
+
127
+ abstract fun userDao(): UserDao
128
+ abstract fun orderDao(): OrderDao
129
+ abstract fun productDao(): ProductDao
130
+
131
+ companion object {
132
+ @Volatile
133
+ private var INSTANCE: AppDatabase? = null
134
+
135
+ fun getInstance(context: Context): AppDatabase {
136
+ return INSTANCE ?: synchronized(this) {
137
+ Room.databaseBuilder(
138
+ context.applicationContext,
139
+ AppDatabase::class.java,
140
+ "app_database"
141
+ )
142
+ .addMigrations(MIGRATION_1_2, MIGRATION_2_3)
143
+ .fallbackToDestructiveMigrationOnDowngrade()
144
+ .build()
145
+ .also { INSTANCE = it }
146
+ }
147
+ }
148
+ }
149
+ }
150
+
151
+ // ✅ With Hilt — preferred over manual singleton
152
+ @Module
153
+ @InstallIn(SingletonComponent::class)
154
+ object DatabaseModule {
155
+
156
+ @Provides
157
+ @Singleton
158
+ fun provideDatabase(@ApplicationContext context: Context): AppDatabase =
159
+ Room.databaseBuilder(context, AppDatabase::class.java, "app_database")
160
+ .addMigrations(MIGRATION_1_2, MIGRATION_2_3)
161
+ .build()
162
+
163
+ @Provides
164
+ fun provideUserDao(database: AppDatabase): UserDao = database.userDao()
165
+ }
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Type Converters
171
+
172
+ ```kotlin
173
+ // ✅ For types Room can't store natively
174
+ class Converters {
175
+
176
+ @TypeConverter
177
+ fun fromTimestamp(value: Long?): Date? =
178
+ value?.let { Date(it) }
179
+
180
+ @TypeConverter
181
+ fun dateToTimestamp(date: Date?): Long? =
182
+ date?.time
183
+
184
+ @TypeConverter
185
+ fun fromStringList(value: String): List<String> =
186
+ Json.decodeFromString(value)
187
+
188
+ @TypeConverter
189
+ fun toStringList(list: List<String>): String =
190
+ Json.encodeToString(list)
191
+ }
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Integration with Repository
197
+
198
+ ```kotlin
199
+ // ✅ Repository maps Entity ↔ Domain model
200
+ class UserRepository @Inject constructor(
201
+ private val userDao: UserDao,
202
+ private val userMapper: UserMapper
203
+ ) {
204
+
205
+ // Observable query — Flow
206
+ fun observeUsers(): Flow<List<User>> =
207
+ userDao.observeAll()
208
+ .map { entities -> entities.map { userMapper.toDomain(it) } }
209
+
210
+ // One-shot read
211
+ suspend fun getUserById(id: String): User? =
212
+ userDao.getById(id)?.let { userMapper.toDomain(it) }
213
+
214
+ // Write operations
215
+ suspend fun saveUser(user: User) {
216
+ userDao.upsert(userMapper.toEntity(user))
217
+ }
218
+
219
+ suspend fun deleteUser(id: String) {
220
+ userDao.deleteById(id)
221
+ }
222
+ }
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Anti-Patterns
228
+
229
+ - Running Room queries on the main thread — causes ANR
230
+ - Exposing `UserEntity` outside the data layer — couples UI to DB schema
231
+ - Using `allowMainThreadQueries()` — only acceptable in tests
232
+ - Not exporting schema (`exportSchema = false`) — can't write or test migrations
233
+ - Missing indices on queried columns — slow queries on large datasets
234
+ - Using `@PrimaryKey(autoGenerate = true)` with String IDs — use UUID instead
235
+ - Accessing database instance directly from ViewModel — always go through Repository
236
+
237
+ ---
238
+
239
+ ## Related Skills
240
+ - `dao` — DAO queries and operations
241
+ - `migration` — database schema migrations
242
+ - `dto-mapping` — Entity ↔ Domain mapping
243
+ - `repository-pattern` — Repository wrapping Room
244
+ - `hilt` — injecting Room database and DAOs
@@ -0,0 +1,255 @@
1
+ ---
2
+ name: sqlite
3
+ description: >
4
+ SQLite fundamentals and direct SQLite usage in Android.
5
+ Load this skill when working with raw SQLite queries, SupportSQLiteDatabase
6
+ in migrations, understanding SQLite constraints, or diagnosing SQL issues
7
+ that go beyond Room's abstraction.
8
+ ---
9
+
10
+ # SQLite
11
+
12
+ ## Overview
13
+ SQLite is the embedded relational database engine used by Android. Room is built on top of SQLite and handles most use cases. Direct SQLite access is needed in migrations, performance diagnostics, and edge cases that Room doesn't cover. Understanding SQLite's constraints prevents data integrity bugs.
14
+
15
+ ---
16
+
17
+ ## Core Principles
18
+
19
+ - Prefer Room over raw SQLite — use raw SQLite only when Room is insufficient
20
+ - SQLite is **not thread-safe** — always use Room's dispatcher management
21
+ - SQLite uses **dynamic typing** — enforce types via constraints, not the engine
22
+ - SQLite does **not enforce foreign keys by default** — must be enabled explicitly
23
+ - Transactions are the primary tool for performance and atomicity
24
+
25
+ ---
26
+
27
+ ## SQLite Type System
28
+
29
+ ```sql
30
+ -- SQLite storage classes (not strict types)
31
+ NULL -- null value
32
+ INTEGER -- signed integer (1, 2, 3, 4, 6, or 8 bytes)
33
+ REAL -- floating point (8-byte IEEE 754)
34
+ TEXT -- UTF-8/16 string
35
+ BLOB -- binary data
36
+
37
+ -- Room maps Kotlin types to SQLite:
38
+ -- String → TEXT
39
+ -- Int → INTEGER
40
+ -- Long → INTEGER
41
+ -- Double → REAL
42
+ -- Boolean → INTEGER (0 or 1)
43
+ -- ByteArray → BLOB
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Foreign Keys — Must Be Enabled
49
+
50
+ ```kotlin
51
+ // ✅ Enable foreign key enforcement in Room
52
+ Room.databaseBuilder(context, AppDatabase::class.java, "app_database")
53
+ .addCallback(object : RoomDatabase.Callback() {
54
+ override fun onOpen(db: SupportSQLiteDatabase) {
55
+ db.execSQL("PRAGMA foreign_keys = ON")
56
+ }
57
+ })
58
+ .build()
59
+
60
+ // Without this, foreign key constraints are silently ignored
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Direct SQL in Migrations
66
+
67
+ ```kotlin
68
+ val MIGRATION_3_4 = object : Migration(3, 4) {
69
+ override fun migrate(database: SupportSQLiteDatabase) {
70
+
71
+ // ✅ Create table
72
+ database.execSQL("""
73
+ CREATE TABLE IF NOT EXISTS products (
74
+ id TEXT NOT NULL PRIMARY KEY,
75
+ name TEXT NOT NULL,
76
+ price INTEGER NOT NULL DEFAULT 0,
77
+ category TEXT NOT NULL,
78
+ created_at INTEGER NOT NULL
79
+ )
80
+ """)
81
+
82
+ // ✅ Add column
83
+ database.execSQL("ALTER TABLE users ADD COLUMN avatar_url TEXT")
84
+
85
+ // ✅ Create index
86
+ database.execSQL(
87
+ "CREATE INDEX IF NOT EXISTS index_products_category ON products(category)"
88
+ )
89
+
90
+ // ✅ Create unique index
91
+ database.execSQL(
92
+ "CREATE UNIQUE INDEX IF NOT EXISTS index_users_email ON users(email)"
93
+ )
94
+
95
+ // ✅ Drop index
96
+ database.execSQL("DROP INDEX IF EXISTS old_index_name")
97
+
98
+ // ✅ Drop table
99
+ database.execSQL("DROP TABLE IF EXISTS old_table")
100
+
101
+ // ✅ Rename table (within migration)
102
+ database.execSQL("ALTER TABLE users_temp RENAME TO users")
103
+ }
104
+ }
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Rename Column (Pre-API 29)
110
+
111
+ ```kotlin
112
+ // SQLite supports RENAME COLUMN only from API 29 / SQLite 3.25.0
113
+ // For older support — recreate table
114
+
115
+ val MIGRATION_RENAME = object : Migration(5, 6) {
116
+ override fun migrate(database: SupportSQLiteDatabase) {
117
+ // 1. Create new table with correct schema
118
+ database.execSQL("""
119
+ CREATE TABLE users_new (
120
+ id TEXT NOT NULL PRIMARY KEY,
121
+ full_name TEXT NOT NULL, -- renamed from 'name'
122
+ email TEXT NOT NULL,
123
+ created_at INTEGER NOT NULL
124
+ )
125
+ """)
126
+ // 2. Copy data
127
+ database.execSQL("""
128
+ INSERT INTO users_new (id, full_name, email, created_at)
129
+ SELECT id, name, email, created_at FROM users
130
+ """)
131
+ // 3. Drop old table
132
+ database.execSQL("DROP TABLE users")
133
+ // 4. Rename new table
134
+ database.execSQL("ALTER TABLE users_new RENAME TO users")
135
+ // 5. Recreate indices
136
+ database.execSQL("CREATE INDEX index_users_email ON users(email)")
137
+ }
138
+ }
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Transactions for Performance
144
+
145
+ ```kotlin
146
+ // ✅ Wrap bulk inserts in a transaction — dramatically faster
147
+ val MIGRATION_BULK = object : Migration(6, 7) {
148
+ override fun migrate(database: SupportSQLiteDatabase) {
149
+ database.beginTransaction()
150
+ try {
151
+ database.execSQL("ALTER TABLE orders ADD COLUMN tax INTEGER NOT NULL DEFAULT 0")
152
+ // backfill
153
+ database.execSQL("UPDATE orders SET tax = CAST(total * 0.09 AS INTEGER)")
154
+ database.setTransactionSuccessful()
155
+ } finally {
156
+ database.endTransaction()
157
+ }
158
+ }
159
+ }
160
+
161
+ // ✅ Room handles transactions via @Transaction in DAOs
162
+ // Use raw transactions only in migrations or SupportSQLiteDatabase contexts
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Useful PRAGMA Commands
168
+
169
+ ```sql
170
+ -- Check schema integrity
171
+ PRAGMA integrity_check;
172
+
173
+ -- Get table info (columns, types, constraints)
174
+ PRAGMA table_info(users);
175
+
176
+ -- List all tables
177
+ SELECT name FROM sqlite_master WHERE type='table';
178
+
179
+ -- List all indices
180
+ SELECT name FROM sqlite_master WHERE type='index';
181
+
182
+ -- Get foreign key list for a table
183
+ PRAGMA foreign_key_list(orders);
184
+
185
+ -- Check foreign key violations
186
+ PRAGMA foreign_key_check;
187
+
188
+ -- Get current database version (Room version)
189
+ PRAGMA user_version;
190
+
191
+ -- WAL mode — better concurrent read performance
192
+ PRAGMA journal_mode = WAL;
193
+ ```
194
+
195
+ ---
196
+
197
+ ## WAL Mode
198
+
199
+ ```kotlin
200
+ // ✅ Enable WAL (Write-Ahead Logging) for better read concurrency
201
+ Room.databaseBuilder(context, AppDatabase::class.java, "app_database")
202
+ .setJournalMode(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING)
203
+ .build()
204
+
205
+ // WAL benefits:
206
+ // - Readers don't block writers
207
+ // - Writers don't block readers
208
+ // - Better performance for concurrent access patterns
209
+ // Default in Room — explicitly set if needed
210
+ ```
211
+
212
+ ---
213
+
214
+ ## Querying System Tables
215
+
216
+ ```kotlin
217
+ // ✅ Check if a table exists (useful in migrations)
218
+ fun SupportSQLiteDatabase.tableExists(tableName: String): Boolean {
219
+ val cursor = query(
220
+ "SELECT name FROM sqlite_master WHERE type='table' AND name=?",
221
+ arrayOf(tableName)
222
+ )
223
+ return cursor.use { it.count > 0 }
224
+ }
225
+
226
+ // ✅ Check if a column exists (useful in migrations)
227
+ fun SupportSQLiteDatabase.columnExists(tableName: String, columnName: String): Boolean {
228
+ val cursor = query("PRAGMA table_info($tableName)", null)
229
+ return cursor.use { c ->
230
+ while (c.moveToNext()) {
231
+ if (c.getString(c.getColumnIndex("name")) == columnName) return true
232
+ }
233
+ false
234
+ }
235
+ }
236
+ ```
237
+
238
+ ---
239
+
240
+ ## Anti-Patterns
241
+
242
+ - Raw SQLite without Room — loses type safety, compile-time checks, and Flow support
243
+ - Not enabling foreign keys (`PRAGMA foreign_keys = ON`) — constraints silently ignored
244
+ - String concatenation in SQL — use parameterized queries to prevent SQL injection
245
+ - Bulk operations outside transactions — orders of magnitude slower
246
+ - Using `AUTOINCREMENT` keyword — use `INTEGER PRIMARY KEY` instead (simpler, faster)
247
+ - Assuming column order is stable — always use column names, not positions
248
+
249
+ ---
250
+
251
+ ## Related Skills
252
+ - `room` — Room as the primary SQLite abstraction
253
+ - `dao` — Room DAO for type-safe queries
254
+ - `migration` — using SupportSQLiteDatabase in migrations
255
+ - `indexing` — index creation and management