This repository has been archived by the owner on Jan 21, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 129
/
Implicits.scala
235 lines (201 loc) · 11.8 KB
/
Implicits.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/**
* Copyright (c) 2010 10gen, Inc. <http://10gen.com>
* Copyright (c) 2009, 2010 Novus Partners, Inc. <http://novus.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For questions and comments about this product, please see the project page at:
*
* http://github.com/mongodb/casbah
*
*/
package com.mongodb.casbah
package query
import com.mongodb.casbah.query.dsl.QueryExpressionObject
trait Implicits {
/**
* Implicit extension methods for String values (e.g. a field name)
* to add Mongo's query operators, minimizing the need to write long series'
* of nested maps.
*
* Mixes in the QueryOperators defined in the QueryOperators mixin.
* The NestedQuery implicit [Defined below] allows you to call chained operators on the return value of this
* method. Chained operators will place the subsequent operators within the same DBObject,
* e.g. <code>"fooDate" $lte yesterday $gte tomorrow</code> maps to a Mongo query of:
* <code>{"fooDate": {"$lte": <yesterday>, "$gte": <tomorrow>}}</code>
*
* @param left A string which should be the field name, the left hand of the query
* @return Tuple2[String, DBObject] A tuple containing the field name and the mapped operator value, suitable for instantiating a Map
*/
implicit def mongoQueryStatements(left: String) = new {
val field = left
} with dsl.FluidQueryOperators
/**
* Implicit extension methods for Tuple2[String, DBObject] values
* to add Mongo's query operators, minimizing the need to write long series'
* of nested maps.
*
* Mixes in the QueryOperators defined in the QueryOperators mixin.
* The NestedQuery implicits allows you to call chained operators on the return value of the
* base String method method. Chained operators will place the subsequent operators within the same DBObject,
* e.g. <code>"fooDate" $lte yesterday $gte tomorrow</code> maps to a Mongo query of:
* <code>{"fooDate": {"$lte": <yesterday>, "$gte": <tomorrow>}}</code>
*
* @param left A string which should be the field name, the left hand of the query
* @return Tuple2[String, DBObject] A tuple containing the field name and the mapped operator value, suitable for instantiating a Map
*/
implicit def mongoNestedDBObjectQueryStatements(nested: DBObject with QueryExpressionObject) = {
new {
val field = nested.field
} with dsl.ValueTestFluidQueryOperators {
dbObj = nested.getAs[DBObject](nested.field) // TODO - shore the safety of this up
}
}
implicit def tupleToGeoCoords[A: ValidNumericType: Manifest, B: ValidNumericType: Manifest](coords: (A, B)) = dsl.GeoCoords(coords._1, coords._2)
}
/*@deprecated("The Imports._ semantic has been deprecated. Please import 'com.mongodb.casbah.query._' instead.")
object Imports extends query.Imports with commons.Imports*/
trait Imports extends dsl.FluidQueryBarewordOps with query.BaseImports with query.TypeImports with query.Implicits
with commons.Imports with commons.Exports with ValidBarewordExpressionArgTypeHolder with ValidDateTypeHolder
with ValidNumericTypeHolder with ValidDateOrNumericTypeHolder
object `package` extends Imports // query.dsl.FluidQueryBarewordOps with commons.Exports with query.BaseImports with query.TypeImports with query.Implicits with commons.Imports with ValidDateOrNumericTypeHolder
trait BaseImports {
val GeoCoords = com.mongodb.casbah.query.dsl.GeoCoords
}
trait TypeImports {
type GeoCoords = com.mongodb.casbah.query.dsl.GeoCoords[_, _]
}
trait Exports {
type ValidNumericType[T] = query.ValidNumericType[T]
type ValidDateType[T] = query.ValidDateType[T]
type ValidDateOrNumericType[T] = query.ValidDateOrNumericType[T]
}
object ValidTypes {
trait JDKDateOk extends ValidDateType[java.util.Date]
trait JodaDateTimeOk extends ValidDateType[org.joda.time.DateTime]
trait KVPair[A] extends ValidBarewordExpressionArgType[(String, A)] {
def toDBObject(arg: (String, A)): DBObject = MongoDBObject(arg)
}
// Valid Bareword Query Expression entries
trait CoreOperatorResultObj extends ValidBarewordExpressionArgType[DBObject with QueryExpressionObject] {
def toDBObject(arg: DBObject with QueryExpressionObject): DBObject = arg
}
trait ConcreteDBObject extends ValidBarewordExpressionArgType[DBObject] {
def toDBObject(arg: DBObject): DBObject = arg
}
// ValidNumericTypes
trait BigIntOk extends ValidNumericType[BigInt] with Numeric.BigIntIsIntegral with Ordering.BigIntOrdering
trait IntOk extends ValidNumericType[Int] with Numeric.IntIsIntegral with Ordering.IntOrdering
trait ShortOk extends ValidNumericType[Short] with Numeric.ShortIsIntegral with Ordering.ShortOrdering
trait ByteOk extends ValidNumericType[Byte] with Numeric.ByteIsIntegral with Ordering.ByteOrdering
trait LongOk extends ValidNumericType[Long] with Numeric.LongIsIntegral with Ordering.LongOrdering
trait FloatOk extends ValidNumericType[Float] with Numeric.FloatIsFractional with Ordering.FloatOrdering
trait BigDecimalOk extends ValidNumericType[BigDecimal] with Numeric.BigDecimalIsFractional with Ordering.BigDecimalOrdering
trait DoubleOk extends ValidNumericType[Double] with Numeric.DoubleIsFractional with Ordering.DoubleOrdering
}
trait ValidBarewordExpressionArgType[T] {
def toDBObject(arg: T): DBObject
}
trait ValidBarewordExpressionArgTypeHolder {
import com.mongodb.casbah.query.ValidTypes.{ConcreteDBObject, CoreOperatorResultObj, KVPair}
implicit def kvPairOk[A]: KVPair[A] = new KVPair[A] {}
implicit object ConcreteDBObjectOk extends ConcreteDBObject
implicit object CoreOperatorResultObjOk extends CoreOperatorResultObj
}
trait AsIterable[A]{
def asIterable(a:A):Iterable[_]
}
object AsIterable {
def apply[A](implicit asIterable:AsIterable[A]) = asIterable
implicit def iterable[A <: Iterable[_]]:AsIterable[A] = new AsIterable[A]{
def asIterable(a: A) = a
}
implicit def product[A <: Product]:AsIterable[A] = new AsIterable[A]{
def asIterable(a: A) = a.productIterator.toIterable
}
}
@annotation.implicitNotFound("${A} is not a valid query parameter")
trait AsQueryParam[A]{
def asQueryParam(a:A):Any
}
object AsQueryParam {
def apply[A](implicit a:AsQueryParam[A]) = a
private def as[A](f:A => Any):AsQueryParam[A] = new AsQueryParam[A]{
def asQueryParam(a: A) = f(a)
}
implicit val string = as[String](identity)
implicit def dbObject[A <: DBObject] = as[A](identity)
implicit val dbRef = as[DBRef](identity)
implicit val objectId = as[ObjectId](identity)
implicit val boolean = as[Boolean](identity)
implicit def array[A] = as[Array[A]](_.toList)
implicit def iterable[A <: Iterable[_]] = as[A](_.toList)
implicit def dateOrNumeric[A : ValidDateOrNumericType] = as[A](identity)
implicit def tuple1[A1] = as[Tuple1[A1]](_.productIterator.toList)
implicit def tuple2[A1,A2] = as[(A1,A2)](_.productIterator.toList)
implicit def tuple3[A1,A2,A3] = as[(A1,A2,A3)](_.productIterator.toList)
implicit def tuple4[A1,A2,A3,A4] = as[(A1,A2,A3,A4)](_.productIterator.toList)
implicit def tuple5[A1,A2,A3,A4,A5] = as[(A1,A2,A3,A4,A5)](_.productIterator.toList)
implicit def tuple6[A1,A2,A3,A4,A5,A6] = as[(A1,A2,A3,A4,A5,A6)](_.productIterator.toList)
implicit def tuple7[A1,A2,A3,A4,A5,A6,A7] = as[(A1,A2,A3,A4,A5,A6,A7)](_.productIterator.toList)
implicit def tuple8[A1,A2,A3,A4,A5,A6,A7,A8] = as[(A1,A2,A3,A4,A5,A6,A7,A8)](_.productIterator.toList)
implicit def tuple9[A1,A2,A3,A4,A5,A6,A7,A8,A9] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9)](_.productIterator.toList)
implicit def tuple10[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)](_.productIterator.toList)
implicit def tuple11[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)](_.productIterator.toList)
implicit def tuple12[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)](_.productIterator.toList)
implicit def tuple13[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)](_.productIterator.toList)
implicit def tuple14[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)](_.productIterator.toList)
implicit def tuple15[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)](_.productIterator.toList)
implicit def tuple16[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16)](_.productIterator.toList)
implicit def tuple17[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17)](_.productIterator.toList)
implicit def tuple18[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18)](_.productIterator.toList)
implicit def tuple19[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19)](_.productIterator.toList)
implicit def tuple20[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20)](_.productIterator.toList)
implicit def tuple21[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,A21] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,A21)](_.productIterator.toList)
implicit def tuple22[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,A21,A22] = as[(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,A21,A22)](_.productIterator.toList)
}
trait ValidNumericType[T]
trait ValidDateType[T]
trait ValidDateOrNumericType[T]
trait ValidDateTypeHolder {
import com.mongodb.casbah.query.ValidTypes.{JDKDateOk, JodaDateTimeOk}
implicit object JDKDateOk extends JDKDateOk
implicit object JodaDateTimeOk extends JodaDateTimeOk
}
trait ValidNumericTypeHolder {
import com.mongodb.casbah.query.ValidTypes.{BigIntOk, IntOk, ShortOk, ByteOk, LongOk,
FloatOk, BigDecimalOk, DoubleOk}
implicit object BigIntOk extends BigIntOk
implicit object IntOk extends IntOk
implicit object ShortOk extends ShortOk
implicit object ByteOk extends ByteOk
implicit object LongOk extends LongOk
implicit object FloatOk extends FloatOk
implicit object BigDecimalOk extends BigDecimalOk
implicit object DoubleOk extends DoubleOk
}
trait ValidDateOrNumericTypeHolder {
import com.mongodb.casbah.query.ValidTypes.{JDKDateOk, BigIntOk, IntOk, ShortOk, ByteOk,
LongOk, FloatOk, BigDecimalOk, DoubleOk}
implicit object JDKDateDoNOk extends ValidDateOrNumericType[java.util.Date]
implicit object JodaDateTimeDoNOk extends ValidDateOrNumericType[org.joda.time.DateTime]
implicit object BigIntDoNOk extends ValidDateOrNumericType[BigInt]
implicit object IntDoNOk extends ValidDateOrNumericType[Int]
implicit object ShortDoNOk extends ValidDateOrNumericType[Short]
implicit object ByteDoNOk extends ValidDateOrNumericType[Byte]
implicit object LongDoNOk extends ValidDateOrNumericType[Long]
implicit object FloatDoNOk extends ValidDateOrNumericType[Float]
implicit object BigDecimalDoNOk extends ValidDateOrNumericType[BigDecimal]
implicit object DoubleDoNOk extends ValidDateOrNumericType[Double]
}
// vim: set ts=2 sw=2 sts=2 et: