Use Jetpack DataStore for Session Storage (Optional)
import androidx.datastore.core.DataStoreimport androidx.datastore.preferences.core.Preferencesimport androidx.datastore.preferences.core.editimport androidx.datastore.preferences.core.stringPreferencesKeyimport androidx.datastore.preferences.preferencesDataStoreimport kotlinx.coroutines.flow.firstimport kotlinx.coroutines.flow.mapval Context.authDataStore: DataStore<Preferences> by preferencesDataStore(name = "insforge_auth")class DataStoreSessionStorage(private val context: Context) : SessionStorage { override suspend fun save(key: String, value: String) { context.authDataStore.edit { prefs -> prefs[stringPreferencesKey(key)] = value } } override suspend fun get(key: String): String? { return context.authDataStore.data.map { prefs -> prefs[stringPreferencesKey(key)] }.first() } override suspend fun remove(key: String) { context.authDataStore.edit { prefs -> prefs.remove(stringPreferencesKey(key)) } }}// Then use it in your InsForge clientinstall(Auth) { browserLauncher = ... persistSession = true sessionStorage = DataStoreSessionStorage(context)}
insert()
Insert new records into a table.
Examples
// Define your data class@Serializabledata class Post( val id: String? = null, val title: String, val content: String, @SerialName("created_at") val createdAt: String? = null)// Single insert (must wrap in list)val post = Post(title = "Hello World", content = "My first post!")val result = insforge.database .from("posts") .insertTyped(listOf(post)) .returning() .execute<Post>() // Returns List<Post>// Bulk insertval posts = listOf( Post(title = "First Post", content = "Hello everyone!"), Post(title = "Second Post", content = "Another update."))val result = insforge.database .from("posts") .insertTyped(posts) .returning() .execute<Post>() // Returns List<Post>
update()
Update existing records in a table.
Examples
import kotlinx.serialization.json.JsonPrimitiveimport kotlinx.serialization.json.buildJsonObjectimport kotlinx.serialization.json.put// Update by ID (using JsonPrimitive)val result = insforge.database .from("posts") .update(mapOf("title" to JsonPrimitive("Updated Title"))) .eq("id", postId) .returning() .execute<Post>() // Returns List<Post>// Update by ID (using buildJsonObject)val result = insforge.database .from("posts") .update(buildJsonObject { put("title", "Updated Title") }) .eq("id", postId) .returning() .execute<Post>() // Returns List<Post>// Update multipleval result = insforge.database .from("tasks") .update(buildJsonObject { put("status", "completed") }) .`in`("id", listOf("task-1", "task-2")) .returning() .execute<Task>() // Returns List<Task>
delete()
Delete records from a table.
Examples
// Delete by IDinsforge.database .from("posts") .delete() .eq("id", postId) .execute()// Delete with filterinsforge.database .from("sessions") .delete() .lt("expires_at", Date()) .execute()
select()
Query records from a table.
Examples
// Get all postsval posts = insforge.database .from("posts") .select() .execute<Post>() // Returns List<Post>// Specific columnsval posts = insforge.database .from("posts") .select("id, title, content") .execute<Post>() // Returns List<Post>// With relationships (typed)@Serializabledata class PostWithComments( val id: String, val title: String, val content: String, val comments: List<Comment>)val posts = insforge.database .from("posts") .select("*, comments(id, content)") .execute<PostWithComments>() // Returns List<PostWithComments>
executeRaw()
Execute SELECT query and return raw JSON array. Use this method when you need to work with dynamic/untyped data, such as queries with joins that return nested objects.
Examples
import kotlinx.serialization.json.jsonArrayimport kotlinx.serialization.json.jsonObjectimport kotlinx.serialization.json.jsonPrimitive// Query with relationships - raw JSON accessval result = insforge.database .from("tweets") .select("id, content, profiles!tweets_user_id_fkey(username)") .executeRaw() // Returns JsonArrayresult.forEach { element -> val obj = element.jsonObject val id = obj["id"]?.jsonPrimitive?.content val content = obj["content"]?.jsonPrimitive?.content val profile = obj["profiles"]?.jsonObject val username = profile?.get("username")?.jsonPrimitive?.content println("Tweet by $username: $content")}// Dynamic queries where structure is unknownval rawData = insforge.database .from("dynamic_table") .select() .executeRaw()// Process raw JSON as neededrawData.forEach { element -> val obj = element.jsonObject obj.keys.forEach { key -> println("$key: ${obj[key]}") }}
rpc()
Call PostgreSQL stored functions (RPC - Remote Procedure Call). This method allows you to directly invoke SQL functions defined in your database.
Signature
// Typed RPC call - deserializes response to specified typesuspend inline fun <reified T> rpc( functionName: String, args: Map<String, Any?>? = null): T// Raw RPC call - returns JsonElement for dynamic processingsuspend fun rpcRaw( functionName: String, args: Map<String, Any?>? = null): JsonElement
Parameters
functionName (String) - Name of the PostgreSQL function to call
args (Map\<String, Any?\>?, optional) - Arguments to pass to the function
Implementation details
No arguments: Uses GET request to /api/database/rpc/{functionName}
With arguments: Uses POST request with JSON body to /api/database/rpc/{functionName}
Examples
// Define response data classes@Serializabledata class UserStats( val totalPosts: Int, val totalLikes: Int, val joinedAt: String)@Serializabledata class User( val id: String, val name: String, val email: String)// Call function with parametersval stats = insforge.database.rpc<UserStats>( "get_user_stats", mapOf("user_id" to 123))println("Total posts: ${stats.totalPosts}")// Call function without parametersval users = insforge.database.rpc<List<User>>("get_all_active_users")users.forEach { user -> println("User: ${user.name}")}// Call function returning a single valueval count = insforge.database.rpc<Int>("count_active_posts")println("Active posts: $count")// Call function with multiple parametersval result = insforge.database.rpc<List<Post>>( "search_posts", mapOf( "search_term" to "kotlin", "limit" to 10, "offset" to 0 ))
rpcRaw() examples
Use rpcRaw() when the return type is dynamic or unknown at compile time.
import kotlinx.serialization.json.jsonArrayimport kotlinx.serialization.json.jsonObjectimport kotlinx.serialization.json.jsonPrimitive// Get raw JSON responseval result = insforge.database.rpcRaw( "some_dynamic_function", mapOf("param" to "value"))// Process based on actual response structurewhen (result) { is JsonArray -> { result.forEach { element -> val obj = element.jsonObject println("Item: ${obj["name"]?.jsonPrimitive?.content}") } } is JsonObject -> { println("Single result: ${result["data"]}") } is JsonPrimitive -> { println("Value: ${result.content}") }}// Handle complex nested structuresval complexResult = insforge.database.rpcRaw("get_dashboard_data")val dashboard = complexResult.jsonObjectval userCount = dashboard["user_count"]?.jsonPrimitive?.intval recentPosts = dashboard["recent_posts"]?.jsonArray