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

import SwiftSdkInstallation from '/snippets/swift-sdk-installation.mdx';

## Installation

<SwiftSdkInstallation />

## Define Models

Define your data models using Swift's `Codable` protocol:

```swift
struct Post: Codable {
    let id: String?
    let title: String
    let content: String
    let userId: String
    let createdAt: Date?
}
```

---

## insert()

Insert new records into a table.

### Parameters

- `values` - Single Codable object or array of objects to insert

### Examples

```swift
// Single insert
let post = Post(
    id: nil,
    title: "Hello World",
    content: "My first post!",
    userId: currentUserId,
    createdAt: nil
)
let inserted = try await insforge.database
    .from("posts")
    .insert(post)

// Bulk insert
let posts = [
    Post(id: nil, title: "First Post", content: "Hello everyone!", userId: currentUserId, createdAt: nil),
    Post(id: nil, title: "Second Post", content: "Another update.", userId: currentUserId, createdAt: nil)
]
let inserted = try await insforge.database
    .from("posts")
    .insert(posts)
```

---

## update()

Update existing records in a table.

### Examples

```swift
// Define update model
struct PostUpdate: Codable {
    let title: String
}

// Update by ID
let updated: [Post] = try await insforge.database
    .from("posts")
    .eq("id", value: postId)
    .update(PostUpdate(title: "Updated Title"))

// Update multiple records
struct TaskUpdate: Codable {
    let status: String
}

let updated: [Task] = try await insforge.database
    .from("tasks")
    .in("id", values: ["task-1", "task-2"])
    .update(TaskUpdate(status: "completed"))
```

---

## delete()

Delete records from a table.

### Examples

```swift
// Delete by ID
try await insforge.database
    .from("posts")
    .eq("id", value: postId)
    .delete()

// Delete with filter
try await insforge.database
    .from("sessions")
    .lt("expires_at", value: Date())
    .delete()
```

---

## select()

Query records from a table.

### Examples

```swift
// Get all posts
let posts: [Post] = try await insforge.database
    .from("posts")
    .select()
    .execute()

// Filter and sort
let recentPosts: [Post] = try await insforge.database
    .from("posts")
    .select()
    .eq("userId", value: currentUserId)
    .order("createdAt", ascending: false)
    .limit(20)
    .execute()

// Multiple filters
let activePosts: [Post] = try await insforge.database
    .from("posts")
    .select()
    .eq("userId", value: currentUserId)
    .eq("status", value: "published")
    .execute()

// Specific columns
let posts = try await insforge.database
    .from("posts")
    .select("id, title, content")
    .execute()

// With relationships
let posts = try await insforge.database
    .from("posts")
    .select("*, comments(id, content)")
    .execute()
```

---

## rpc()

Call PostgreSQL stored functions (RPC - Remote Procedure Call). This method allows you to directly invoke SQL functions defined in your database.

### Parameters

- `functionName` (String) - Name of the PostgreSQL function to call
- `args` ([String: Any]?, optional) - Arguments to pass to the function

### Examples

```swift
// Define response models
struct UserStats: Decodable {
    let totalPosts: Int
    let totalComments: Int
}

struct User: Decodable {
    let id: String
    let name: String
    let email: String
}

// Call function with parameters, returning array
let stats: [UserStats] = try await insforge.database
    .rpc("get_user_stats", args: ["user_id": "123"])
    .execute()

// Call function with parameters, returning single result
let stat: UserStats = try await insforge.database
    .rpc("get_user_stats", args: ["user_id": "123"])
    .executeSingle()

// Call function without parameters
let users: [User] = try await insforge.database
    .rpc("get_all_active_users")
    .execute()

// Call function with multiple parameters
let results: [Post] = try await insforge.database
    .rpc("search_posts", args: [
        "search_term": "swift",
        "limit": 10,
        "offset": 0
    ])
    .execute()

// Call function with no return value (void function)
try await insforge.database
    .rpc("cleanup_old_records", args: ["days": 30])
    .execute()

// Call function returning a single primitive value
let count: Int = try await insforge.database
    .rpc("count_active_posts")
    .executeSingle()
```

### 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}`
- Use `execute()` for functions returning arrays or void
- Use `executeSingle()` for functions returning a single object or value

---

## Filters

| Filter | Description | Example |
|--------|-------------|---------|
| `.eq(column, value:)` | Equals | `.eq("status", value: "active")` |
| `.neq(column, value:)` | Not equals | `.neq("status", value: "banned")` |
| `.gt(column, value:)` | Greater than | `.gt("age", value: 18)` |
| `.gte(column, value:)` | Greater than or equal | `.gte("price", value: 100)` |
| `.lt(column, value:)` | Less than | `.lt("stock", value: 10)` |
| `.lte(column, value:)` | Less than or equal | `.lte("priority", value: 3)` |
| `.like(column, pattern:)` | Case-sensitive pattern | `.like("name", pattern: "%Widget%")` |
| `.ilike(column, pattern:)` | Case-insensitive pattern | `.ilike("email", pattern: "%@gmail.com")` |
| `.in(column, values:)` | Value in array | `.in("status", values: ["pending", "active"])` |
| `.is(column, value:)` | Exactly equals (for nil/bool) | `.is("deleted_at", value: nil)` |

```swift
// Chain multiple filters
let products: [Product] = try await insforge.database
    .from("products")
    .select()
    .eq("category", value: "electronics")
    .gte("price", value: 50)
    .lte("price", value: 500)
    .execute()

// Pattern matching
let posts: [Post] = try await insforge.database
    .from("posts")
    .select()
    .ilike("title", pattern: "%swift%")
    .execute()

// Filter by multiple values
let tasks: [Task] = try await insforge.database
    .from("tasks")
    .select()
    .in("status", values: ["pending", "in_progress"])
    .execute()

// Check for null or boolean
let activePosts: [Post] = try await insforge.database
    .from("posts")
    .select()
    .is("deleted_at", value: nil)
    .is("published", value: true)
    .execute()
```

---

## Modifiers

| Modifier | Description | Example |
|----------|-------------|---------|
| `.order(column, ascending:)` | Sort results | `.order("createdAt", ascending: false)` |
| `.limit(count)` | Limit rows | `.limit(10)` |
| `.offset(count)` | Skip rows | `.offset(20)` |
| `.range(from:, to:)` | Range pagination | `.range(from: 0, to: 9)` |

```swift
// Pagination with sorting
let posts: [Post] = try await insforge.database
    .from("posts")
    .select()
    .order("createdAt", ascending: false)
    .limit(10)
    .offset(20)
    .execute()

// Range pagination (get items 10-19)
let posts: [Post] = try await insforge.database
    .from("posts")
    .select()
    .range(from: 10, to: 19)
    .execute()
```
