session.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Copyright (c) 2012 The gocql Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package gocql
  5. import (
  6. "errors"
  7. )
  8. // Session is the interface used by users to interact with the database.
  9. //
  10. // It extends the Node interface by adding a convinient query builder and
  11. // automatically sets a default consinstency level on all operations
  12. // that do not have a consistency level set.
  13. type Session struct {
  14. Node Node
  15. Cons Consistency
  16. }
  17. // NewSession wraps an existing Node.
  18. func NewSession(node Node) *Session {
  19. if s, ok := node.(*Session); ok {
  20. return &Session{Node: s.Node}
  21. }
  22. return &Session{Node: node, Cons: Quorum}
  23. }
  24. // Query can be used to build new queries that should be executed on this
  25. // session.
  26. func (s *Session) Query(stmt string, args ...interface{}) QueryBuilder {
  27. return QueryBuilder{NewQuery(stmt, args...), s}
  28. }
  29. // Do can be used to modify a copy of an existing query before it is
  30. // executed on this session.
  31. func (s *Session) Do(qry *Query) QueryBuilder {
  32. q := *qry
  33. return QueryBuilder{&q, s}
  34. }
  35. // Close closes all connections. The session is unuseable after this
  36. // operation.
  37. func (s *Session) Close() {
  38. s.Node.Close()
  39. }
  40. // ExecuteBatch executes a Batch on the underlying Node.
  41. func (s *Session) ExecuteBatch(batch *Batch) error {
  42. if batch.Cons == 0 {
  43. batch.Cons = s.Cons
  44. }
  45. return s.Node.ExecuteBatch(batch)
  46. }
  47. // ExecuteQuery executes a Query on the underlying Node.
  48. func (s *Session) ExecuteQuery(qry *Query) (*Iter, error) {
  49. if qry.Cons == 0 {
  50. qry.Cons = s.Cons
  51. }
  52. return s.Node.ExecuteQuery(qry)
  53. }
  54. type Query struct {
  55. Stmt string
  56. Args []interface{}
  57. Cons Consistency
  58. Token string
  59. PageSize int
  60. Trace bool
  61. }
  62. func NewQuery(stmt string, args ...interface{}) *Query {
  63. return &Query{Stmt: stmt, Args: args}
  64. }
  65. type QueryBuilder struct {
  66. qry *Query
  67. ctx Node
  68. }
  69. // Args specifies the query parameters.
  70. func (b QueryBuilder) Args(args ...interface{}) {
  71. b.qry.Args = args
  72. }
  73. // Consistency sets the consistency level for this query. If no consistency
  74. // level have been set, the default consistency level of the cluster
  75. // is used.
  76. func (b QueryBuilder) Consistency(cons Consistency) QueryBuilder {
  77. b.qry.Cons = cons
  78. return b
  79. }
  80. func (b QueryBuilder) Token(token string) QueryBuilder {
  81. b.qry.Token = token
  82. return b
  83. }
  84. func (b QueryBuilder) Trace(trace bool) QueryBuilder {
  85. b.qry.Trace = trace
  86. return b
  87. }
  88. func (b QueryBuilder) PageSize(size int) QueryBuilder {
  89. b.qry.PageSize = size
  90. return b
  91. }
  92. func (b QueryBuilder) Exec() error {
  93. _, err := b.ctx.ExecuteQuery(b.qry)
  94. return err
  95. }
  96. func (b QueryBuilder) Iter() *Iter {
  97. iter, err := b.ctx.ExecuteQuery(b.qry)
  98. if err != nil {
  99. return &Iter{err: err}
  100. }
  101. return iter
  102. }
  103. func (b QueryBuilder) Scan(values ...interface{}) error {
  104. iter := b.Iter()
  105. iter.Scan(values...)
  106. return iter.Close()
  107. }
  108. type Iter struct {
  109. err error
  110. pos int
  111. rows [][][]byte
  112. columns []ColumnInfo
  113. }
  114. func (iter *Iter) Columns() []ColumnInfo {
  115. return iter.columns
  116. }
  117. func (iter *Iter) Scan(values ...interface{}) bool {
  118. if iter.err != nil || iter.pos >= len(iter.rows) {
  119. return false
  120. }
  121. if len(values) != len(iter.columns) {
  122. iter.err = errors.New("count mismatch")
  123. return false
  124. }
  125. for i := 0; i < len(iter.columns); i++ {
  126. err := Unmarshal(iter.columns[i].TypeInfo, iter.rows[iter.pos][i], values[i])
  127. if err != nil {
  128. iter.err = err
  129. return false
  130. }
  131. }
  132. iter.pos++
  133. return true
  134. }
  135. func (iter *Iter) Close() error {
  136. return iter.err
  137. }
  138. type Batch struct {
  139. Type BatchType
  140. Entries []BatchEntry
  141. Cons Consistency
  142. }
  143. func NewBatch(typ BatchType) *Batch {
  144. return &Batch{Type: typ}
  145. }
  146. func (b *Batch) Query(stmt string, args ...interface{}) {
  147. b.Entries = append(b.Entries, BatchEntry{Stmt: stmt, Args: args})
  148. }
  149. type BatchType int
  150. const (
  151. LoggedBatch BatchType = 0
  152. UnloggedBatch BatchType = 1
  153. CounterBatch BatchType = 2
  154. )
  155. type BatchEntry struct {
  156. Stmt string
  157. Args []interface{}
  158. }
  159. type Consistency int
  160. const (
  161. Any Consistency = 1 + iota
  162. One
  163. Two
  164. Three
  165. Quorum
  166. All
  167. LocalQuorum
  168. EachQuorum
  169. Serial
  170. LocalSerial
  171. )
  172. var consinstencyNames = []string{
  173. 0: "default",
  174. Any: "any",
  175. One: "one",
  176. Two: "two",
  177. Three: "three",
  178. Quorum: "quorum",
  179. All: "all",
  180. LocalQuorum: "localquorum",
  181. EachQuorum: "eachquorum",
  182. Serial: "serial",
  183. LocalSerial: "localserial",
  184. }
  185. func (c Consistency) String() string {
  186. return consinstencyNames[c]
  187. }
  188. type ColumnInfo struct {
  189. Keyspace string
  190. Table string
  191. Name string
  192. TypeInfo *TypeInfo
  193. }
  194. type Error struct {
  195. Code int
  196. Message string
  197. }
  198. func (e Error) Error() string {
  199. return e.Message
  200. }
  201. var (
  202. ErrNotFound = errors.New("not found")
  203. ErrUnavailable = errors.New("unavailable")
  204. ErrProtocol = errors.New("protocol error")
  205. )