feat(appwrite): create the abuse table schema inline - #120
Merged
Conversation
Appwrite now builds columns and indexes sent inline with create table from the same mapping the dedicated per-column endpoints use, so the workaround of create table + one request per column is no longer needed (appwrite/appwrite#13174). Setup now sends the whole schema with the table in a single request. Inline columns and indexes come back available, so the two polling loops are gone from the cold path. A table left over from a setup that did not run to completion still falls back to the per-column endpoints, since inline definitions only apply while the table is being created; both paths now read the schema from one list instead of restating it. Also bumps appwrite/appwrite to 27.1, and fixes the readiness poll: list responses carry raw payloads rather than hydrated models, so reading status as a property always yielded '' and the poll could only ever time out. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Greptile SummaryThe PR creates the Appwrite abuse-table schema inline while retaining incremental repair for existing partial tables.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Important Files Changed
Reviews (2): Last reviewed commit: "fix(tests): read listed indexes as model..." | Re-trigger Greptile |
listIndexes hydrates each entry into a ColumnIndex; listColumns does not, because the SDK has no single model for the union of column types. The schema assertions treated both as arrays. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
abnegate
approved these changes
Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
appwrite/appwrite#13174 moved the attribute type/format/size mapping into
Appwrite\Utopia\Database\Attribute, shared by the inline validator and the inline attribute builder. The PR calls out the cost of the old behaviour directly: callers hit a partially-executed request and "have to fall back tocreateTable+ N separate column calls". That fallback is exactly what this adapter did.setup()now sends the whole schema — three columns and two indexes — inline withcreateTable, in one request. Inline columns and indexes are created synchronously and land asavailable, so the twowaitForResourcesReady()polling loops are gone from the cold path. Setting up the abuse table drops from 6 requests plus up to 30s of polling to 2 requests.The dedicated per-column endpoints are still needed for one case: a table left behind by a
setup()that did not run to completion. Inline definitions only apply while the table is being created, so whencreateTablereportstable_already_existsthe adapter falls back to the old incremental path (which is what makes a partial setup self-heal today).createColumns()/createIndexes()now read that schema fromcolumnDefinitions()/indexDefinitions()rather than restating it, so the two paths cannot drift.executeWithSilentError()returns whether the call went through, which is howsetup()distinguishes the two cases.Also in here
appwrite/appwrite26.0 → 27.1. Every SDK method this adapter uses (createTable,create*Column,createIndex,listColumns,listIndexes,listRows,createRow,updateRow,incrementRowColumn,deleteRows) has an identical signature in 27.1; the 27.x changes are additive (dedicated database specifications, replicas, vector queries). Note the fix itself is server-side and needs no SDK change.ColumnIndexListhydrates each entry into aColumnIndex, butColumnListhands back the raw payloads — the SDK has no single model to hydrate the union of column types into.(string) $resource->statuson an array therefore yielded'', never'available', so once a column really was still processing the loop could only ever run out of attempts and throw.resourceStatus()reads the status off either shape.Tests
tests/Abuse/Appwrite/TablesDBTest.php:testSetupCreatesSchema— asserts the inline path produces the same columns and indexes the dedicated endpoints did:keystring(255) required,timedatetime required,countinteger required with min 0 / maxPHP_INT_MAX, a unique index overkey, timeand a key index overtime, all available.testSetupRepairsPartiallyCreatedTable— creates a bare table to stand in for a setup that died halfway, runssetup(), and asserts the fallback fills in every column and index and that rate limiting then works through the repaired table.testSetupIsIdempotent—setup()runs on every boot, so a second call must not duplicate or re-create anything.Green on 8.4 and 8.5 against the CI Appwrite endpoint, along with Pint, PHPStan (level max) and the benchmarks. The first push failed these three tests for the hydration reason above, which is what turned up the asymmetry between the two list endpoints; the second run needed one retry after a TLS reset mid-request on 8.5.
🤖 Generated with Claude Code