305 lines
7.1 KiB
Plaintext
305 lines
7.1 KiB
Plaintext
---
|
|
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()
|
|
```
|