//go:build mysql // +build mysql package mysql import ( "encoding/json" "time" "github.com/jmoiron/sqlx" t "github.com/tinode/chat/server/store/types" ) func (a *adapter) PublicUploadCreate(upload *t.PublicUpload) (*t.PublicUpload, error) { db := a.controlDB() if db == nil { return nil, t.ErrInternal } now := t.TimeNow() if upload.CreatedAt.IsZero() { upload.CreatedAt = now } if upload.UploadedAt.IsZero() { upload.UploadedAt = now } ctx, cancel := a.getContext() if cancel != nil { defer cancel() } _, err := db.ExecContext(ctx, `INSERT INTO im_public_uploads (file_id,purpose,mime_type,size,etag,location,expires_at,created_at,uploaded_at) VALUES(?,?,?,?,?,?,?,?,?)`, upload.FileID, upload.Purpose, upload.MimeType, upload.Size, upload.ETag, upload.Location, nullableTenantEntryTime(upload.ExpiresAt), upload.CreatedAt, upload.UploadedAt) if err != nil { return nil, err } return upload, nil } func (a *adapter) TenantApplicationCreate(application *t.TenantApplication) (*t.TenantApplication, error) { db := a.controlDB() if db == nil { return nil, t.ErrInternal } now := t.TimeNow() if application.Status == "" { application.Status = t.TenantApplicationStatusReceived } if application.EstimatedReviewHour <= 0 { application.EstimatedReviewHour = 24 } if application.SubmittedAt.IsZero() { application.SubmittedAt = now } application.CreatedAt = now application.UpdatedAt = now clientContext, _ := json.Marshal(application.ClientContext) ctx, cancel := a.getContext() if cancel != nil { defer cancel() } _, err := db.ExecContext(ctx, `INSERT INTO im_tenant_applications (application_id,credit_code,enterprise_email,license_file_id,tenant_code_hint,client_context,idempotency_key,status,estimated_review_hour,submitted_at,created_at,updated_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)`, application.ApplicationID, application.CreditCode, application.EnterpriseEmail, application.LicenseFileID, application.TenantCodeHint, string(clientContext), application.IdempotencyKey, application.Status, application.EstimatedReviewHour, application.SubmittedAt, now, now) if err != nil { return a.tenantApplicationByIdempotency(application.IdempotencyKey) } return a.tenantApplicationByIdempotency(application.IdempotencyKey) } func (a *adapter) TenantEntryFeedbackCreate(feedback *t.TenantEntryFeedback) (*t.TenantEntryFeedback, error) { db := a.controlDB() if db == nil { return nil, t.ErrInternal } now := t.TimeNow() if feedback.Status == "" { feedback.Status = t.TenantEntryFeedbackReceived } if feedback.SubmittedAt.IsZero() { feedback.SubmittedAt = now } feedback.CreatedAt = now feedback.UpdatedAt = now screenshots, _ := json.Marshal(feedback.ScreenshotFileIDs) clientContext, _ := json.Marshal(feedback.ClientContext) ctx, cancel := a.getContext() if cancel != nil { defer cancel() } _, err := db.ExecContext(ctx, `INSERT INTO im_tenant_entry_feedbacks (feedback_id,description,contact,tenant_code_hint,screenshot_file_ids,client_context,idempotency_key,status,submitted_at,created_at,updated_at) VALUES(?,?,?,?,?,?,?,?,?,?,?)`, feedback.FeedbackID, feedback.Description, feedback.Contact, feedback.TenantCodeHint, string(screenshots), string(clientContext), feedback.IdempotencyKey, feedback.Status, feedback.SubmittedAt, now, now) if err != nil { return a.tenantEntryFeedbackByIdempotency(feedback.IdempotencyKey) } return a.tenantEntryFeedbackByIdempotency(feedback.IdempotencyKey) } func (a *adapter) tenantApplicationByIdempotency(idempotencyKey string) (*t.TenantApplication, error) { db := a.controlDB() ctx, cancel := a.getContext() if cancel != nil { defer cancel() } row := struct { ApplicationID string `db:"application_id"` CreditCode string `db:"credit_code"` EnterpriseEmail string `db:"enterprise_email"` LicenseFileID string `db:"license_file_id"` TenantCodeHint string `db:"tenant_code_hint"` ClientContext []byte `db:"client_context"` IdempotencyKey string `db:"idempotency_key"` Status string `db:"status"` EstimatedReviewHour int `db:"estimated_review_hour"` SubmittedAt time.Time `db:"submitted_at"` CreatedAt time.Time `db:"created_at"` UpdatedAt time.Time `db:"updated_at"` }{} if err := db.GetContext(ctx, &row, `SELECT application_id,credit_code,enterprise_email,license_file_id, tenant_code_hint,client_context,idempotency_key,status,estimated_review_hour,submitted_at,created_at,updated_at FROM im_tenant_applications WHERE idempotency_key=?`, idempotencyKey); err != nil { return nil, err } app := &t.TenantApplication{ ApplicationID: row.ApplicationID, CreditCode: row.CreditCode, EnterpriseEmail: row.EnterpriseEmail, LicenseFileID: row.LicenseFileID, TenantCodeHint: row.TenantCodeHint, IdempotencyKey: row.IdempotencyKey, Status: row.Status, EstimatedReviewHour: row.EstimatedReviewHour, SubmittedAt: row.SubmittedAt, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt, } _ = json.Unmarshal(row.ClientContext, &app.ClientContext) return app, nil } func (a *adapter) tenantEntryFeedbackByIdempotency(idempotencyKey string) (*t.TenantEntryFeedback, error) { db := a.controlDB() ctx, cancel := a.getContext() if cancel != nil { defer cancel() } row := struct { FeedbackID string `db:"feedback_id"` Description string `db:"description"` Contact string `db:"contact"` TenantCodeHint string `db:"tenant_code_hint"` ScreenshotFileIDs []byte `db:"screenshot_file_ids"` ClientContext []byte `db:"client_context"` IdempotencyKey string `db:"idempotency_key"` Status string `db:"status"` SubmittedAt time.Time `db:"submitted_at"` CreatedAt time.Time `db:"created_at"` UpdatedAt time.Time `db:"updated_at"` }{} if err := db.GetContext(ctx, &row, `SELECT feedback_id,description,contact,tenant_code_hint, screenshot_file_ids,client_context,idempotency_key,status,submitted_at,created_at,updated_at FROM im_tenant_entry_feedbacks WHERE idempotency_key=?`, idempotencyKey); err != nil { return nil, err } feedback := &t.TenantEntryFeedback{ FeedbackID: row.FeedbackID, Description: row.Description, Contact: row.Contact, TenantCodeHint: row.TenantCodeHint, IdempotencyKey: row.IdempotencyKey, Status: row.Status, SubmittedAt: row.SubmittedAt, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt, } _ = json.Unmarshal(row.ScreenshotFileIDs, &feedback.ScreenshotFileIDs) _ = json.Unmarshal(row.ClientContext, &feedback.ClientContext) return feedback, nil } func (a *adapter) controlDB() *sqlx.DB { if a.registryDB != nil { return a.registryDB } return a.db } func nullableTenantEntryTime(value time.Time) any { if value.IsZero() { return nil } return value }