package arango import ( "fmt" "strings" ) // Query provides a simple way to build ArangoDB queries. type Query struct { Lines []string Params map[string]any } // Append adds a line to the query, attaching (optional) values to bind parameters. // // Any variables given are assigned to bind parameters in the same order as they appear in the line. // Keep in mind the following behaviours: // // - If more variables are provided than there are parameters in the line, leftover variables are discarded // - If more parameters are used than variables are given, remaining parameters are left unmapped // - Reused parameters are overwritten func (query *Query) Append(line string, values ...any) *Query { var params map[string]any = nil names := ReadParams(line) if len(names) > 0 { params = map[string]any{} for i, name := range names { if i == len(values) { break } params[name] = values[i] } } query.Lines = append(query.Lines, line) return query.BindMap(params) } // Appendf adds a line to the query, replacing values directly into the string using standard formatting syntax. // This is a shorthand for: // // // query *Query // query.Append(fmt.Sprintf("my format (%s)", "example")) // // This method does not attach values to bind parameters. func (query *Query) Appendf(line string, a ...any) *Query { line = fmt.Sprintf(line, a...) return query.Append(line) } // Bind binds a value to a bind parameter. func (query *Query) Bind(name string, value any) *Query { query.Params[name] = value return query } // BindMap assigns values to bind parameters. func (query *Query) BindMap(params map[string]any) *Query { for name, value := range params { query.Params[name] = value } return query } // Copy creates a copy of the query. func (query *Query) Copy() *Query { newQuery := NewQuery() newQuery.Lines = append(newQuery.Lines, query.Lines...) for name, value := range query.Params { newQuery.Params[name] = value } return newQuery } // String returns the query formatted across multiple lines. func (query *Query) String() string { return strings.Join(query.Lines, "\n") } // StringLine returns the query formatted on a single line. // This reduces readability but may be more suitable for logging. func (query *Query) StringLine() string { return strings.Join(query.Lines, " ") } // NewQuery creates a new, empty Query. func NewQuery() *Query { return &Query{ Lines: []string{}, Params: map[string]any{}, } }