1// Copyright 2013-2020 Aerospike, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package aerospike
16
17import xornd "github.com/aerospike/aerospike-client-go/types/rand"
18
19// Statement encapsulates query statement parameters.
20type Statement struct {
21	// Namespace determines query Namespace
22	Namespace string
23
24	// SetName determines query Set name (Optional)
25	SetName string
26
27	// IndexName determines query index name (Optional)
28	// If not set, the server will determine the index from the filter's bin name.
29	IndexName string
30
31	// BinNames detemines bin names (optional)
32	BinNames []string
33
34	// Filter determines query index filter (Optional).
35	// This filter is applied to the secondary index on query.
36	// Query index filters must reference a bin which has a secondary index defined.
37	Filter *Filter
38
39	packageName  string
40	functionName string
41	functionArgs []Value
42
43	// Ordered list of predicate expressions
44	predExps []PredExp
45
46	// TaskId determines query task id. (Optional)
47	TaskId uint64
48
49	// determines if the query should return data
50	returnData bool
51}
52
53// NewStatement initializes a new Statement instance.
54func NewStatement(ns string, set string, binNames ...string) *Statement {
55	return &Statement{
56		Namespace:  ns,
57		SetName:    set,
58		BinNames:   binNames,
59		returnData: true,
60		TaskId:     uint64(xornd.Int64()),
61	}
62}
63
64// SetFilter Sets a filter for the statement.
65// Aerospike Server currently only supports using a single filter per statement/query.
66func (stmt *Statement) SetFilter(filter *Filter) error {
67	stmt.Filter = filter
68
69	return nil
70}
71
72// SetPredExp sets low-level predicate expressions for the statement in postfix notation.
73// Supported only by Aerospike Server v3.12+.
74// Predicate expression filters are applied on the query results on the server.
75// Predicate expression filters may occur on any bin in the record.
76// To learn how to use this API, consult predexp_test.go file.
77//
78// Postfix notation is described here: http://wiki.c2.com/?PostfixNotation
79//
80// Example: (c >= 11 and c <= 20) or (d > 3 and (d < 5)
81//
82// stmt.SetPredExp(
83//   NewPredExpIntegerValue(11),
84//   NewPredExpIntegerBin("c"),
85//   NewPredExpIntegerGreaterEq(),
86//   NewPredExpIntegerValue(20),
87//   NewPredExpIntegerBin("c"),
88//   NewPredExpIntegerLessEq(),
89//   NewPredExpAnd(2),
90//   NewPredExpIntegerValue(3),
91//   NewPredExpIntegerBin("d"),
92//   NewPredExpIntegerGreater(),
93//   NewPredExpIntegerValue(5),
94//   NewPredExpIntegerBin("d"),
95//   NewPredExpIntegerLess(),
96//   NewPredExpAnd(2),
97//   NewPredExpOr(2)
98// );
99//
100// // Record last update time > 2017-01-15
101// stmt.SetPredExp(
102//   NewIntegerValue(time.Date(2017, 0, 15, 0, 0, 0, 0, time.UTC).UnixNano()),
103//   NewPredExpLastUpdate(),
104//   NewPredExpIntegerGreater(),
105// );
106func (stmt *Statement) SetPredExp(predexp ...PredExp) error {
107	stmt.predExps = predexp
108	return nil
109}
110
111// SetAggregateFunction sets aggregation function parameters.
112// This function will be called on both the server
113// and client for each selected item.
114func (stmt *Statement) SetAggregateFunction(packageName string, functionName string, functionArgs []Value, returnData bool) {
115	stmt.packageName = packageName
116	stmt.functionName = functionName
117	stmt.functionArgs = functionArgs
118	stmt.returnData = returnData
119}
120
121// IsScan determines is the Statement is a full namespace/set scan or a selective Query.
122func (stmt *Statement) IsScan() bool {
123	return stmt.Filter == nil
124}
125
126// Always set the taskID client-side to a non-zero random value
127func (stmt *Statement) setTaskID() {
128	for stmt.TaskId == 0 {
129		stmt.TaskId = uint64(xornd.Int64())
130	}
131}
132
133// Always set the taskID client-side to a non-zero random value
134func (stmt *Statement) prepare(returnData bool) {
135	stmt.returnData = returnData
136	stmt.setTaskID()
137}
138