Merge pull request #19090 from owen-mc/review/egregius313/18902

Go: Add `database` source models for the `squirrel` package (#2)
This commit is contained in:
Owen Mansel-Chan
2025-03-27 15:54:25 +00:00
committed by GitHub
11 changed files with 941 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added `database` source models for the `github.com/Masterminds/squirrel` ORM package.

View File

@@ -6,6 +6,37 @@ extensions:
- ["squirrel", "github.com/Masterminds/squirrel"]
- ["squirrel", "gopkg.in/Masterminds/squirrel"]
- ["squirrel", "github.com/lann/squirrel"]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["group:squirrel", "", True, "QueryContextWith", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "", True, "QueryRowContextWith", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "", True, "QueryRowWith", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "", True, "QueryWith", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "QueryRower", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "QueryRowerContext", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "Queryer", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "QueryerContext", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "StdSql", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "StdSql", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "StdSqlCtx", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "StdSqlCtx", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
@@ -49,3 +80,5 @@ extensions:
- ["group:squirrel", "UpdateBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "Table", "", "", "Argument[0]", "sql-injection", "manual"]
# UpdateBuilder.Where has to be modeled in QL to avoid FPs when a non-string argument is used
# There are summary models for Row.Scan, RowScanner.Scan, {Insert,Delete,Select,Update}Builder.Scan and {Insert,Delete,Select,Update}Builder.ScanContext modeled in QL

View File

@@ -57,6 +57,7 @@ import semmle.go.frameworks.Protobuf
import semmle.go.frameworks.Revel
import semmle.go.frameworks.Spew
import semmle.go.frameworks.SQL
import semmle.go.frameworks.Squirrel
import semmle.go.frameworks.Stdlib
import semmle.go.frameworks.SystemCommandExecutors
import semmle.go.frameworks.Testing

View File

@@ -0,0 +1,85 @@
/**
* Provides classes modeling security-relevant aspects of the `squirrel` ORM package.
*/
import go
/**
* Provides classes modeling security-relevant aspects of the `squirrel` ORM package.
*/
module Squirrel {
private string packagePath() {
result =
package([
"github.com/Masterminds/squirrel",
"github.com/lann/squirrel",
"gopkg.in/Masterminds/squirrel",
], "")
}
private class RowScan extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;
RowScan() {
// signature: func (r *Row) Scan(dest ...interface{}) error
this.hasQualifiedName(packagePath(), "Row", "Scan") and
inp.isReceiver() and
outp.isParameter(_)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
private class RowScannerScan extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;
RowScannerScan() {
// signature: func (rs *RowScanner) Scan(dest ...interface{}) error
this.hasQualifiedName(packagePath(), "RowScanner", "Scan") and
inp.isReceiver() and
outp.isParameter(_)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
private class BuilderScan extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;
BuilderScan() {
// signature: func (b {Insert,Delete,Select,Update}Builder) Scan(dest ...interface{}) error
this.hasQualifiedName(packagePath(),
["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"], "Scan") and
inp.isReceiver() and
outp.isParameter(_)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
private class BuilderScanContext extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;
BuilderScanContext() {
// signature: func (b {Insert,Delete,Select,Update}Builder) ScanContext(ctx context.Context, dest ...interface{}) error
this.hasQualifiedName(packagePath(),
["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"], "ScanContext") and
inp.isReceiver() and
exists(int i | i > 0 | outp.isParameter(i))
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
}

View File

@@ -8,9 +8,11 @@ require (
github.com/couchbase/gocb v1.6.7
github.com/couchbase/gocb/v2 v2.9.4
github.com/jmoiron/sqlx v1.4.0
github.com/Masterminds/squirrel v1.5.4
github.com/rqlite/gorqlite v0.0.0-20250128004930-114c7828b55a
go.mongodb.org/mongo-driver v1.17.3
gorm.io/gorm v1.25.12
github.com/nonexistent/sources v0.0.0-20250300000000-000000000000
)
require (

View File

@@ -3,4 +3,9 @@ extensions:
pack: codeql/threat-models
extensible: threatModelConfiguration
data:
- ["database", true, 0]
- ["database", true, 0]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]

View File

@@ -5,3 +5,9 @@ extensions:
extensible: threatModelConfiguration
data:
- ["database", true, 0]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]

View File

@@ -0,0 +1,291 @@
package test
//go:generate depstubber -vendor github.com/Masterminds/squirrel DeleteBuilder,InsertBuilder,QueryRower,QueryRowerContext,Queryer,QueryerContext,SelectBuilder,StdSql,StdSqlCtx,UpdateBuilder QueryContextWith,QueryRowContextWith,QueryRowWith,QueryWith
import (
"context"
"github.com/Masterminds/squirrel"
src "github.com/nonexistent/sources"
)
func test_Masterminds_squirrel_QueryRower(ctx context.Context, db squirrel.QueryRower, sqlizer squirrel.Sqlizer) {
scanner := db.QueryRow("") // $ source
var r1, r2, r3 string
scanner.Scan(&r1, &r2, &r3)
sink(r1) // $ hasTaintFlow="r1"
sink(r2) // $ hasTaintFlow="r2"
sink(r3) // $ hasTaintFlow="r3"
scanner2 := squirrel.QueryRowWith(db, sqlizer) // $ source
var r4, r5, r6 string
scanner2.Scan(&r4, &r5, &r6)
sink(r4) // $ hasTaintFlow="r4"
sink(r5) // $ hasTaintFlow="r5"
sink(r6) // $ hasTaintFlow="r6"
}
func test_Masterminds_squirrel_QueryRowerContext(ctx context.Context, db squirrel.QueryRowerContext, sqlizer squirrel.Sqlizer) {
scanner := db.QueryRowContext(ctx, "") // $ source
var r1, r2, r3 string
scanner.Scan(&r1, &r2, &r3)
sink(r1) // $ hasTaintFlow="r1"
sink(r2) // $ hasTaintFlow="r2"
sink(r3) // $ hasTaintFlow="r3"
scanner2 := squirrel.QueryRowContextWith(ctx, db, sqlizer) // $ source
var r4, r5, r6 string
scanner2.Scan(&r4, &r5, &r6)
sink(r4) // $ hasTaintFlow="r4"
sink(r5) // $ hasTaintFlow="r5"
sink(r6) // $ hasTaintFlow="r6"
}
func test_Masterminds_squirrel_Queryer(ctx context.Context, db squirrel.Queryer, sqlizer squirrel.Sqlizer) {
v1, err := db.Query("") // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := squirrel.QueryWith(db, sqlizer) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
}
func test_Masterminds_squirrel_QueryerContext(ctx context.Context, db squirrel.QueryerContext, sqlizer squirrel.Sqlizer) {
v1, err := db.QueryContext(ctx, "") // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := squirrel.QueryContextWith(ctx, db, sqlizer) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
}
// StdSqlCtx extends StdSql so we can test both with a StdSqlCtx
func test_Masterminds_squirrel_StdSql_StdSqlCtx(ctx context.Context, std squirrel.StdSqlCtx) {
v1, err := std.Query("") // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := std.QueryContext(ctx, "") // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
s3 := std.QueryRow("") // $ source
if err != nil {
return
}
var r31, r32, r33 string
s3.Scan(&r31, &r32, &r33)
sink(r31) // $ hasTaintFlow="r31"
sink(r32) // $ hasTaintFlow="r32"
sink(r33) // $ hasTaintFlow="r33"
s4 := std.QueryRowContext(ctx, "") // $ source
var r41, r42, r43 string
s4.Scan(&r41, &r42, &r43)
sink(r41) // $ hasTaintFlow="r41"
sink(r42) // $ hasTaintFlow="r42"
sink(r43) // $ hasTaintFlow="r43"
}
func test_Masterminds_squirrel_DeleteBuilder(ctx context.Context, builder squirrel.DeleteBuilder) {
v1, err := builder.Query() // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := builder.QueryContext(ctx) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
s3 := builder.QueryRowContext(ctx) // $ source
var r31, r32, r33 string
s3.Scan(&r31, &r32, &r33)
sink(r31) // $ hasTaintFlow="r31"
sink(r32) // $ hasTaintFlow="r32"
sink(r33) // $ hasTaintFlow="r33"
builder2 := src.Source[squirrel.DeleteBuilder]() // $ source
var r41, r42, r43 string
builder2.ScanContext(ctx, &r41, &r42, &r43)
sink(r41) // $ hasTaintFlow="r41"
sink(r42) // $ hasTaintFlow="r42"
sink(r43) // $ hasTaintFlow="r43"
}
func test_Masterminds_squirrel_InsertBuilder(ctx context.Context, builder squirrel.InsertBuilder) {
v1, err := builder.Query() // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := builder.QueryContext(ctx) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
s3 := builder.QueryRow() // $ source
var r31, r32, r33 string
s3.Scan(&r31, &r32, &r33)
sink(r31) // $ hasTaintFlow="r31"
sink(r32) // $ hasTaintFlow="r32"
sink(r33) // $ hasTaintFlow="r33"
s4 := builder.QueryRowContext(ctx) // $ source
var r41, r42, r43 string
s4.Scan(&r41, &r42, &r43)
sink(r41) // $ hasTaintFlow="r41"
sink(r42) // $ hasTaintFlow="r42"
sink(r43) // $ hasTaintFlow="r43"
builder2 := src.Source[squirrel.InsertBuilder]() // $ source
var r51, r52, r53 string
builder2.Scan(&r51, &r52, &r53)
sink(r51) // $ hasTaintFlow="r51"
sink(r52) // $ hasTaintFlow="r52"
sink(r53) // $ hasTaintFlow="r53"
var r61, r62, r63 string
builder2.ScanContext(ctx, &r61, &r62, &r63)
sink(r61) // $ hasTaintFlow="r61"
sink(r62) // $ hasTaintFlow="r62"
sink(r63) // $ hasTaintFlow="r63"
}
func test_Masterminds_squirrel_SelectBuilder(ctx context.Context, builder squirrel.SelectBuilder) {
v1, err := builder.Query() // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := builder.QueryContext(ctx) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
s3 := builder.QueryRow() // $ source
var r31, r32, r33 string
s3.Scan(&r31, &r32, &r33)
sink(r31) // $ hasTaintFlow="r31"
sink(r32) // $ hasTaintFlow="r32"
sink(r33) // $ hasTaintFlow="r33"
s4 := builder.QueryRowContext(ctx) // $ source
var r41, r42, r43 string
s4.Scan(&r41, &r42, &r43)
sink(r41) // $ hasTaintFlow="r41"
sink(r42) // $ hasTaintFlow="r42"
sink(r43) // $ hasTaintFlow="r43"
builder2 := src.Source[squirrel.SelectBuilder]() // $ source
var r51, r52, r53 string
builder2.Scan(&r51, &r52, &r53)
sink(r51) // $ hasTaintFlow="r51"
sink(r52) // $ hasTaintFlow="r52"
sink(r53) // $ hasTaintFlow="r53"
var r61, r62, r63 string
builder2.ScanContext(ctx, &r61, &r62, &r63)
sink(r61) // $ hasTaintFlow="r61"
sink(r62) // $ hasTaintFlow="r62"
sink(r63) // $ hasTaintFlow="r63"
}
func test_Masterminds_squirrel_UpdateBuilder(ctx context.Context, builder squirrel.UpdateBuilder) {
v1, err := builder.Query() // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := builder.QueryContext(ctx) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
s3 := builder.QueryRow() // $ source
var r31, r32, r33 string
s3.Scan(&r31, &r32, &r33)
sink(r31) // $ hasTaintFlow="r31"
sink(r32) // $ hasTaintFlow="r32"
sink(r33) // $ hasTaintFlow="r33"
s4 := builder.QueryRowContext(ctx) // $ source
var r41, r42, r43 string
s4.Scan(&r41, &r42, &r43)
sink(r41) // $ hasTaintFlow="r41"
sink(r42) // $ hasTaintFlow="r42"
sink(r43) // $ hasTaintFlow="r43"
builder2 := src.Source[squirrel.UpdateBuilder]() // $ source
var r51, r52, r53 string
builder2.Scan(&r51, &r52, &r53)
sink(r51) // $ hasTaintFlow="r51"
sink(r52) // $ hasTaintFlow="r52"
sink(r53) // $ hasTaintFlow="r53"
var r61, r62, r63 string
builder2.ScanContext(ctx, &r61, &r62, &r63)
sink(r61) // $ hasTaintFlow="r61"
sink(r62) // $ hasTaintFlow="r62"
sink(r63) // $ hasTaintFlow="r63"
}

View File

@@ -0,0 +1,501 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for github.com/Masterminds/squirrel, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: github.com/Masterminds/squirrel (exports: DeleteBuilder,InsertBuilder,QueryRower,QueryRowerContext,Queryer,QueryerContext,SelectBuilder,StdSql,StdSqlCtx,UpdateBuilder; functions: QueryContextWith,QueryRowContextWith,QueryRowWith,QueryWith)
// Package squirrel is a stub of github.com/Masterminds/squirrel, generated by depstubber.
package squirrel
import (
context "context"
sql "database/sql"
)
type BaseRunner interface {
Exec(_ string, _ ...interface{}) (sql.Result, error)
Query(_ string, _ ...interface{}) (*sql.Rows, error)
}
type DeleteBuilder struct{}
func (_ DeleteBuilder) Exec() (sql.Result, error) {
return nil, nil
}
func (_ DeleteBuilder) ExecContext(_ context.Context) (sql.Result, error) {
return nil, nil
}
func (_ DeleteBuilder) From(_ string) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) Limit(_ uint64) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) MustSql() (string, []interface{}) {
return "", nil
}
func (_ DeleteBuilder) Offset(_ uint64) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) OrderBy(_ ...string) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) PlaceholderFormat(_ PlaceholderFormat) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) Prefix(_ string, _ ...interface{}) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) PrefixExpr(_ Sqlizer) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) Query() (*sql.Rows, error) {
return nil, nil
}
func (_ DeleteBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
return nil, nil
}
func (_ DeleteBuilder) QueryRowContext(_ context.Context) RowScanner {
return nil
}
func (_ DeleteBuilder) RunWith(_ BaseRunner) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
return nil
}
func (_ DeleteBuilder) Suffix(_ string, _ ...interface{}) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) SuffixExpr(_ Sqlizer) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) ToSql() (string, []interface{}, error) {
return "", nil, nil
}
func (_ DeleteBuilder) Where(_ interface{}, _ ...interface{}) DeleteBuilder {
return DeleteBuilder{}
}
type InsertBuilder struct{}
func (_ InsertBuilder) Columns(_ ...string) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) Exec() (sql.Result, error) {
return nil, nil
}
func (_ InsertBuilder) ExecContext(_ context.Context) (sql.Result, error) {
return nil, nil
}
func (_ InsertBuilder) Into(_ string) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) MustSql() (string, []interface{}) {
return "", nil
}
func (_ InsertBuilder) Options(_ ...string) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) PlaceholderFormat(_ PlaceholderFormat) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) Prefix(_ string, _ ...interface{}) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) PrefixExpr(_ Sqlizer) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) Query() (*sql.Rows, error) {
return nil, nil
}
func (_ InsertBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
return nil, nil
}
func (_ InsertBuilder) QueryRow() RowScanner {
return nil
}
func (_ InsertBuilder) QueryRowContext(_ context.Context) RowScanner {
return nil
}
func (_ InsertBuilder) RunWith(_ BaseRunner) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) Scan(_ ...interface{}) error {
return nil
}
func (_ InsertBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
return nil
}
func (_ InsertBuilder) Select(_ SelectBuilder) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) SetMap(_ map[string]interface{}) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) Suffix(_ string, _ ...interface{}) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) SuffixExpr(_ Sqlizer) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) ToSql() (string, []interface{}, error) {
return "", nil, nil
}
func (_ InsertBuilder) Values(_ ...interface{}) InsertBuilder {
return InsertBuilder{}
}
type PlaceholderFormat interface {
ReplacePlaceholders(_ string) (string, error)
}
func QueryContextWith(_ context.Context, _ QueryerContext, _ Sqlizer) (*sql.Rows, error) {
return nil, nil
}
func QueryRowContextWith(_ context.Context, _ QueryRowerContext, _ Sqlizer) RowScanner {
return nil
}
func QueryRowWith(_ QueryRower, _ Sqlizer) RowScanner {
return nil
}
type QueryRower interface {
QueryRow(_ string, _ ...interface{}) RowScanner
}
type QueryRowerContext interface {
QueryRowContext(_ context.Context, _ string, _ ...interface{}) RowScanner
}
func QueryWith(_ Queryer, _ Sqlizer) (*sql.Rows, error) {
return nil, nil
}
type Queryer interface {
Query(_ string, _ ...interface{}) (*sql.Rows, error)
}
type QueryerContext interface {
QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error)
}
type RowScanner interface {
Scan(_ ...interface{}) error
}
type SelectBuilder struct{}
func (_ SelectBuilder) Column(_ interface{}, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Columns(_ ...string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) CrossJoin(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Distinct() SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Exec() (sql.Result, error) {
return nil, nil
}
func (_ SelectBuilder) ExecContext(_ context.Context) (sql.Result, error) {
return nil, nil
}
func (_ SelectBuilder) From(_ string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) FromSelect(_ SelectBuilder, _ string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) GroupBy(_ ...string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Having(_ interface{}, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) InnerJoin(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Join(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) JoinClause(_ interface{}, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) LeftJoin(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Limit(_ uint64) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) MustSql() (string, []interface{}) {
return "", nil
}
func (_ SelectBuilder) Offset(_ uint64) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Options(_ ...string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) OrderBy(_ ...string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) OrderByClause(_ interface{}, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) PlaceholderFormat(_ PlaceholderFormat) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Prefix(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) PrefixExpr(_ Sqlizer) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Query() (*sql.Rows, error) {
return nil, nil
}
func (_ SelectBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
return nil, nil
}
func (_ SelectBuilder) QueryRow() RowScanner {
return nil
}
func (_ SelectBuilder) QueryRowContext(_ context.Context) RowScanner {
return nil
}
func (_ SelectBuilder) RemoveColumns() SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) RemoveLimit() SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) RemoveOffset() SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) RightJoin(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) RunWith(_ BaseRunner) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Scan(_ ...interface{}) error {
return nil
}
func (_ SelectBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
return nil
}
func (_ SelectBuilder) Suffix(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) SuffixExpr(_ Sqlizer) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) ToSql() (string, []interface{}, error) {
return "", nil, nil
}
func (_ SelectBuilder) Where(_ interface{}, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
type Sqlizer interface {
ToSql() (string, []interface{}, error)
}
type StdSql interface {
Exec(_ string, _ ...interface{}) (sql.Result, error)
Query(_ string, _ ...interface{}) (*sql.Rows, error)
QueryRow(_ string, _ ...interface{}) *sql.Row
}
type StdSqlCtx interface {
Exec(_ string, _ ...interface{}) (sql.Result, error)
ExecContext(_ context.Context, _ string, _ ...interface{}) (sql.Result, error)
Query(_ string, _ ...interface{}) (*sql.Rows, error)
QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error)
QueryRow(_ string, _ ...interface{}) *sql.Row
QueryRowContext(_ context.Context, _ string, _ ...interface{}) *sql.Row
}
type UpdateBuilder struct{}
func (_ UpdateBuilder) Exec() (sql.Result, error) {
return nil, nil
}
func (_ UpdateBuilder) ExecContext(_ context.Context) (sql.Result, error) {
return nil, nil
}
func (_ UpdateBuilder) From(_ string) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) FromSelect(_ SelectBuilder, _ string) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Limit(_ uint64) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) MustSql() (string, []interface{}) {
return "", nil
}
func (_ UpdateBuilder) Offset(_ uint64) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) OrderBy(_ ...string) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) PlaceholderFormat(_ PlaceholderFormat) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Prefix(_ string, _ ...interface{}) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) PrefixExpr(_ Sqlizer) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Query() (*sql.Rows, error) {
return nil, nil
}
func (_ UpdateBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
return nil, nil
}
func (_ UpdateBuilder) QueryRow() RowScanner {
return nil
}
func (_ UpdateBuilder) QueryRowContext(_ context.Context) RowScanner {
return nil
}
func (_ UpdateBuilder) RunWith(_ BaseRunner) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Scan(_ ...interface{}) error {
return nil
}
func (_ UpdateBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
return nil
}
func (_ UpdateBuilder) Set(_ string, _ interface{}) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) SetMap(_ map[string]interface{}) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Suffix(_ string, _ ...interface{}) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) SuffixExpr(_ Sqlizer) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Table(_ string) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) ToSql() (string, []interface{}, error) {
return "", nil, nil
}
func (_ UpdateBuilder) Where(_ interface{}, _ ...interface{}) UpdateBuilder {
return UpdateBuilder{}
}

View File

@@ -0,0 +1,5 @@
package sources
func Source[T any]() T {
return *new(T)
}

View File

@@ -13,6 +13,9 @@ github.com/couchbase/gocb/v2
# github.com/jmoiron/sqlx v1.4.0
## explicit
github.com/jmoiron/sqlx
# github.com/Masterminds/squirrel v1.5.4
## explicit
github.com/Masterminds/squirrel
# github.com/rqlite/gorqlite v0.0.0-20250128004930-114c7828b55a
## explicit
github.com/rqlite/gorqlite
@@ -22,6 +25,9 @@ go.mongodb.org/mongo-driver/mongo
# gorm.io/gorm v1.25.12
## explicit
gorm.io/gorm
# github.com/nonexistent/sources v0.0.0-20250300000000-000000000000
## explicit
github.com/nonexistent/sources
# github.com/couchbase/gocbcore/v10 v10.5.4
## explicit
github.com/couchbase/gocbcore/v10