stardb/builder.go

135 lines
3.0 KiB
Go
Raw Permalink Normal View History

2026-03-07 19:27:44 +08:00
package stardb
import (
"fmt"
"strings"
)
// QueryBuilder helps build SQL queries
type QueryBuilder struct {
table string
columns []string
joins []string
where []string
whereArgs []interface{}
groupBy []string
having []string
havingArgs []interface{}
orderBy string
limit int
offset int
2026-03-07 19:27:44 +08:00
}
// NewQueryBuilder creates a new query builder
func NewQueryBuilder(table string) *QueryBuilder {
return &QueryBuilder{
table: table,
columns: []string{"*"},
}
}
// Select sets the columns to select
func (qb *QueryBuilder) Select(columns ...string) *QueryBuilder {
qb.columns = columns
return qb
}
// Where adds a WHERE condition
func (qb *QueryBuilder) Where(condition string, args ...interface{}) *QueryBuilder {
qb.where = append(qb.where, condition)
qb.whereArgs = append(qb.whereArgs, args...)
return qb
}
// Join adds a JOIN clause.
func (qb *QueryBuilder) Join(clause string) *QueryBuilder {
qb.joins = append(qb.joins, clause)
return qb
}
// GroupBy sets GROUP BY columns.
func (qb *QueryBuilder) GroupBy(columns ...string) *QueryBuilder {
qb.groupBy = append(qb.groupBy, columns...)
return qb
}
// Having adds a HAVING condition.
func (qb *QueryBuilder) Having(condition string, args ...interface{}) *QueryBuilder {
qb.having = append(qb.having, condition)
qb.havingArgs = append(qb.havingArgs, args...)
return qb
}
2026-03-07 19:27:44 +08:00
// OrderBy sets the ORDER BY clause
func (qb *QueryBuilder) OrderBy(orderBy string) *QueryBuilder {
qb.orderBy = orderBy
return qb
}
// Limit sets the LIMIT
func (qb *QueryBuilder) Limit(limit int) *QueryBuilder {
qb.limit = limit
return qb
}
// Offset sets the OFFSET
func (qb *QueryBuilder) Offset(offset int) *QueryBuilder {
qb.offset = offset
return qb
}
// Build builds the SQL query and returns query string and args
func (qb *QueryBuilder) Build() (string, []interface{}) {
var parts []string
// SELECT
parts = append(parts, fmt.Sprintf("SELECT %s FROM %s",
strings.Join(qb.columns, ", "), qb.table))
// JOIN
if len(qb.joins) > 0 {
parts = append(parts, strings.Join(qb.joins, " "))
}
2026-03-07 19:27:44 +08:00
// WHERE
if len(qb.where) > 0 {
parts = append(parts, "WHERE "+strings.Join(qb.where, " AND "))
}
// GROUP BY
if len(qb.groupBy) > 0 {
parts = append(parts, "GROUP BY "+strings.Join(qb.groupBy, ", "))
}
// HAVING
if len(qb.having) > 0 {
parts = append(parts, "HAVING "+strings.Join(qb.having, " AND "))
}
2026-03-07 19:27:44 +08:00
// ORDER BY
if qb.orderBy != "" {
parts = append(parts, "ORDER BY "+qb.orderBy)
}
// LIMIT
if qb.limit > 0 {
parts = append(parts, fmt.Sprintf("LIMIT %d", qb.limit))
}
// OFFSET
if qb.offset > 0 {
parts = append(parts, fmt.Sprintf("OFFSET %d", qb.offset))
}
args := make([]interface{}, 0, len(qb.whereArgs)+len(qb.havingArgs))
args = append(args, qb.whereArgs...)
args = append(args, qb.havingArgs...)
return strings.Join(parts, " "), args
2026-03-07 19:27:44 +08:00
}
// Query executes the query
func (qb *QueryBuilder) Query(db *StarDB) (*StarRows, error) {
query, args := qb.Build()
return db.Query(query, args...)
}