package tenant import ( "context" "database/sql" "encoding/json" ) func (q *Queries) CountPlugins(ctx context.Context) (int, error) { var count int err := q.db.QueryRowContext(ctx, `SELECT COUNT(*) FROM plugins`).Scan(&count) return count, err } func (q *Queries) ListPlugins(ctx context.Context) ([]Plugin, error) { rows, err := q.db.QueryContext(ctx, `SELECT id, name, language, source, hooks, enabled, LENGTH(wasm) as wasm_size, created_at, updated_at FROM plugins ORDER BY name`) if err != nil { return nil, err } defer rows.Close() var plugins []Plugin for rows.Next() { p, err := scanPluginList(rows) if err != nil { return nil, err } plugins = append(plugins, p) } return plugins, rows.Err() } func (q *Queries) GetPlugin(ctx context.Context, id string) (*Plugin, error) { row := q.db.QueryRowContext(ctx, `SELECT id, name, language, source, wasm, hooks, enabled, created_at, updated_at FROM plugins WHERE id = ?`, id) p, err := scanPlugin(row) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, err } return &p, nil } func (q *Queries) CreatePlugin(ctx context.Context, p *Plugin) error { hooks, _ := json.Marshal(p.Hooks) _, err := q.db.ExecContext(ctx, `INSERT INTO plugins (id, name, language, source, wasm, hooks, enabled) VALUES (?, ?, ?, ?, ?, ?, ?)`, p.ID, p.Name, p.Language, p.Source, p.Wasm, string(hooks), boolToInt(p.Enabled)) return err } func (q *Queries) UpdatePlugin(ctx context.Context, p *Plugin) error { hooks, _ := json.Marshal(p.Hooks) _, err := q.db.ExecContext(ctx, `UPDATE plugins SET name = ?, language = ?, source = ?, wasm = ?, hooks = ?, enabled = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`, p.Name, p.Language, p.Source, p.Wasm, string(hooks), boolToInt(p.Enabled), p.ID) return err } func (q *Queries) DeletePlugin(ctx context.Context, id string) error { _, err := q.db.ExecContext(ctx, `DELETE FROM plugins WHERE id = ?`, id) return err } func (q *Queries) GetPluginsByHook(ctx context.Context, hook string) ([]Plugin, error) { rows, err := q.db.QueryContext(ctx, `SELECT id, name, language, source, wasm, hooks, enabled, created_at, updated_at FROM plugins WHERE enabled = 1 AND hooks LIKE ?`, "%"+hook+"%") if err != nil { return nil, err } defer rows.Close() var plugins []Plugin for rows.Next() { p, err := scanPlugin(rows) if err != nil { return nil, err } for _, h := range p.Hooks { if h == hook { plugins = append(plugins, p) break } } } return plugins, rows.Err() } func (q *Queries) TogglePlugin(ctx context.Context, id string, enabled bool) error { _, err := q.db.ExecContext(ctx, `UPDATE plugins SET enabled = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`, boolToInt(enabled), id) return err } func scanPlugin(s scanner) (Plugin, error) { var p Plugin var hooks string var enabled sql.NullInt64 var createdAt, updatedAt sql.NullString err := s.Scan(&p.ID, &p.Name, &p.Language, &p.Source, &p.Wasm, &hooks, &enabled, &createdAt, &updatedAt) if err != nil { return p, err } p.Enabled = enabled.Int64 == 1 p.CreatedAt = parseTime(createdAt.String) p.UpdatedAt = parseTime(updatedAt.String) json.Unmarshal([]byte(hooks), &p.Hooks) return p, nil } func scanPluginList(s scanner) (Plugin, error) { var p Plugin var hooks string var enabled sql.NullInt64 var wasmSize sql.NullInt64 var createdAt, updatedAt sql.NullString err := s.Scan(&p.ID, &p.Name, &p.Language, &p.Source, &hooks, &enabled, &wasmSize, &createdAt, &updatedAt) if err != nil { return p, err } p.Enabled = enabled.Int64 == 1 p.WasmSize = int(wasmSize.Int64) p.CreatedAt = parseTime(createdAt.String) p.UpdatedAt = parseTime(updatedAt.String) json.Unmarshal([]byte(hooks), &p.Hooks) return p, nil }