---
title: Database SDK Reference
description: Type-safe database operations using the InsForge Kotlin SDK
---

import KotlinSdkInstallation from '/snippets/kotlin-sdk-installation.mdx';


## Installation

<KotlinSdkInstallation />

## insert()

Insert new records into a table.

### Examples

```kotlin
// Define your data class
@Serializable
data 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 insert
val 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

```kotlin
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.buildJsonObject
import 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 multiple
val 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

```kotlin
// Delete by ID
insforge.database
    .from("posts")
    .delete()
    .eq("id", postId)
    .execute()

// Delete with filter
insforge.database
    .from("sessions")
    .delete()
    .lt("expires_at", Date())
    .execute()
```

---

## select()

Query records from a table.

### Examples

```kotlin
// Get all posts
val posts = insforge.database
    .from("posts")
    .select()
    .execute<Post>()  // Returns List<Post>

// Specific columns
val posts = insforge.database
    .from("posts")
    .select("id, title, content")
    .execute<Post>()  // Returns List<Post>

// With relationships (typed)
@Serializable
data 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

```kotlin
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive

// Query with relationships - raw JSON access
val result = insforge.database
    .from("tweets")
    .select("id, content, profiles!tweets_user_id_fkey(username)")
    .executeRaw()  // Returns JsonArray

result.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 unknown
val rawData = insforge.database
    .from("dynamic_table")
    .select()
    .executeRaw()

// Process raw JSON as needed
rawData.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

```kotlin
// Typed RPC call - deserializes response to specified type
suspend inline fun <reified T> rpc(
    functionName: String,
    args: Map<String, Any?>? = null
): T

// Raw RPC call - returns JsonElement for dynamic processing
suspend 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

```kotlin
// Define response data classes
@Serializable
data class UserStats(
    val totalPosts: Int,
    val totalLikes: Int,
    val joinedAt: String
)

@Serializable
data class User(
    val id: String,
    val name: String,
    val email: String
)

// Call function with parameters
val stats = insforge.database.rpc<UserStats>(
    "get_user_stats",
    mapOf("user_id" to 123)
)
println("Total posts: ${stats.totalPosts}")

// Call function without parameters
val users = insforge.database.rpc<List<User>>("get_all_active_users")
users.forEach { user ->
    println("User: ${user.name}")
}

// Call function returning a single value
val count = insforge.database.rpc<Int>("count_active_posts")
println("Active posts: $count")

// Call function with multiple parameters
val 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.

```kotlin
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive

// Get raw JSON response
val result = insforge.database.rpcRaw(
    "some_dynamic_function",
    mapOf("param" to "value")
)

// Process based on actual response structure
when (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 structures
val complexResult = insforge.database.rpcRaw("get_dashboard_data")
val dashboard = complexResult.jsonObject
val userCount = dashboard["user_count"]?.jsonPrimitive?.int
val recentPosts = dashboard["recent_posts"]?.jsonArray
```

---

## Filters

| Filter | Description | Example |
|--------|-------------|---------|
| `.eq(column, value)` | Equals | `.eq("status", "active")` |
| `.neq(column, value)` | Not equals | `.neq("status", "banned")` |
| `.gt(column, value)` | Greater than | `.gt("age", 18)` |
| `.gte(column, value)` | Greater than or equal | `.gte("price", 100)` |
| `.lt(column, value)` | Less than | `.lt("stock", 10)` |
| `.lte(column, value)` | Less than or equal | `.lte("priority", 3)` |
| `.like(column, pattern)` | Case-sensitive pattern | `.like("name", "%Widget%")` |
| `.ilike(column, pattern)` | Case-insensitive pattern | `.ilike("email", "%@gmail.com")` |
| `.in(column, list)` | Value in list | `.in("status", listOf("pending", "active"))` |
| `.isNull(column)` | Is null | `.isNull("deleted_at")` |

```kotlin
// Chain multiple filters
val products = insforge.database
    .from("products")
    .select()
    .eq("category", "electronics")
    .gte("price", 50)
    .lte("price", 500)
    .execute<Product>()  // Returns List<Product>
```

---

## Modifiers

| Modifier | Description | Example |
|----------|-------------|---------|
| `.order(column, ascending)` | Sort results | `.order("created_at", ascending = false)` |
| `.limit(count)` | Limit rows | `.limit(10)` |
| `.range(from, to)` | Pagination | `.range(0, 9)` |

```kotlin
// Pagination with sorting
val posts = insforge.database
    .from("posts")
    .select()
    .order("created_at", ascending = false)
    .range(0, 9)
    .limit(10)
    .execute<Post>()  // Returns List<Post>
```

