A lexicon-driven AppView for ATProto. happyview.dev
backfill firehose jetstream atproto appview oauth lexicon
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: add db.search, db.raw, db.backlinks, and toarray()

Trezy a5a3ca1c 88073d83

+80 -5
+80 -5
docs/guides/scripting.md
··· 58 58 59 59 Available in both queries and procedures: 60 60 61 - | Function | Returns | Description | 62 - | -------------- | ------- | ------------------------------------------------------------------- | 63 - | `now()` | string | Current UTC timestamp in ISO 8601 format | 64 - | `log(message)` | — | Log a message (appears in server logs at debug level) | 65 - | `TID()` | string | Generate a fresh AT Protocol TID (13-character sortable identifier) | 61 + | Function | Returns | Description | 62 + | ---------------- | ------- | ------------------------------------------------------------------- | 63 + | `now()` | string | Current UTC timestamp in ISO 8601 format | 64 + | `log(message)` | — | Log a message (appears in server logs at debug level) | 65 + | `TID()` | string | Generate a fresh AT Protocol TID (13-character sortable identifier) | 66 + | `toarray(table)` | table | Mark a table as a JSON array for serialization (see [below](#toarray)) | 67 + 68 + ### toarray 69 + 70 + Lua tables don't distinguish between arrays and objects. When a table is serialized to JSON, an empty table `{}` becomes a JSON object `{}` instead of an array `[]`. The `toarray()` function marks a table so it always serializes as a JSON array — even when empty. 71 + 72 + ```lua 73 + return { items = toarray(results) } 74 + -- With results: [{"name": "a"}, {"name": "b"}] 75 + -- Without results: {"items": []} (not {"items": {}}) 76 + ``` 77 + 78 + You don't need `toarray()` on results from `db.query`, `db.search`, `db.backlinks`, or `db.raw` — those already return properly marked arrays. Use it when you build a table yourself with `table.insert()`. 66 79 67 80 ## Record API 68 81 ··· 175 188 -- The returned table includes a "uri" field 176 189 ``` 177 190 191 + ### db.search 192 + 193 + ```lua 194 + local result = db.search({ 195 + collection = "xyz.statusphere.status", -- required 196 + field = "displayName", -- required: record field to search 197 + query = "alice", -- required: search term 198 + limit = 10, -- optional: max 100, default 10 199 + }) 200 + 201 + -- result.records — array of matching records, ranked by relevance: 202 + -- exact match > prefix match > contains match, then alphabetical 203 + ``` 204 + 205 + ### db.backlinks 206 + 207 + Find records that reference a given AT URI anywhere in their data. Useful for finding likes on a post, replies to a thread, or any record that links to another. 208 + 209 + ```lua 210 + local result = db.backlinks({ 211 + collection = "xyz.statusphere.status", -- required 212 + uri = "at://did:plc:abc/xyz.statusphere.status/foo", -- required: the URI to find references to 213 + did = "did:plc:abc", -- optional: filter by DID 214 + limit = 20, -- optional: max 100, default 20 215 + offset = 0, -- optional: for pagination 216 + }) 217 + 218 + -- result.records — array of records whose data contains the given URI 219 + -- result.cursor — present when more records exist 220 + ``` 221 + 222 + The search checks the full record data, so it works regardless of which field holds the reference (`subject`, `parent`, `reply.root`, etc.). 223 + 178 224 ### db.count 179 225 180 226 ```lua 181 227 local n = db.count("xyz.statusphere.status") 182 228 local n = db.count("xyz.statusphere.status", "did:plc:abc") -- filter by DID 183 229 ``` 230 + 231 + ### db.raw 232 + 233 + Run a raw SQL query against the database. Only `SELECT` statements are allowed. 234 + 235 + ```lua 236 + local rows = db.raw( 237 + "SELECT uri, did, record FROM records WHERE collection = $1 AND did = $2 LIMIT $3", 238 + { "xyz.statusphere.status", "did:plc:abc", 10 } 239 + ) 240 + 241 + for _, row in ipairs(rows) do 242 + -- row.uri, row.did, row.record (JSONB is returned as a Lua table) 243 + end 244 + ``` 245 + 246 + Parameters are passed as an array and bound to `$1`, `$2`, etc. Supported parameter types: strings, integers, numbers, booleans, and nil. 247 + 248 + Column types are mapped automatically: 249 + 250 + | Postgres type | Lua type | 251 + | ---------------------- | -------- | 252 + | `TEXT`, `VARCHAR` | string | 253 + | `INT4`, `INT8` | integer | 254 + | `FLOAT4`, `FLOAT8` | number | 255 + | `BOOL` | boolean | 256 + | `JSON`, `JSONB` | table | 257 + | `TIMESTAMPTZ` | string (ISO 8601) | 258 + | Other | string (fallback) | 184 259 185 260 ## Standard libraries 186 261