insforge 1.2.10 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +20 -20
- package/.dockerignore +60 -60
- package/.env.example +83 -77
- package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -36
- package/.github/ISSUE_TEMPLATE/config.yml +11 -11
- package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -26
- package/.github/PULL_REQUEST_TEMPLATE.md +7 -7
- package/.github/copilot-instructions.md +146 -146
- package/.github/workflows/build-image.yml +65 -65
- package/.github/workflows/ci-premerge-check.yml +23 -23
- package/.github/workflows/e2e.yml +63 -63
- package/.github/workflows/lint-and-format.yml +32 -32
- package/.prettierignore +64 -64
- package/CHANGELOG.md +44 -44
- package/CLAUDE_PLUGIN.md +104 -104
- package/CODE_OF_CONDUCT.md +128 -128
- package/CONTRIBUTING.md +125 -125
- package/Dockerfile +30 -30
- package/GITHUB_OAUTH_SETUP.md +49 -49
- package/GOOGLE_OAUTH_SETUP.md +148 -148
- package/LICENSE +201 -201
- package/README.md +182 -182
- package/assets/Dark.svg +23 -23
- package/auth/package.json +28 -28
- package/auth/src/lib/broadcastService.ts +117 -115
- package/auth/src/pages/SignInPage.tsx +60 -57
- package/auth/src/pages/SignUpPage.tsx +60 -57
- package/auth/tsconfig.json +32 -32
- package/auth/tsconfig.node.json +11 -11
- package/backend/package.json +78 -75
- package/backend/src/api/routes/ai/index.routes.ts +3 -3
- package/backend/src/api/routes/auth/index.routes.ts +667 -570
- package/backend/src/api/routes/auth/oauth.routes.ts +473 -448
- package/backend/src/api/routes/database/advance.routes.ts +37 -16
- package/backend/src/api/routes/database/index.routes.ts +78 -1
- package/backend/src/api/routes/database/records.routes.ts +10 -10
- package/backend/src/api/routes/database/tables.routes.ts +0 -14
- package/backend/src/api/routes/docs/index.routes.ts +75 -76
- package/backend/src/api/routes/email/index.routes.ts +35 -0
- package/backend/src/api/routes/functions/index.routes.ts +18 -12
- package/backend/src/api/routes/metadata/index.routes.ts +12 -0
- package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
- package/backend/src/api/routes/realtime/index.routes.ts +12 -0
- package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
- package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
- package/backend/src/api/routes/storage/index.routes.ts +18 -12
- package/backend/src/api/routes/usage/index.routes.ts +6 -4
- package/backend/src/infra/database/database.manager.ts +14 -1
- package/backend/src/infra/database/migrations/000_create-base-tables.sql +141 -141
- package/backend/src/infra/database/migrations/001_create-helper-functions.sql +40 -40
- package/backend/src/infra/database/migrations/002_rename-auth-tables.sql +29 -29
- package/backend/src/infra/database/migrations/003_create-users-table.sql +55 -55
- package/backend/src/infra/database/migrations/004_add-reload-postgrest-func.sql +23 -23
- package/backend/src/infra/database/migrations/005_enable-project-admin-modify-users.sql +29 -29
- package/backend/src/infra/database/migrations/006_modify-ai-usage-table.sql +24 -24
- package/backend/src/infra/database/migrations/007_drop-metadata-table.sql +1 -1
- package/backend/src/infra/database/migrations/008_add-system-tables.sql +76 -76
- package/backend/src/infra/database/migrations/009_add-function-secrets.sql +23 -23
- package/backend/src/infra/database/migrations/010_modify-ai-config-modalities.sql +93 -93
- package/backend/src/infra/database/migrations/011_refactor-secrets-table.sql +15 -15
- package/backend/src/infra/database/migrations/012_add-storage-uploaded-by.sql +7 -7
- package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -44
- package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +7 -7
- package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +59 -59
- package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -24
- package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
- package/backend/src/infra/realtime/realtime.manager.ts +246 -0
- package/backend/src/infra/realtime/webhook-sender.ts +82 -0
- package/backend/src/infra/security/token.manager.ts +219 -125
- package/backend/src/infra/socket/socket.manager.ts +198 -64
- package/backend/src/providers/ai/openrouter.provider.ts +12 -9
- package/backend/src/providers/email/base.provider.ts +4 -7
- package/backend/src/providers/email/cloud.provider.ts +84 -0
- package/backend/src/providers/oauth/apple.provider.ts +266 -0
- package/backend/src/providers/oauth/index.ts +1 -0
- package/backend/src/server.ts +317 -284
- package/backend/src/services/ai/ai-model.service.ts +5 -5
- package/backend/src/services/ai/chat-completion.service.ts +4 -4
- package/backend/src/services/ai/image-generation.service.ts +3 -3
- package/backend/src/services/auth/auth.service.ts +14 -0
- package/backend/src/services/database/database-table.service.ts +0 -9
- package/backend/src/services/database/database.service.ts +127 -0
- package/backend/src/services/email/email.service.ts +5 -7
- package/backend/src/services/realtime/index.ts +3 -0
- package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
- package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
- package/backend/src/services/realtime/realtime-message.service.ts +260 -0
- package/backend/src/types/auth.ts +11 -0
- package/backend/src/types/realtime.ts +18 -0
- package/backend/src/types/socket.ts +7 -31
- package/backend/src/utils/cookies.ts +35 -0
- package/backend/src/utils/s3-config-loader.ts +64 -0
- package/backend/src/utils/seed.ts +301 -298
- package/backend/src/utils/sql-parser.ts +90 -0
- package/backend/tests/README.md +133 -133
- package/backend/tests/cleanup-all-test-data.sh +230 -230
- package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
- package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
- package/backend/tests/local/test-ai-config.sh +129 -129
- package/backend/tests/local/test-ai-usage.sh +80 -80
- package/backend/tests/local/test-auth-router.sh +143 -143
- package/backend/tests/local/test-database-router.sh +222 -222
- package/backend/tests/local/test-e2e.sh +240 -240
- package/backend/tests/local/test-fk-errors.sh +96 -96
- package/backend/tests/local/test-functions.sh +123 -123
- package/backend/tests/local/test-id-field.sh +200 -200
- package/backend/tests/local/test-logs.sh +132 -132
- package/backend/tests/local/test-public-bucket.sh +264 -264
- package/backend/tests/local/test-secrets.sh +249 -249
- package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
- package/backend/tests/local/test-traditional-rest.sh +208 -208
- package/backend/tests/manual/README.md +50 -50
- package/backend/tests/manual/create-large-table-simple.sql +10 -10
- package/backend/tests/manual/seed-large-table.sql +100 -100
- package/backend/tests/manual/setup-large-table-extras.sql +33 -33
- package/backend/tests/manual/test-bulk-upsert.sh +409 -409
- package/backend/tests/manual/test-database-advance.sh +296 -296
- package/backend/tests/manual/test-postgrest-stability.sh +191 -191
- package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
- package/backend/tests/manual/test-rawsql-modes.sh +244 -244
- package/backend/tests/manual/test-universal-storage.sh +263 -263
- package/backend/tests/manual/test-users.sql +17 -17
- package/backend/tests/run-all-tests.sh +139 -139
- package/backend/tests/setup.ts +0 -0
- package/backend/tests/test-config.sh +338 -338
- package/backend/tests/unit/analyze-query.test.ts +697 -0
- package/backend/tsconfig.json +22 -22
- package/claude-plugin/.claude-plugin/plugin.json +24 -24
- package/claude-plugin/README.md +133 -133
- package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -270
- package/docker-compose.prod.yml +204 -200
- package/docker-compose.yml +232 -228
- package/docker-init/db/db-init.sql +97 -97
- package/docker-init/db/jwt.sql +5 -5
- package/docker-init/db/postgresql.conf +16 -16
- package/docker-init/logs/vector.yml +236 -236
- package/docs/README.md +44 -44
- package/docs/agent-docs/real-time.md +269 -0
- package/docs/changelog.mdx +119 -67
- package/docs/core-concepts/ai/architecture.mdx +372 -372
- package/docs/core-concepts/ai/sdk.mdx +213 -213
- package/docs/core-concepts/authentication/architecture.mdx +278 -278
- package/docs/core-concepts/authentication/sdk.mdx +414 -414
- package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -529
- package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -221
- package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -184
- package/docs/core-concepts/authentication/ui-components/react.mdx +129 -129
- package/docs/core-concepts/database/architecture.mdx +255 -255
- package/docs/core-concepts/database/sdk.mdx +382 -382
- package/docs/core-concepts/email/architecture.mdx +101 -0
- package/docs/core-concepts/email/sdk.mdx +53 -0
- package/docs/core-concepts/functions/architecture.mdx +105 -105
- package/docs/core-concepts/functions/sdk.mdx +184 -184
- package/docs/core-concepts/realtime/architecture.mdx +446 -0
- package/docs/core-concepts/realtime/sdk.mdx +409 -0
- package/docs/core-concepts/storage/architecture.mdx +243 -243
- package/docs/core-concepts/storage/sdk.mdx +253 -253
- package/docs/deployment/README.md +94 -94
- package/docs/deployment/deploy-to-aws-ec2.md +564 -564
- package/docs/deployment/deploy-to-azure-virtual-machines.md +312 -312
- package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -613
- package/docs/deployment/deploy-to-render.md +441 -441
- package/docs/deprecated/insforge-auth-api.md +214 -214
- package/docs/deprecated/insforge-auth-sdk.md +99 -99
- package/docs/deprecated/insforge-db-api.md +358 -358
- package/docs/deprecated/insforge-db-sdk.md +139 -139
- package/docs/deprecated/insforge-debug-sdk.md +156 -156
- package/docs/deprecated/insforge-debug.md +64 -64
- package/docs/deprecated/insforge-instructions.md +123 -123
- package/docs/deprecated/insforge-project.md +117 -117
- package/docs/deprecated/insforge-storage-api.md +278 -278
- package/docs/deprecated/insforge-storage-sdk.md +158 -158
- package/docs/docs.json +232 -210
- package/docs/examples/framework-guides/nextjs.mdx +131 -131
- package/docs/examples/framework-guides/nuxt.mdx +165 -165
- package/docs/examples/framework-guides/react.mdx +165 -165
- package/docs/examples/framework-guides/svelte.mdx +153 -153
- package/docs/examples/framework-guides/vue.mdx +159 -159
- package/docs/examples/overview.mdx +67 -67
- package/docs/favicon.svg +19 -19
- package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
- package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
- package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
- package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
- package/docs/images/changelog/dec-2025/mcp-installer.png +0 -0
- package/docs/images/changelog/dec-2025/realtime-module.jpg +0 -0
- package/docs/images/icons/ai.svg +4 -4
- package/docs/images/logos/nextjs.svg +4 -4
- package/docs/images/logos/nuxt.svg +4 -4
- package/docs/images/logos/react.svg +5 -5
- package/docs/images/logos/svelte.svg +4 -4
- package/docs/images/logos/vue.svg +5 -5
- package/docs/insforge-instructions-sdk.md +89 -88
- package/docs/introduction.mdx +45 -45
- package/docs/logo/dark.svg +22 -22
- package/docs/logo/light.svg +20 -20
- package/docs/partnership.mdx +651 -646
- package/docs/quickstart.mdx +82 -82
- package/docs/showcase.mdx +52 -52
- package/docs/snippets/sdk-installation.mdx +21 -21
- package/docs/snippets/service-icons.mdx +27 -27
- package/examples/oauth/frontend-oauth-example.html +250 -250
- package/examples/response-examples.md +443 -443
- package/frontend/components.json +17 -17
- package/frontend/package.json +69 -69
- package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
- package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
- package/frontend/src/assets/icons/checked.svg +3 -3
- package/frontend/src/assets/icons/connected.svg +3 -3
- package/frontend/src/assets/icons/error.svg +3 -3
- package/frontend/src/assets/icons/loader.svg +9 -9
- package/frontend/src/assets/icons/pencil.svg +4 -4
- package/frontend/src/assets/icons/refresh.svg +4 -4
- package/frontend/src/assets/icons/step_active.svg +3 -3
- package/frontend/src/assets/icons/step_inactive.svg +11 -11
- package/frontend/src/assets/icons/warning.svg +3 -3
- package/frontend/src/assets/logos/apple.svg +3 -3
- package/frontend/src/assets/logos/claude_code.svg +3 -3
- package/frontend/src/assets/logos/cline.svg +6 -6
- package/frontend/src/assets/logos/cursor.svg +20 -20
- package/frontend/src/assets/logos/discord.svg +8 -8
- package/frontend/src/assets/logos/facebook.svg +3 -3
- package/frontend/src/assets/logos/gemini.svg +19 -19
- package/frontend/src/assets/logos/github.svg +5 -5
- package/frontend/src/assets/logos/google.svg +13 -13
- package/frontend/src/assets/logos/grok.svg +10 -10
- package/frontend/src/assets/logos/insforge_dark.svg +15 -15
- package/frontend/src/assets/logos/insforge_light.svg +15 -15
- package/frontend/src/assets/logos/instagram.svg +1 -1
- package/frontend/src/assets/logos/linkedin.svg +3 -3
- package/frontend/src/assets/logos/openai.svg +10 -10
- package/frontend/src/assets/logos/roo_code.svg +9 -9
- package/frontend/src/assets/logos/spotify.svg +16 -16
- package/frontend/src/assets/logos/tiktok.svg +5 -5
- package/frontend/src/assets/logos/trae.svg +3 -3
- package/frontend/src/assets/logos/windsurf.svg +10 -10
- package/frontend/src/assets/logos/x.svg +3 -3
- package/frontend/src/components/layout/AppHeader.tsx +9 -10
- package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +1 -0
- package/frontend/src/features/auth/components/UsersDataGrid.tsx +6 -0
- package/frontend/src/features/auth/helpers.tsx +8 -0
- package/frontend/src/features/auth/{page → pages}/UsersPage.tsx +0 -28
- package/frontend/src/features/database/components/SQLModal.tsx +75 -0
- package/frontend/src/features/database/components/TableForm.tsx +0 -4
- package/frontend/src/features/database/hooks/useDatabase.ts +66 -0
- package/frontend/src/features/database/hooks/useTables.ts +32 -28
- package/frontend/src/features/database/index.ts +1 -0
- package/frontend/src/features/database/{page → pages}/FunctionsPage.tsx +29 -37
- package/frontend/src/features/database/{page → pages}/IndexesPage.tsx +35 -47
- package/frontend/src/features/database/{page → pages}/PoliciesPage.tsx +43 -54
- package/frontend/src/features/database/{page → pages}/TablesPage.tsx +0 -42
- package/frontend/src/features/database/{page → pages}/TriggersPage.tsx +35 -47
- package/frontend/src/features/database/services/advance.service.ts +0 -26
- package/frontend/src/features/database/services/database.service.ts +55 -0
- package/frontend/src/features/database/services/table.service.ts +0 -6
- package/frontend/src/features/functions/{page → pages}/FunctionsPage.tsx +21 -44
- package/frontend/src/features/functions/{page → pages}/SecretsPage.tsx +11 -9
- package/frontend/src/features/logs/hooks/useMcpUsage.ts +13 -66
- package/frontend/src/features/realtime/components/ChannelRow.tsx +83 -0
- package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
- package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
- package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
- package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
- package/frontend/src/features/realtime/index.ts +11 -0
- package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
- package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
- package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
- package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
- package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +1 -29
- package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +3 -3
- package/frontend/src/features/visualizer/{page → pages}/VisualizerPage.tsx +1 -35
- package/frontend/src/lib/contexts/SocketContext.tsx +119 -75
- package/frontend/src/lib/routing/AppRoutes.tsx +35 -20
- package/frontend/src/lib/utils/cloudMessaging.ts +1 -1
- package/frontend/src/lib/utils/menuItems.ts +24 -0
- package/frontend/src/lib/utils/utils.ts +14 -1
- package/frontend/tsconfig.json +25 -25
- package/frontend/tsconfig.node.json +9 -9
- package/functions/deno.json +24 -24
- package/functions/server.ts +315 -315
- package/i18n/README.ar.md +130 -130
- package/i18n/README.de.md +130 -130
- package/i18n/README.es.md +154 -154
- package/i18n/README.fr.md +134 -134
- package/i18n/README.hi.md +129 -129
- package/i18n/README.ja.md +174 -174
- package/i18n/README.ko.md +136 -136
- package/i18n/README.pt-BR.md +131 -131
- package/i18n/README.ru.md +129 -129
- package/i18n/README.zh-CN.md +133 -133
- package/openapi/ai.yaml +715 -715
- package/openapi/auth.yaml +1244 -1244
- package/openapi/email.yaml +158 -0
- package/openapi/functions.yaml +475 -475
- package/openapi/health.yaml +29 -29
- package/openapi/logs.yaml +223 -223
- package/openapi/metadata.yaml +177 -177
- package/openapi/realtime.yaml +699 -0
- package/openapi/records.yaml +381 -381
- package/openapi/secrets.yaml +370 -370
- package/openapi/storage.yaml +875 -875
- package/openapi/tables.yaml +463 -463
- package/package.json +97 -97
- package/shared-schemas/package.json +31 -31
- package/shared-schemas/src/ai.schema.ts +63 -59
- package/shared-schemas/src/auth-api.schema.ts +352 -339
- package/shared-schemas/src/auth.schema.ts +1 -1
- package/shared-schemas/src/database-api.schema.ts +32 -1
- package/shared-schemas/src/database.schema.ts +39 -0
- package/shared-schemas/src/docs.schema.ts +26 -0
- package/shared-schemas/src/email-api.schema.ts +30 -0
- package/shared-schemas/src/index.ts +4 -0
- package/shared-schemas/src/metadata.schema.ts +9 -0
- package/shared-schemas/src/realtime-api.schema.ts +111 -0
- package/shared-schemas/src/realtime.schema.ts +143 -0
- package/shared-schemas/tsconfig.json +21 -21
- package/tsconfig.json +7 -7
- package/zeabur/README.md +13 -13
- package/zeabur/template.yml +1032 -1032
- package/.cursor/rules/cursor-rules.mdc +0 -94
- package/frontend/src/features/database/hooks/useFullMetadata.ts +0 -18
- package/test-gemini.sh +0 -35
- package/test-usage-admin.sh +0 -57
- package/test-usage.sh +0 -50
- /package/frontend/src/features/ai/{page → pages}/AIPage.tsx +0 -0
- /package/frontend/src/features/auth/{page → pages}/AuthMethodsPage.tsx +0 -0
- /package/frontend/src/features/auth/{page → pages}/ConfigurationPage.tsx +0 -0
- /package/frontend/src/features/dashboard/{page → pages}/DashboardPage.tsx +0 -0
- /package/frontend/src/features/database/{page → pages}/SQLEditorPage.tsx +0 -0
- /package/frontend/src/features/database/{page → pages}/TemplatesPage.tsx +0 -0
- /package/frontend/src/features/login/{page → pages}/CloudLoginPage.tsx +0 -0
- /package/frontend/src/features/login/{page → pages}/LoginPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/LogsPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/MCPLogsPage.tsx +0 -0
|
@@ -1,412 +1,412 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Test RawSQL, Export, and Import endpoints
|
|
4
|
-
# This script tests the database advanced operations
|
|
5
|
-
|
|
6
|
-
# Get the directory where this script is located
|
|
7
|
-
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
8
|
-
|
|
9
|
-
# Source the test configuration
|
|
10
|
-
source "$SCRIPT_DIR/../test-config.sh"
|
|
11
|
-
|
|
12
|
-
# Check requirements
|
|
13
|
-
check_requirements
|
|
14
|
-
|
|
15
|
-
print_blue "🧪 Testing RawSQL, Export, and Import Endpoints..."
|
|
16
|
-
|
|
17
|
-
# Test tracking
|
|
18
|
-
TEST_FAILED=0
|
|
19
|
-
|
|
20
|
-
# Function to track test failures
|
|
21
|
-
track_test_failure() {
|
|
22
|
-
TEST_FAILED=$((TEST_FAILED + 1))
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
# Function to cleanup and exit
|
|
26
|
-
cleanup_and_exit() {
|
|
27
|
-
local exit_code=$1
|
|
28
|
-
|
|
29
|
-
print_info "🧹 Cleaning up test data..."
|
|
30
|
-
|
|
31
|
-
# Drop the test table if it exists
|
|
32
|
-
if [ -n "$AUTH_TOKEN" ]; then
|
|
33
|
-
print_info "Dropping large_table..."
|
|
34
|
-
local drop_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
35
|
-
-H "Content-Type: application/json" \
|
|
36
|
-
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
37
|
-
-d '{
|
|
38
|
-
"query": "DROP TABLE IF EXISTS large_table CASCADE;"
|
|
39
|
-
}')
|
|
40
|
-
|
|
41
|
-
if echo "$drop_response" | grep -q '"success"'; then
|
|
42
|
-
print_success "Table large_table dropped successfully"
|
|
43
|
-
else
|
|
44
|
-
print_info "Table cleanup response: $drop_response"
|
|
45
|
-
fi
|
|
46
|
-
fi
|
|
47
|
-
|
|
48
|
-
exit $exit_code
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
# Function to exit with proper status
|
|
52
|
-
exit_with_status() {
|
|
53
|
-
if [ $TEST_FAILED -eq 0 ]; then
|
|
54
|
-
print_success "All tests passed!"
|
|
55
|
-
cleanup_and_exit 0
|
|
56
|
-
else
|
|
57
|
-
print_fail "Failed $TEST_FAILED test(s)"
|
|
58
|
-
cleanup_and_exit 1
|
|
59
|
-
fi
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
# API Configuration
|
|
63
|
-
API_BASE="$TEST_API_BASE"
|
|
64
|
-
AUTH_TOKEN=""
|
|
65
|
-
|
|
66
|
-
# Read .env file to get admin credentials
|
|
67
|
-
if [ -f "$SCRIPT_DIR/../../.env" ]; then
|
|
68
|
-
export $(grep -v '^#' "$SCRIPT_DIR/../../.env" | xargs)
|
|
69
|
-
print_info "Loaded environment variables from .env"
|
|
70
|
-
fi
|
|
71
|
-
|
|
72
|
-
# Use admin credentials from environment
|
|
73
|
-
ADMIN_EMAIL="${ADMIN_EMAIL:-admin@example.com}"
|
|
74
|
-
ADMIN_PASSWORD="${ADMIN_PASSWORD:-admin123}"
|
|
75
|
-
|
|
76
|
-
print_info "Using admin credentials: $ADMIN_EMAIL"
|
|
77
|
-
|
|
78
|
-
# ========================================
|
|
79
|
-
# 1. Login as admin
|
|
80
|
-
# ========================================
|
|
81
|
-
print_blue "1. Logging in as admin..."
|
|
82
|
-
|
|
83
|
-
auth_response=$(curl -s -X POST "$API_BASE/auth/admin/sessions" \
|
|
84
|
-
-H "Content-Type: application/json" \
|
|
85
|
-
-d "{
|
|
86
|
-
\"email\": \"$ADMIN_EMAIL\",
|
|
87
|
-
\"password\": \"$ADMIN_PASSWORD\"
|
|
88
|
-
}")
|
|
89
|
-
|
|
90
|
-
# Check if login was successful
|
|
91
|
-
if echo "$auth_response" | grep -q '"accessToken"'; then
|
|
92
|
-
AUTH_TOKEN=$(echo "$auth_response" | grep -o '"accessToken":"[^"]*' | cut -d'"' -f4)
|
|
93
|
-
print_success "Admin login successful"
|
|
94
|
-
else
|
|
95
|
-
print_fail "Failed to login as admin"
|
|
96
|
-
echo "Response: $auth_response"
|
|
97
|
-
exit 1
|
|
98
|
-
fi
|
|
99
|
-
|
|
100
|
-
# ========================================
|
|
101
|
-
# 2. Create large_table using RawSQL
|
|
102
|
-
# ========================================
|
|
103
|
-
print_blue "2. Creating large_table using RawSQL endpoint..."
|
|
104
|
-
|
|
105
|
-
# Step 1: Create the basic table
|
|
106
|
-
print_info "Creating basic table structure..."
|
|
107
|
-
CREATE_TABLE_SQL=$(cat "$SCRIPT_DIR/create-large-table-simple.sql")
|
|
108
|
-
|
|
109
|
-
if command -v jq &> /dev/null; then
|
|
110
|
-
json_payload=$(jq -n --arg query "$CREATE_TABLE_SQL" '{"query": $query}')
|
|
111
|
-
create_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
112
|
-
-H "Content-Type: application/json" \
|
|
113
|
-
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
114
|
-
-d "$json_payload")
|
|
115
|
-
else
|
|
116
|
-
CREATE_TABLE_SQL_ESCAPED=$(echo "$CREATE_TABLE_SQL" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | tr '\n' ' ')
|
|
117
|
-
create_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
118
|
-
-H "Content-Type: application/json" \
|
|
119
|
-
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
120
|
-
-d "{\"query\": \"$CREATE_TABLE_SQL_ESCAPED\"}")
|
|
121
|
-
fi
|
|
122
|
-
|
|
123
|
-
if echo "$create_response" | grep -q '"error"'; then
|
|
124
|
-
print_fail "Failed to create table"
|
|
125
|
-
echo "Response: $create_response"
|
|
126
|
-
track_test_failure
|
|
127
|
-
else
|
|
128
|
-
print_success "Basic table created successfully"
|
|
129
|
-
|
|
130
|
-
# Step 2: Add indexes, triggers and RLS
|
|
131
|
-
print_info "Setting up indexes, triggers and RLS..."
|
|
132
|
-
SETUP_SQL=$(cat "$SCRIPT_DIR/setup-large-table-extras.sql")
|
|
133
|
-
|
|
134
|
-
if command -v jq &> /dev/null; then
|
|
135
|
-
json_payload=$(jq -n --arg query "$SETUP_SQL" '{"query": $query}')
|
|
136
|
-
setup_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
137
|
-
-H "Content-Type: application/json" \
|
|
138
|
-
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
139
|
-
-d "$json_payload")
|
|
140
|
-
else
|
|
141
|
-
SETUP_SQL_ESCAPED=$(echo "$SETUP_SQL" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | tr '\n' ' ')
|
|
142
|
-
setup_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
143
|
-
-H "Content-Type: application/json" \
|
|
144
|
-
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
145
|
-
-d "{\"query\": \"$SETUP_SQL_ESCAPED\"}")
|
|
146
|
-
fi
|
|
147
|
-
|
|
148
|
-
if echo "$setup_response" | grep -q '"error"'; then
|
|
149
|
-
print_fail "Failed to setup table extras"
|
|
150
|
-
echo "Response: $setup_response"
|
|
151
|
-
track_test_failure
|
|
152
|
-
else
|
|
153
|
-
print_success "Table fully configured with indexes, triggers and RLS"
|
|
154
|
-
fi
|
|
155
|
-
fi
|
|
156
|
-
|
|
157
|
-
# ========================================
|
|
158
|
-
# 3. Verify table schema
|
|
159
|
-
# ========================================
|
|
160
|
-
print_blue "3. Verifying table schema..."
|
|
161
|
-
|
|
162
|
-
# Get table schema
|
|
163
|
-
schema_response=$(curl -s "$API_BASE/metadata/large_table" \
|
|
164
|
-
-H "Authorization: Bearer $AUTH_TOKEN")
|
|
165
|
-
|
|
166
|
-
if echo "$schema_response" | grep -q '"large_table"'; then
|
|
167
|
-
print_success "Table schema retrieved successfully"
|
|
168
|
-
|
|
169
|
-
# Verify required columns exist
|
|
170
|
-
if echo "$schema_response" | grep -q '"columnName":"user_id"' && \
|
|
171
|
-
echo "$schema_response" | grep -q '"columnName":"created_at"' && \
|
|
172
|
-
echo "$schema_response" | grep -q '"columnName":"updated_at"'; then
|
|
173
|
-
print_success "Required columns (user_id, created_at, updated_at) exist"
|
|
174
|
-
else
|
|
175
|
-
print_fail "Missing required columns"
|
|
176
|
-
echo "Schema response: $schema_response"
|
|
177
|
-
track_test_failure
|
|
178
|
-
fi
|
|
179
|
-
|
|
180
|
-
# Verify RLS is enabled
|
|
181
|
-
if echo "$schema_response" | grep -q '"rlsEnabled":true'; then
|
|
182
|
-
print_success "RLS is enabled on the table"
|
|
183
|
-
else
|
|
184
|
-
print_fail "RLS is not enabled"
|
|
185
|
-
track_test_failure
|
|
186
|
-
fi
|
|
187
|
-
else
|
|
188
|
-
print_fail "Failed to get table schema"
|
|
189
|
-
echo "Response: $schema_response"
|
|
190
|
-
track_test_failure
|
|
191
|
-
fi
|
|
192
|
-
|
|
193
|
-
# ========================================
|
|
194
|
-
# 4. Import test data
|
|
195
|
-
# ========================================
|
|
196
|
-
print_blue "4. Importing test data using Import endpoint..."
|
|
197
|
-
|
|
198
|
-
# Use multipart form-data to upload the SQL file
|
|
199
|
-
import_response=$(curl -s -X POST "$API_BASE/database/advance/import" \
|
|
200
|
-
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
201
|
-
-F "file=@$SCRIPT_DIR/seed-large-table.sql" \
|
|
202
|
-
-F "truncate=false")
|
|
203
|
-
|
|
204
|
-
if echo "$import_response" | grep -q '"error"'; then
|
|
205
|
-
print_fail "Failed to import data"
|
|
206
|
-
echo "Response: $import_response"
|
|
207
|
-
track_test_failure
|
|
208
|
-
else
|
|
209
|
-
print_success "Data imported successfully"
|
|
210
|
-
|
|
211
|
-
# Check if response contains success information
|
|
212
|
-
if echo "$import_response" | grep -q '"rowsAffected"'; then
|
|
213
|
-
rows_affected=$(echo "$import_response" | grep -o '"rowsAffected":[0-9]*' | cut -d':' -f2)
|
|
214
|
-
print_success "Rows affected: $rows_affected"
|
|
215
|
-
|
|
216
|
-
if [ "$rows_affected" -ge 1000 ]; then
|
|
217
|
-
print_success "Successfully imported 1000+ rows"
|
|
218
|
-
else
|
|
219
|
-
print_fail "Less than 1000 rows imported"
|
|
220
|
-
track_test_failure
|
|
221
|
-
fi
|
|
222
|
-
fi
|
|
223
|
-
fi
|
|
224
|
-
|
|
225
|
-
# ========================================
|
|
226
|
-
# 5. Verify imported data
|
|
227
|
-
# ========================================
|
|
228
|
-
print_blue "5. Verifying imported data..."
|
|
229
|
-
|
|
230
|
-
# Count records using RawSQL
|
|
231
|
-
count_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
232
|
-
-H "Content-Type: application/json" \
|
|
233
|
-
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
234
|
-
-d '{
|
|
235
|
-
"query": "SELECT COUNT(*) as total FROM large_table;"
|
|
236
|
-
}')
|
|
237
|
-
|
|
238
|
-
if echo "$count_response" | grep -q '"rows"'; then
|
|
239
|
-
# Extract the count from the rows array
|
|
240
|
-
if command -v jq &> /dev/null; then
|
|
241
|
-
total_count=$(echo "$count_response" | jq -r '.rows[0].total // 0')
|
|
242
|
-
else
|
|
243
|
-
# Fallback without jq
|
|
244
|
-
total_count=$(echo "$count_response" | grep -o '"total":[0-9]*' | cut -d':' -f2 | head -1)
|
|
245
|
-
if [ -z "$total_count" ]; then
|
|
246
|
-
# Try another pattern
|
|
247
|
-
total_count=$(echo "$count_response" | sed -n 's/.*"total":\([0-9]*\).*/\1/p' | head -1)
|
|
248
|
-
fi
|
|
249
|
-
fi
|
|
250
|
-
|
|
251
|
-
if [ -n "$total_count" ] && [ "$total_count" -ge 0 ]; then
|
|
252
|
-
print_info "Total records in large_table: $total_count"
|
|
253
|
-
|
|
254
|
-
if [ "$total_count" -ge 1000 ]; then
|
|
255
|
-
print_success "Table contains 1000+ records as expected"
|
|
256
|
-
else
|
|
257
|
-
print_fail "Table has less than 1000 records ($total_count found)"
|
|
258
|
-
track_test_failure
|
|
259
|
-
fi
|
|
260
|
-
else
|
|
261
|
-
print_fail "Could not parse record count"
|
|
262
|
-
echo "Response: $count_response"
|
|
263
|
-
track_test_failure
|
|
264
|
-
fi
|
|
265
|
-
else
|
|
266
|
-
print_fail "Failed to count records"
|
|
267
|
-
echo "Response: $count_response"
|
|
268
|
-
track_test_failure
|
|
269
|
-
fi
|
|
270
|
-
|
|
271
|
-
# ========================================
|
|
272
|
-
# 6. Test Export endpoint
|
|
273
|
-
# ========================================
|
|
274
|
-
print_blue "6. Testing Export endpoint..."
|
|
275
|
-
|
|
276
|
-
# Export all data including schema
|
|
277
|
-
export_response=$(curl -s -X POST "$API_BASE/database/advance/export" \
|
|
278
|
-
-H "Content-Type: application/json" \
|
|
279
|
-
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
280
|
-
-d '{
|
|
281
|
-
"tables": ["large_table"],
|
|
282
|
-
"format": "sql",
|
|
283
|
-
"includeData": true,
|
|
284
|
-
"includeFunctions": true,
|
|
285
|
-
"includeSequences": true,
|
|
286
|
-
"includeViews": false
|
|
287
|
-
}')
|
|
288
|
-
|
|
289
|
-
if echo "$export_response" | grep -q '"error"'; then
|
|
290
|
-
print_fail "Failed to export database"
|
|
291
|
-
echo "Response preview: $(echo "$export_response" | head -c 500)..."
|
|
292
|
-
track_test_failure
|
|
293
|
-
else
|
|
294
|
-
print_success "Database exported successfully"
|
|
295
|
-
|
|
296
|
-
# Verify export contains expected elements
|
|
297
|
-
if echo "$export_response" | grep -q '"data"'; then
|
|
298
|
-
export_content=$(echo "$export_response" | jq -r '.data // empty')
|
|
299
|
-
|
|
300
|
-
if [ -n "$export_content" ]; then
|
|
301
|
-
# Check for table creation (use case statement to avoid broken pipe)
|
|
302
|
-
case "$export_content" in
|
|
303
|
-
*"CREATE TABLE"*"large_table"*)
|
|
304
|
-
print_success "Export contains table creation statement"
|
|
305
|
-
;;
|
|
306
|
-
*)
|
|
307
|
-
print_fail "Export missing table creation statement"
|
|
308
|
-
track_test_failure
|
|
309
|
-
;;
|
|
310
|
-
esac
|
|
311
|
-
|
|
312
|
-
# Check for data
|
|
313
|
-
case "$export_content" in
|
|
314
|
-
*"INSERT INTO"*"large_table"*)
|
|
315
|
-
print_success "Export contains data insertion statements"
|
|
316
|
-
;;
|
|
317
|
-
*)
|
|
318
|
-
print_fail "Export missing data insertion statements"
|
|
319
|
-
track_test_failure
|
|
320
|
-
;;
|
|
321
|
-
esac
|
|
322
|
-
|
|
323
|
-
# Check for RLS policies
|
|
324
|
-
case "$export_content" in
|
|
325
|
-
*"CREATE POLICY"*)
|
|
326
|
-
print_success "Export contains RLS policies"
|
|
327
|
-
;;
|
|
328
|
-
*)
|
|
329
|
-
print_fail "Export missing RLS policies"
|
|
330
|
-
track_test_failure
|
|
331
|
-
;;
|
|
332
|
-
esac
|
|
333
|
-
|
|
334
|
-
# Check for trigger
|
|
335
|
-
case "$export_content" in
|
|
336
|
-
*"CREATE TRIGGER"*"update_large_table_updated_at"*)
|
|
337
|
-
print_success "Export contains update trigger"
|
|
338
|
-
;;
|
|
339
|
-
*)
|
|
340
|
-
print_fail "Export missing update trigger"
|
|
341
|
-
track_test_failure
|
|
342
|
-
;;
|
|
343
|
-
esac
|
|
344
|
-
|
|
345
|
-
# Count INSERT statements to verify all data exported (using awk for efficiency)
|
|
346
|
-
insert_count=$(echo "$export_content" | awk '/INSERT INTO/ {count++} END {print count+0}')
|
|
347
|
-
print_info "Number of INSERT statements in export: $insert_count"
|
|
348
|
-
else
|
|
349
|
-
print_fail "Export content is empty"
|
|
350
|
-
track_test_failure
|
|
351
|
-
fi
|
|
352
|
-
else
|
|
353
|
-
print_fail "Export response missing data field"
|
|
354
|
-
echo "Response structure: $(echo "$export_response" | jq -r 'keys' 2>/dev/null || echo "$export_response" | head -c 200)"
|
|
355
|
-
track_test_failure
|
|
356
|
-
fi
|
|
357
|
-
fi
|
|
358
|
-
|
|
359
|
-
# ========================================
|
|
360
|
-
# 7. Test Export with row limit
|
|
361
|
-
# ========================================
|
|
362
|
-
print_blue "7. Testing Export with row limit..."
|
|
363
|
-
|
|
364
|
-
limited_export_response=$(curl -s -X POST "$API_BASE/database/advance/export" \
|
|
365
|
-
-H "Content-Type: application/json" \
|
|
366
|
-
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
367
|
-
-d '{
|
|
368
|
-
"tables": ["large_table"],
|
|
369
|
-
"format": "sql",
|
|
370
|
-
"includeData": true,
|
|
371
|
-
"rowLimit": 10
|
|
372
|
-
}')
|
|
373
|
-
|
|
374
|
-
if echo "$limited_export_response" | grep -q '"error"'; then
|
|
375
|
-
print_fail "Failed to export with row limit"
|
|
376
|
-
echo "Response preview: $(echo "$limited_export_response" | head -c 500)..."
|
|
377
|
-
track_test_failure
|
|
378
|
-
else
|
|
379
|
-
print_success "Export with row limit successful"
|
|
380
|
-
|
|
381
|
-
if echo "$limited_export_response" | grep -q '"data"'; then
|
|
382
|
-
limited_content=$(echo "$limited_export_response" | jq -r '.data // empty')
|
|
383
|
-
|
|
384
|
-
# Count data rows in limited export (should be much less than full export)
|
|
385
|
-
if [ -n "$limited_content" ]; then
|
|
386
|
-
limited_insert_count=$(echo "$limited_content" | awk '/INSERT INTO/ {count++} END {print count+0}')
|
|
387
|
-
print_info "INSERT statements in limited export: $limited_insert_count"
|
|
388
|
-
|
|
389
|
-
# Only compare if insert_count is set and valid
|
|
390
|
-
if [ -n "$insert_count" ] && [ "$insert_count" -gt 0 ] 2>/dev/null; then
|
|
391
|
-
if [ "$limited_insert_count" -lt "$insert_count" ] 2>/dev/null; then
|
|
392
|
-
print_success "Row limit is working (limited export has fewer rows)"
|
|
393
|
-
else
|
|
394
|
-
print_info "Unable to verify row limit effectiveness"
|
|
395
|
-
fi
|
|
396
|
-
else
|
|
397
|
-
print_info "Skipping row limit comparison (no full export count available)"
|
|
398
|
-
fi
|
|
399
|
-
fi
|
|
400
|
-
fi
|
|
401
|
-
fi
|
|
402
|
-
|
|
403
|
-
# ========================================
|
|
404
|
-
# Summary
|
|
405
|
-
# ========================================
|
|
406
|
-
echo ""
|
|
407
|
-
print_blue "=========================================="
|
|
408
|
-
print_blue "RawSQL/Export/Import Test Complete"
|
|
409
|
-
print_blue "=========================================="
|
|
410
|
-
|
|
411
|
-
# Exit with proper status
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Test RawSQL, Export, and Import endpoints
|
|
4
|
+
# This script tests the database advanced operations
|
|
5
|
+
|
|
6
|
+
# Get the directory where this script is located
|
|
7
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
8
|
+
|
|
9
|
+
# Source the test configuration
|
|
10
|
+
source "$SCRIPT_DIR/../test-config.sh"
|
|
11
|
+
|
|
12
|
+
# Check requirements
|
|
13
|
+
check_requirements
|
|
14
|
+
|
|
15
|
+
print_blue "🧪 Testing RawSQL, Export, and Import Endpoints..."
|
|
16
|
+
|
|
17
|
+
# Test tracking
|
|
18
|
+
TEST_FAILED=0
|
|
19
|
+
|
|
20
|
+
# Function to track test failures
|
|
21
|
+
track_test_failure() {
|
|
22
|
+
TEST_FAILED=$((TEST_FAILED + 1))
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# Function to cleanup and exit
|
|
26
|
+
cleanup_and_exit() {
|
|
27
|
+
local exit_code=$1
|
|
28
|
+
|
|
29
|
+
print_info "🧹 Cleaning up test data..."
|
|
30
|
+
|
|
31
|
+
# Drop the test table if it exists
|
|
32
|
+
if [ -n "$AUTH_TOKEN" ]; then
|
|
33
|
+
print_info "Dropping large_table..."
|
|
34
|
+
local drop_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
35
|
+
-H "Content-Type: application/json" \
|
|
36
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
37
|
+
-d '{
|
|
38
|
+
"query": "DROP TABLE IF EXISTS large_table CASCADE;"
|
|
39
|
+
}')
|
|
40
|
+
|
|
41
|
+
if echo "$drop_response" | grep -q '"success"'; then
|
|
42
|
+
print_success "Table large_table dropped successfully"
|
|
43
|
+
else
|
|
44
|
+
print_info "Table cleanup response: $drop_response"
|
|
45
|
+
fi
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
exit $exit_code
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Function to exit with proper status
|
|
52
|
+
exit_with_status() {
|
|
53
|
+
if [ $TEST_FAILED -eq 0 ]; then
|
|
54
|
+
print_success "All tests passed!"
|
|
55
|
+
cleanup_and_exit 0
|
|
56
|
+
else
|
|
57
|
+
print_fail "Failed $TEST_FAILED test(s)"
|
|
58
|
+
cleanup_and_exit 1
|
|
59
|
+
fi
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# API Configuration
|
|
63
|
+
API_BASE="$TEST_API_BASE"
|
|
64
|
+
AUTH_TOKEN=""
|
|
65
|
+
|
|
66
|
+
# Read .env file to get admin credentials
|
|
67
|
+
if [ -f "$SCRIPT_DIR/../../.env" ]; then
|
|
68
|
+
export $(grep -v '^#' "$SCRIPT_DIR/../../.env" | xargs)
|
|
69
|
+
print_info "Loaded environment variables from .env"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Use admin credentials from environment
|
|
73
|
+
ADMIN_EMAIL="${ADMIN_EMAIL:-admin@example.com}"
|
|
74
|
+
ADMIN_PASSWORD="${ADMIN_PASSWORD:-admin123}"
|
|
75
|
+
|
|
76
|
+
print_info "Using admin credentials: $ADMIN_EMAIL"
|
|
77
|
+
|
|
78
|
+
# ========================================
|
|
79
|
+
# 1. Login as admin
|
|
80
|
+
# ========================================
|
|
81
|
+
print_blue "1. Logging in as admin..."
|
|
82
|
+
|
|
83
|
+
auth_response=$(curl -s -X POST "$API_BASE/auth/admin/sessions" \
|
|
84
|
+
-H "Content-Type: application/json" \
|
|
85
|
+
-d "{
|
|
86
|
+
\"email\": \"$ADMIN_EMAIL\",
|
|
87
|
+
\"password\": \"$ADMIN_PASSWORD\"
|
|
88
|
+
}")
|
|
89
|
+
|
|
90
|
+
# Check if login was successful
|
|
91
|
+
if echo "$auth_response" | grep -q '"accessToken"'; then
|
|
92
|
+
AUTH_TOKEN=$(echo "$auth_response" | grep -o '"accessToken":"[^"]*' | cut -d'"' -f4)
|
|
93
|
+
print_success "Admin login successful"
|
|
94
|
+
else
|
|
95
|
+
print_fail "Failed to login as admin"
|
|
96
|
+
echo "Response: $auth_response"
|
|
97
|
+
exit 1
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# ========================================
|
|
101
|
+
# 2. Create large_table using RawSQL
|
|
102
|
+
# ========================================
|
|
103
|
+
print_blue "2. Creating large_table using RawSQL endpoint..."
|
|
104
|
+
|
|
105
|
+
# Step 1: Create the basic table
|
|
106
|
+
print_info "Creating basic table structure..."
|
|
107
|
+
CREATE_TABLE_SQL=$(cat "$SCRIPT_DIR/create-large-table-simple.sql")
|
|
108
|
+
|
|
109
|
+
if command -v jq &> /dev/null; then
|
|
110
|
+
json_payload=$(jq -n --arg query "$CREATE_TABLE_SQL" '{"query": $query}')
|
|
111
|
+
create_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
112
|
+
-H "Content-Type: application/json" \
|
|
113
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
114
|
+
-d "$json_payload")
|
|
115
|
+
else
|
|
116
|
+
CREATE_TABLE_SQL_ESCAPED=$(echo "$CREATE_TABLE_SQL" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | tr '\n' ' ')
|
|
117
|
+
create_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
118
|
+
-H "Content-Type: application/json" \
|
|
119
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
120
|
+
-d "{\"query\": \"$CREATE_TABLE_SQL_ESCAPED\"}")
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
if echo "$create_response" | grep -q '"error"'; then
|
|
124
|
+
print_fail "Failed to create table"
|
|
125
|
+
echo "Response: $create_response"
|
|
126
|
+
track_test_failure
|
|
127
|
+
else
|
|
128
|
+
print_success "Basic table created successfully"
|
|
129
|
+
|
|
130
|
+
# Step 2: Add indexes, triggers and RLS
|
|
131
|
+
print_info "Setting up indexes, triggers and RLS..."
|
|
132
|
+
SETUP_SQL=$(cat "$SCRIPT_DIR/setup-large-table-extras.sql")
|
|
133
|
+
|
|
134
|
+
if command -v jq &> /dev/null; then
|
|
135
|
+
json_payload=$(jq -n --arg query "$SETUP_SQL" '{"query": $query}')
|
|
136
|
+
setup_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
137
|
+
-H "Content-Type: application/json" \
|
|
138
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
139
|
+
-d "$json_payload")
|
|
140
|
+
else
|
|
141
|
+
SETUP_SQL_ESCAPED=$(echo "$SETUP_SQL" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | tr '\n' ' ')
|
|
142
|
+
setup_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
143
|
+
-H "Content-Type: application/json" \
|
|
144
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
145
|
+
-d "{\"query\": \"$SETUP_SQL_ESCAPED\"}")
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
if echo "$setup_response" | grep -q '"error"'; then
|
|
149
|
+
print_fail "Failed to setup table extras"
|
|
150
|
+
echo "Response: $setup_response"
|
|
151
|
+
track_test_failure
|
|
152
|
+
else
|
|
153
|
+
print_success "Table fully configured with indexes, triggers and RLS"
|
|
154
|
+
fi
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
# ========================================
|
|
158
|
+
# 3. Verify table schema
|
|
159
|
+
# ========================================
|
|
160
|
+
print_blue "3. Verifying table schema..."
|
|
161
|
+
|
|
162
|
+
# Get table schema
|
|
163
|
+
schema_response=$(curl -s "$API_BASE/metadata/large_table" \
|
|
164
|
+
-H "Authorization: Bearer $AUTH_TOKEN")
|
|
165
|
+
|
|
166
|
+
if echo "$schema_response" | grep -q '"large_table"'; then
|
|
167
|
+
print_success "Table schema retrieved successfully"
|
|
168
|
+
|
|
169
|
+
# Verify required columns exist
|
|
170
|
+
if echo "$schema_response" | grep -q '"columnName":"user_id"' && \
|
|
171
|
+
echo "$schema_response" | grep -q '"columnName":"created_at"' && \
|
|
172
|
+
echo "$schema_response" | grep -q '"columnName":"updated_at"'; then
|
|
173
|
+
print_success "Required columns (user_id, created_at, updated_at) exist"
|
|
174
|
+
else
|
|
175
|
+
print_fail "Missing required columns"
|
|
176
|
+
echo "Schema response: $schema_response"
|
|
177
|
+
track_test_failure
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
# Verify RLS is enabled
|
|
181
|
+
if echo "$schema_response" | grep -q '"rlsEnabled":true'; then
|
|
182
|
+
print_success "RLS is enabled on the table"
|
|
183
|
+
else
|
|
184
|
+
print_fail "RLS is not enabled"
|
|
185
|
+
track_test_failure
|
|
186
|
+
fi
|
|
187
|
+
else
|
|
188
|
+
print_fail "Failed to get table schema"
|
|
189
|
+
echo "Response: $schema_response"
|
|
190
|
+
track_test_failure
|
|
191
|
+
fi
|
|
192
|
+
|
|
193
|
+
# ========================================
|
|
194
|
+
# 4. Import test data
|
|
195
|
+
# ========================================
|
|
196
|
+
print_blue "4. Importing test data using Import endpoint..."
|
|
197
|
+
|
|
198
|
+
# Use multipart form-data to upload the SQL file
|
|
199
|
+
import_response=$(curl -s -X POST "$API_BASE/database/advance/import" \
|
|
200
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
201
|
+
-F "file=@$SCRIPT_DIR/seed-large-table.sql" \
|
|
202
|
+
-F "truncate=false")
|
|
203
|
+
|
|
204
|
+
if echo "$import_response" | grep -q '"error"'; then
|
|
205
|
+
print_fail "Failed to import data"
|
|
206
|
+
echo "Response: $import_response"
|
|
207
|
+
track_test_failure
|
|
208
|
+
else
|
|
209
|
+
print_success "Data imported successfully"
|
|
210
|
+
|
|
211
|
+
# Check if response contains success information
|
|
212
|
+
if echo "$import_response" | grep -q '"rowsAffected"'; then
|
|
213
|
+
rows_affected=$(echo "$import_response" | grep -o '"rowsAffected":[0-9]*' | cut -d':' -f2)
|
|
214
|
+
print_success "Rows affected: $rows_affected"
|
|
215
|
+
|
|
216
|
+
if [ "$rows_affected" -ge 1000 ]; then
|
|
217
|
+
print_success "Successfully imported 1000+ rows"
|
|
218
|
+
else
|
|
219
|
+
print_fail "Less than 1000 rows imported"
|
|
220
|
+
track_test_failure
|
|
221
|
+
fi
|
|
222
|
+
fi
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
# ========================================
|
|
226
|
+
# 5. Verify imported data
|
|
227
|
+
# ========================================
|
|
228
|
+
print_blue "5. Verifying imported data..."
|
|
229
|
+
|
|
230
|
+
# Count records using RawSQL
|
|
231
|
+
count_response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
|
|
232
|
+
-H "Content-Type: application/json" \
|
|
233
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
234
|
+
-d '{
|
|
235
|
+
"query": "SELECT COUNT(*) as total FROM large_table;"
|
|
236
|
+
}')
|
|
237
|
+
|
|
238
|
+
if echo "$count_response" | grep -q '"rows"'; then
|
|
239
|
+
# Extract the count from the rows array
|
|
240
|
+
if command -v jq &> /dev/null; then
|
|
241
|
+
total_count=$(echo "$count_response" | jq -r '.rows[0].total // 0')
|
|
242
|
+
else
|
|
243
|
+
# Fallback without jq
|
|
244
|
+
total_count=$(echo "$count_response" | grep -o '"total":[0-9]*' | cut -d':' -f2 | head -1)
|
|
245
|
+
if [ -z "$total_count" ]; then
|
|
246
|
+
# Try another pattern
|
|
247
|
+
total_count=$(echo "$count_response" | sed -n 's/.*"total":\([0-9]*\).*/\1/p' | head -1)
|
|
248
|
+
fi
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
if [ -n "$total_count" ] && [ "$total_count" -ge 0 ]; then
|
|
252
|
+
print_info "Total records in large_table: $total_count"
|
|
253
|
+
|
|
254
|
+
if [ "$total_count" -ge 1000 ]; then
|
|
255
|
+
print_success "Table contains 1000+ records as expected"
|
|
256
|
+
else
|
|
257
|
+
print_fail "Table has less than 1000 records ($total_count found)"
|
|
258
|
+
track_test_failure
|
|
259
|
+
fi
|
|
260
|
+
else
|
|
261
|
+
print_fail "Could not parse record count"
|
|
262
|
+
echo "Response: $count_response"
|
|
263
|
+
track_test_failure
|
|
264
|
+
fi
|
|
265
|
+
else
|
|
266
|
+
print_fail "Failed to count records"
|
|
267
|
+
echo "Response: $count_response"
|
|
268
|
+
track_test_failure
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
# ========================================
|
|
272
|
+
# 6. Test Export endpoint
|
|
273
|
+
# ========================================
|
|
274
|
+
print_blue "6. Testing Export endpoint..."
|
|
275
|
+
|
|
276
|
+
# Export all data including schema
|
|
277
|
+
export_response=$(curl -s -X POST "$API_BASE/database/advance/export" \
|
|
278
|
+
-H "Content-Type: application/json" \
|
|
279
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
280
|
+
-d '{
|
|
281
|
+
"tables": ["large_table"],
|
|
282
|
+
"format": "sql",
|
|
283
|
+
"includeData": true,
|
|
284
|
+
"includeFunctions": true,
|
|
285
|
+
"includeSequences": true,
|
|
286
|
+
"includeViews": false
|
|
287
|
+
}')
|
|
288
|
+
|
|
289
|
+
if echo "$export_response" | grep -q '"error"'; then
|
|
290
|
+
print_fail "Failed to export database"
|
|
291
|
+
echo "Response preview: $(echo "$export_response" | head -c 500)..."
|
|
292
|
+
track_test_failure
|
|
293
|
+
else
|
|
294
|
+
print_success "Database exported successfully"
|
|
295
|
+
|
|
296
|
+
# Verify export contains expected elements
|
|
297
|
+
if echo "$export_response" | grep -q '"data"'; then
|
|
298
|
+
export_content=$(echo "$export_response" | jq -r '.data // empty')
|
|
299
|
+
|
|
300
|
+
if [ -n "$export_content" ]; then
|
|
301
|
+
# Check for table creation (use case statement to avoid broken pipe)
|
|
302
|
+
case "$export_content" in
|
|
303
|
+
*"CREATE TABLE"*"large_table"*)
|
|
304
|
+
print_success "Export contains table creation statement"
|
|
305
|
+
;;
|
|
306
|
+
*)
|
|
307
|
+
print_fail "Export missing table creation statement"
|
|
308
|
+
track_test_failure
|
|
309
|
+
;;
|
|
310
|
+
esac
|
|
311
|
+
|
|
312
|
+
# Check for data
|
|
313
|
+
case "$export_content" in
|
|
314
|
+
*"INSERT INTO"*"large_table"*)
|
|
315
|
+
print_success "Export contains data insertion statements"
|
|
316
|
+
;;
|
|
317
|
+
*)
|
|
318
|
+
print_fail "Export missing data insertion statements"
|
|
319
|
+
track_test_failure
|
|
320
|
+
;;
|
|
321
|
+
esac
|
|
322
|
+
|
|
323
|
+
# Check for RLS policies
|
|
324
|
+
case "$export_content" in
|
|
325
|
+
*"CREATE POLICY"*)
|
|
326
|
+
print_success "Export contains RLS policies"
|
|
327
|
+
;;
|
|
328
|
+
*)
|
|
329
|
+
print_fail "Export missing RLS policies"
|
|
330
|
+
track_test_failure
|
|
331
|
+
;;
|
|
332
|
+
esac
|
|
333
|
+
|
|
334
|
+
# Check for trigger
|
|
335
|
+
case "$export_content" in
|
|
336
|
+
*"CREATE TRIGGER"*"update_large_table_updated_at"*)
|
|
337
|
+
print_success "Export contains update trigger"
|
|
338
|
+
;;
|
|
339
|
+
*)
|
|
340
|
+
print_fail "Export missing update trigger"
|
|
341
|
+
track_test_failure
|
|
342
|
+
;;
|
|
343
|
+
esac
|
|
344
|
+
|
|
345
|
+
# Count INSERT statements to verify all data exported (using awk for efficiency)
|
|
346
|
+
insert_count=$(echo "$export_content" | awk '/INSERT INTO/ {count++} END {print count+0}')
|
|
347
|
+
print_info "Number of INSERT statements in export: $insert_count"
|
|
348
|
+
else
|
|
349
|
+
print_fail "Export content is empty"
|
|
350
|
+
track_test_failure
|
|
351
|
+
fi
|
|
352
|
+
else
|
|
353
|
+
print_fail "Export response missing data field"
|
|
354
|
+
echo "Response structure: $(echo "$export_response" | jq -r 'keys' 2>/dev/null || echo "$export_response" | head -c 200)"
|
|
355
|
+
track_test_failure
|
|
356
|
+
fi
|
|
357
|
+
fi
|
|
358
|
+
|
|
359
|
+
# ========================================
|
|
360
|
+
# 7. Test Export with row limit
|
|
361
|
+
# ========================================
|
|
362
|
+
print_blue "7. Testing Export with row limit..."
|
|
363
|
+
|
|
364
|
+
limited_export_response=$(curl -s -X POST "$API_BASE/database/advance/export" \
|
|
365
|
+
-H "Content-Type: application/json" \
|
|
366
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
367
|
+
-d '{
|
|
368
|
+
"tables": ["large_table"],
|
|
369
|
+
"format": "sql",
|
|
370
|
+
"includeData": true,
|
|
371
|
+
"rowLimit": 10
|
|
372
|
+
}')
|
|
373
|
+
|
|
374
|
+
if echo "$limited_export_response" | grep -q '"error"'; then
|
|
375
|
+
print_fail "Failed to export with row limit"
|
|
376
|
+
echo "Response preview: $(echo "$limited_export_response" | head -c 500)..."
|
|
377
|
+
track_test_failure
|
|
378
|
+
else
|
|
379
|
+
print_success "Export with row limit successful"
|
|
380
|
+
|
|
381
|
+
if echo "$limited_export_response" | grep -q '"data"'; then
|
|
382
|
+
limited_content=$(echo "$limited_export_response" | jq -r '.data // empty')
|
|
383
|
+
|
|
384
|
+
# Count data rows in limited export (should be much less than full export)
|
|
385
|
+
if [ -n "$limited_content" ]; then
|
|
386
|
+
limited_insert_count=$(echo "$limited_content" | awk '/INSERT INTO/ {count++} END {print count+0}')
|
|
387
|
+
print_info "INSERT statements in limited export: $limited_insert_count"
|
|
388
|
+
|
|
389
|
+
# Only compare if insert_count is set and valid
|
|
390
|
+
if [ -n "$insert_count" ] && [ "$insert_count" -gt 0 ] 2>/dev/null; then
|
|
391
|
+
if [ "$limited_insert_count" -lt "$insert_count" ] 2>/dev/null; then
|
|
392
|
+
print_success "Row limit is working (limited export has fewer rows)"
|
|
393
|
+
else
|
|
394
|
+
print_info "Unable to verify row limit effectiveness"
|
|
395
|
+
fi
|
|
396
|
+
else
|
|
397
|
+
print_info "Skipping row limit comparison (no full export count available)"
|
|
398
|
+
fi
|
|
399
|
+
fi
|
|
400
|
+
fi
|
|
401
|
+
fi
|
|
402
|
+
|
|
403
|
+
# ========================================
|
|
404
|
+
# Summary
|
|
405
|
+
# ========================================
|
|
406
|
+
echo ""
|
|
407
|
+
print_blue "=========================================="
|
|
408
|
+
print_blue "RawSQL/Export/Import Test Complete"
|
|
409
|
+
print_blue "=========================================="
|
|
410
|
+
|
|
411
|
+
# Exit with proper status
|
|
412
412
|
exit_with_status
|