-
Notifications
You must be signed in to change notification settings - Fork 9
v1.0.4-preview.3 #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v1.0.4-preview.3 #14
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -278,6 +278,9 @@ func migrateDB() error { | |
| if err := migrateTokenModelLimitsToText(); err != nil { | ||
| return err | ||
| } | ||
| if err := migrateUserQuotaColumnsToBigInt(); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| err := DB.AutoMigrate( | ||
| &Channel{}, | ||
|
|
@@ -331,6 +334,9 @@ func migrateDB() error { | |
| } | ||
|
|
||
| func migrateDBFast() error { | ||
| if err := migrateUserQuotaColumnsToBigInt(); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| var wg sync.WaitGroup | ||
|
|
||
|
|
@@ -660,6 +666,55 @@ func migrateTokenModelLimitsToText() error { | |
| return nil | ||
| } | ||
|
|
||
| func migrateUserQuotaColumnsToBigInt() error { | ||
| if DB == nil || common.UsingSQLite || !DB.Migrator().HasTable(&User{}) { | ||
| return nil | ||
| } | ||
|
|
||
| tableName := "users" | ||
| columnNames := []string{"quota", "used_quota", "aff_quota", "aff_history"} | ||
|
|
||
| for _, columnName := range columnNames { | ||
| if !DB.Migrator().HasColumn(&User{}, columnName) { | ||
| continue | ||
| } | ||
|
|
||
| var alterSQL string | ||
| if common.UsingPostgreSQL { | ||
| var dataType string | ||
| if err := DB.Raw(`SELECT data_type FROM information_schema.columns | ||
| WHERE table_schema = current_schema() AND table_name = ? AND column_name = ?`, | ||
| tableName, columnName).Scan(&dataType).Error; err != nil { | ||
| common.SysLog(fmt.Sprintf("Warning: failed to query metadata for %s.%s: %v", tableName, columnName, err)) | ||
| } else if strings.EqualFold(dataType, "bigint") { | ||
| continue | ||
| } | ||
| alterSQL = fmt.Sprintf(`ALTER TABLE "%s" ALTER COLUMN "%s" TYPE bigint USING "%s"::bigint`, | ||
| tableName, columnName, columnName) | ||
| } else if common.UsingMySQL { | ||
| var columnType string | ||
| if err := DB.Raw(`SELECT COLUMN_TYPE FROM information_schema.columns | ||
| WHERE table_schema = DATABASE() AND table_name = ? AND column_name = ?`, | ||
| tableName, columnName).Scan(&columnType).Error; err != nil { | ||
| common.SysLog(fmt.Sprintf("Warning: failed to query metadata for %s.%s: %v", tableName, columnName, err)) | ||
| } else if strings.HasPrefix(strings.ToLower(columnType), "bigint") { | ||
| continue | ||
| } | ||
| alterSQL = fmt.Sprintf("ALTER TABLE `%s` MODIFY COLUMN `%s` bigint DEFAULT 0", tableName, columnName) | ||
|
Comment on lines
+694
to
+703
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- model/main.go around 660-730 ---'
sed -n '660,730p' model/main.go
echo
echo '--- search quota-related definitions/usages ---'
rg -n "quota|used_quota|aff_quota|aff_history" model . --glob '!**/vendor/**' --glob '!**/node_modules/**'Repository: MAX-API-Next/MAX-API Length of output: 50377 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- model/user.go struct around quota fields ---'
sed -n '50,85p' model/user.go
echo
echo '--- search for user table migrations / schema creation ---'
rg -n "AutoMigrate|CreateTable|quota.*not null|used_quota.*not null|aff_quota.*not null|aff_history.*not null|type:bigint;default:0" model --glob '!**/vendor/**' --glob '!**/node_modules/**'Repository: MAX-API-Next/MAX-API Length of output: 4935 🌐 Web query:
💡 Result: In GORM v2, AutoMigrate handles integer field nullable/NOT NULL constraints based on the Go struct type definition and GORM tags [1][2][3]. 1. Field Nullability: By default, Go primitive types (e.g., int, int64) are treated as non-nullable [3]. To make an integer field nullable, use a pointer type (e.g., *int) or sql.NullInt64 [4][5][3]. 2. NOT NULL Constraint: Use the Citations:
Preserve the existing 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| if alterSQL == "" { | ||
| continue | ||
| } | ||
| if err := DB.Exec(alterSQL).Error; err != nil { | ||
| return fmt.Errorf("failed to migrate %s.%s to bigint: %w", tableName, columnName, err) | ||
| } | ||
| common.SysLog(fmt.Sprintf("Successfully migrated %s.%s to bigint", tableName, columnName)) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
|
Comment on lines
+669
to
+717
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Raw-SQL pre-migration for a large
🤖 Prompt for AI Agents |
||
| // migrateSubscriptionPlanPriceAmount migrates price_amount column from float/double to decimal(10,6) | ||
| // This is safe to run multiple times - it checks the column type first | ||
| func migrateSubscriptionPlanPriceAmount() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,14 +64,14 @@ type User struct { | |
| TelegramId string `json:"telegram_id" gorm:"column:telegram_id;index"` | ||
| VerificationCode string `json:"verification_code" gorm:"-:all"` // this field is only for Email verification, don't save it to database! | ||
| AccessToken *string `json:"-" gorm:"type:char(32);column:access_token;uniqueIndex"` // this token is for system management | ||
| Quota int `json:"quota" gorm:"type:int;default:0"` | ||
| UsedQuota int `json:"used_quota" gorm:"type:int;default:0;column:used_quota"` // used quota | ||
| RequestCount int `json:"request_count" gorm:"type:int;default:0;"` // request number | ||
| Quota int `json:"quota" gorm:"type:bigint;default:0"` | ||
| UsedQuota int `json:"used_quota" gorm:"type:bigint;default:0;column:used_quota"` // used quota | ||
| RequestCount int `json:"request_count" gorm:"type:int;default:0;"` // request number | ||
| Group string `json:"group" gorm:"type:varchar(64);default:'default'"` | ||
| AffCode string `json:"aff_code" gorm:"type:varchar(32);column:aff_code;uniqueIndex"` | ||
| AffCount int `json:"aff_count" gorm:"type:int;default:0;column:aff_count"` | ||
| AffQuota int `json:"aff_quota" gorm:"type:int;default:0;column:aff_quota"` // 邀请剩余额度 | ||
| AffHistoryQuota int `json:"aff_history_quota" gorm:"type:int;default:0;column:aff_history"` // 邀请历史额度 | ||
| AffQuota int `json:"aff_quota" gorm:"type:bigint;default:0;column:aff_quota"` // 邀请剩余额度 | ||
| AffHistoryQuota int `json:"aff_history_quota" gorm:"type:bigint;default:0;column:aff_history"` // 邀请历史额度 | ||
|
Comment on lines
+67
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Assess ripple effect of widening quota fields to int64
rg -nP '\.(Quota|UsedQuota|AffQuota|AffHistoryQuota)\b' --type=go -C2 | rg -v '_test\.go'Repository: MAX-API-Next/MAX-API Length of output: 158 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n## model/user.go context\n'
sed -n '1,160p' model/user.go
printf '\n## quota-related symbols in Go files\n'
rg -n --glob '*.go' '\b(Quota|UsedQuota|AffQuota|AffHistoryQuota)\b|isValidQuota(Override|Addition)|quota' model controller service pkg -C 2Repository: MAX-API-Next/MAX-API Length of output: 50377 🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '1,160p' model/user.goRepository: MAX-API-Next/MAX-API Length of output: 7113 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf 'FILE: model/user.go\n'
cat -n model/user.go | sed -n '55,90p'
printf '\nUSAGES:\n'
rg -n --glob '*.go' '\b(Quota|UsedQuota|AffQuota|AffHistoryQuota)\b|isValidQuota(Override|Addition)' .Repository: MAX-API-Next/MAX-API Length of output: 22787 Use 🤖 Prompt for AI Agents |
||
| InviterId int `json:"inviter_id" gorm:"type:int;column:inviter_id;index"` | ||
| DeletedAt gorm.DeletedAt `gorm:"index"` | ||
| LinuxDOId string `json:"linux_do_id" gorm:"column:linux_do_id;index"` | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win
Test doesn't exercise the actual int64-max boundary or overflow protection.
The updated assertions only prove values beyond the old int32 limit are now accepted; they don't cover the new overflow-safe subtraction check (
current <= maxUserQuotaValue-delta) near the realmaxUserQuotaValueboundary, which is the actual correctness improvement inisValidQuotaAddition.✅ Suggested additional boundary cases
📝 Committable suggestion
🤖 Prompt for AI Agents