docs: Add CLAUDE.md with codebase guidance
Create comprehensive documentation for future Claude Code instances working in this repository, including: - Development commands for testing, building, and code quality - Core architecture overview of the SQL query builder system - Directory structure and component explanations - Testing patterns and conventions - Key dependencies and their purposes 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+54
-6
@@ -5,12 +5,13 @@ import (
|
||||
gsql "database/sql"
|
||||
"reflect"
|
||||
|
||||
"git.fsdpf.net/go/db/v2/internal/errors"
|
||||
"git.fsdpf.net/go/db/v2/internal/util"
|
||||
"git.fsdpf.net/go/db/internal/errors"
|
||||
"git.fsdpf.net/go/db/internal/util"
|
||||
)
|
||||
|
||||
type (
|
||||
QueryExecutor struct {
|
||||
hook func(result interface{}) error
|
||||
de DbExecutor
|
||||
err error
|
||||
query string
|
||||
@@ -19,6 +20,8 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
errUnsupportedScanMapType = errors.New("type must be a pointer to a map when scanning into a map")
|
||||
errUnsupportedScanMapsType = errors.New("type must be a pointer to a slice when scanning into a map")
|
||||
errUnsupportedScanStructType = errors.New("type must be a pointer to a struct when scanning into a struct")
|
||||
errUnsupportedScanStructsType = errors.New("type must be a pointer to a slice when scanning into structs")
|
||||
errUnsupportedScanValsType = errors.New("type must be a pointer to a slice when scanning into vals")
|
||||
@@ -38,22 +41,34 @@ func (q QueryExecutor) Exec() (gsql.Result, error) {
|
||||
return q.ExecContext(context.Background())
|
||||
}
|
||||
|
||||
func (q QueryExecutor) ExecContext(ctx context.Context) (gsql.Result, error) {
|
||||
func (q QueryExecutor) ExecContext(ctx context.Context) (result gsql.Result, err error) {
|
||||
if q.err != nil {
|
||||
return nil, q.err
|
||||
}
|
||||
return q.de.ExecContext(ctx, q.query, q.args...)
|
||||
result, err = q.de.ExecContext(ctx, q.query, q.args...)
|
||||
defer func() {
|
||||
if err == nil && q.hook != nil {
|
||||
err = q.hook(result)
|
||||
}
|
||||
}()
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (q QueryExecutor) Query() (*gsql.Rows, error) {
|
||||
return q.QueryContext(context.Background())
|
||||
}
|
||||
|
||||
func (q QueryExecutor) QueryContext(ctx context.Context) (*gsql.Rows, error) {
|
||||
func (q QueryExecutor) QueryContext(ctx context.Context) (result *gsql.Rows, err error) {
|
||||
if q.err != nil {
|
||||
return nil, q.err
|
||||
}
|
||||
return q.de.QueryContext(ctx, q.query, q.args...)
|
||||
result, err = q.de.QueryContext(ctx, q.query, q.args...)
|
||||
defer func() {
|
||||
if err == nil && q.hook != nil {
|
||||
err = q.hook(result)
|
||||
}
|
||||
}()
|
||||
return result, err
|
||||
}
|
||||
|
||||
// This will execute the SQL and append results to the slice
|
||||
@@ -238,6 +253,35 @@ func (q QueryExecutor) ScanValContext(ctx context.Context, i interface{}) (bool,
|
||||
return false, scanner.Err()
|
||||
}
|
||||
|
||||
func (q QueryExecutor) GetRecord() (map[string]any, error) {
|
||||
return q.GetRecordContext(context.Background())
|
||||
}
|
||||
|
||||
func (q QueryExecutor) GetRecordContext(ctx context.Context) (map[string]any, error) {
|
||||
scanner, err := q.ScannerContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() { _ = scanner.Close() }()
|
||||
if scanner.Next() {
|
||||
return scanner.GetRecord()
|
||||
}
|
||||
return nil, scanner.Err()
|
||||
}
|
||||
|
||||
func (q QueryExecutor) GetRecords() ([]map[string]any, error) {
|
||||
return q.GetRecordsContext(context.Background())
|
||||
}
|
||||
|
||||
func (q QueryExecutor) GetRecordsContext(ctx context.Context) ([]map[string]any, error) {
|
||||
scanner, err := q.ScannerContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() { _ = scanner.Close() }()
|
||||
return scanner.GetRecords()
|
||||
}
|
||||
|
||||
// Scanner will return a Scanner that can be used for manually scanning rows.
|
||||
func (q QueryExecutor) Scanner() (Scanner, error) {
|
||||
return q.ScannerContext(context.Background())
|
||||
@@ -251,3 +295,7 @@ func (q QueryExecutor) ScannerContext(ctx context.Context) (Scanner, error) {
|
||||
}
|
||||
return NewScanner(rows), nil
|
||||
}
|
||||
|
||||
func (q *QueryExecutor) Hook(hook func(dataset interface{}) error) {
|
||||
q.hook = hook
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user