1
0

query.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package arango
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. // Query provides a simple way to build ArangoDB queries.
  7. type Query struct {
  8. Lines []string
  9. Params map[string]any
  10. }
  11. // Append adds a line to the query, attaching (optional) values to bind parameters.
  12. //
  13. // Any variables given are assigned to bind parameters in the same order as they appear in the line.
  14. // Keep in mind the following behaviours:
  15. //
  16. // - If more variables are provided than there are parameters in the line, leftover variables are discarded
  17. // - If more parameters are used than variables are given, remaining parameters are left unmapped
  18. // - Reused parameters are overwritten
  19. func (query *Query) Append(line string, values ...any) *Query {
  20. var params map[string]any = nil
  21. names := ReadParams(line)
  22. if len(names) > 0 {
  23. params = map[string]any{}
  24. for i, name := range names {
  25. if i == len(values) {
  26. break
  27. }
  28. params[name] = values[i]
  29. }
  30. }
  31. query.Lines = append(query.Lines, line)
  32. return query.BindMap(params)
  33. }
  34. // Appendf adds a line to the query, replacing values directly into the string using standard formatting syntax.
  35. // This is a shorthand for:
  36. //
  37. // // query *Query
  38. // query.Append(fmt.Sprintf("my format (%s)", "example"))
  39. //
  40. // This method does not attach values to bind parameters.
  41. func (query *Query) Appendf(line string, a ...any) *Query {
  42. line = fmt.Sprintf(line, a...)
  43. return query.Append(line)
  44. }
  45. // Bind binds a value to a bind parameter.
  46. func (query *Query) Bind(name string, value any) *Query {
  47. query.Params[name] = value
  48. return query
  49. }
  50. // BindMap assigns values to bind parameters.
  51. func (query *Query) BindMap(params map[string]any) *Query {
  52. for name, value := range params {
  53. query.Params[name] = value
  54. }
  55. return query
  56. }
  57. // Copy creates a copy of the query.
  58. func (query *Query) Copy() *Query {
  59. newQuery := NewQuery()
  60. newQuery.Lines = append(newQuery.Lines, query.Lines...)
  61. for name, value := range query.Params {
  62. newQuery.Params[name] = value
  63. }
  64. return newQuery
  65. }
  66. // String returns the query formatted across multiple lines.
  67. func (query *Query) String() string {
  68. return strings.Join(query.Lines, "\n")
  69. }
  70. // StringLine returns the query formatted on a single line.
  71. // This reduces readability but may be more suitable for logging.
  72. func (query *Query) StringLine() string {
  73. return strings.Join(query.Lines, " ")
  74. }
  75. // NewQuery creates a new, empty Query.
  76. func NewQuery() *Query {
  77. return &Query{
  78. Lines: []string{},
  79. Params: map[string]any{},
  80. }
  81. }