> ## Documentation Index
> Fetch the complete documentation index at: https://docs.insforge.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 数据库 SDK 参考

> 使用 InsForge Swift SDK 进行类型安全的数据库操作

## 安装

Add InsForge to your Swift Package Manager dependencies:

```swift theme={null}
dependencies: [
    .package(url: "https://github.com/insforge/insforge-swift.git", from: "0.0.9")
]
```

```swift theme={null}
import InsForge

let insforge = InsForgeClient(
    baseURL: URL(string: "https://your-app.insforge.app")!,
    anonKey: "your-anon-key"
)
```

### Enable Logging (Optional)

For debugging, you can configure the SDK log level and destination:

```swift theme={null}
let options = InsForgeClientOptions(
    global: .init(
        logLevel: .debug,
        logDestination: .osLog,
        logSubsystem: "com.example.MyApp"
    )
)

let insforge = InsForgeClient(
    baseURL: URL(string: "https://your-app.insforge.app")!,
    anonKey: "your-anon-key",
    options: options
)
```

**Log Levels:**

| Level       | Description                                 |
| ----------- | ------------------------------------------- |
| `.trace`    | Most verbose, includes all internal details |
| `.debug`    | Detailed information for debugging          |
| `.info`     | General operational information (default)   |
| `.warning`  | Warnings that don't prevent operation       |
| `.error`    | Errors that affect functionality            |
| `.critical` | Critical failures                           |

**Log Destinations:**

| Destination | Description                                                |
| ----------- | ---------------------------------------------------------- |
| `.console`  | Standard output (print)                                    |
| `.osLog`    | Apple's unified logging system (recommended for iOS/macOS) |
| `.none`     | Disable logging                                            |
| `.custom`   | Provide your own LogHandler factory                        |

<Note>
  Use `.info` or `.error` in production to avoid exposing sensitive data in logs.
</Note>

## 定义模型

使用 Swift 的 `Codable` 协议定义数据模型：

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

***

## insert()

向表中插入新记录。

### 参数

* `values` - 单个 Codable 对象或要插入的对象数组

### 示例

```swift theme={null}
// 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()

更新表中的现有记录。

### 示例

```swift theme={null}
// 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()

从表中删除记录。

### 示例

```swift theme={null}
// 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()

从表中查询记录。

### 示例

```swift theme={null}
// 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()

调用 PostgreSQL 存储函数（RPC - 远程过程调用）。此方法允许您直接调用在数据库中定义的 SQL 函数。

### 参数

* `functionName` (String) - 要调用的 PostgreSQL 函数的名称
* `args` (\[String: Any]?, optional) - 要传递给函数的参数

### 示例

```swift theme={null}
// 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()
```

### 实现详情

* **无参数**：使用 GET 请求到 `/api/database/rpc/{functionName}`
* **带参数**：使用 POST 请求，JSON 主体到 `/api/database/rpc/{functionName}`
* 对于返回数组或 void 的函数，使用 `execute()`
* 对于返回单个对象或值的函数，使用 `executeSingle()`

***

## 过滤器

| 过滤器                        | 描述                | 示例                                             |
| -------------------------- | ----------------- | ---------------------------------------------- |
| `.eq(column, value:)`      | 等于                | `.eq("status", value: "active")`               |
| `.neq(column, value:)`     | 不等于               | `.neq("status", value: "banned")`              |
| `.gt(column, value:)`      | 大于                | `.gt("age", value: 18)`                        |
| `.gte(column, value:)`     | 大于或等于             | `.gte("price", value: 100)`                    |
| `.lt(column, value:)`      | 小于                | `.lt("stock", value: 10)`                      |
| `.lte(column, value:)`     | 小于或等于             | `.lte("priority", value: 3)`                   |
| `.like(column, pattern:)`  | 区分大小写的模式          | `.like("name", pattern: "%Widget%")`           |
| `.ilike(column, pattern:)` | 不区分大小写的模式         | `.ilike("email", pattern: "%@gmail.com")`      |
| `.in(column, values:)`     | 值在数组中             | `.in("status", values: ["pending", "active"])` |
| `.is(column, value:)`      | 精确等于（用于 nil/bool） | `.is("deleted_at", value: nil)`                |

```swift theme={null}
// 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()
```

***

## 修饰符

| 修饰符                          | 描述   | 示例                                      |
| ---------------------------- | ---- | --------------------------------------- |
| `.order(column, ascending:)` | 排序结果 | `.order("createdAt", ascending: false)` |
| `.limit(count)`              | 限制行数 | `.limit(10)`                            |
| `.offset(count)`             | 跳过行数 | `.offset(20)`                           |
| `.range(from:, to:)`         | 范围分页 | `.range(from: 0, to: 9)`                |

```swift theme={null}
// 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()
```
