Skip to content
Browse files

Refactor of the schema macros as well as unification of the 'put' fun…

…ction.
  • Loading branch information...
1 parent ecd1e32 commit e2171d575f9d8c89e9545186698d9c81297cd4a6 @nickmbailey nickmbailey committed Dec 21, 2011
Showing with 77 additions and 80 deletions.
  1. +3 −2 README.md
  2. +61 −66 src/clj_hector/core.clj
  3. +2 −1 src/clj_hector/serialize.clj
  4. +8 −8 test/clj_hector/test/core.clj
  5. +3 −3 test/clj_hector/test/schema.clj
View
5 README.md
@@ -106,11 +106,12 @@ Hector exposes data about how long queries took to execute (and on which host).
## Experimental Schema Querying
-`clj-hector` provides a `defschema` macro to provide default serializers for the specified column family (see `./test/clj_hector/test/schema.clj` for examples).
+`clj-hector` allows you to provide default schema settings for the specified column families (see `./test/clj_hector/test/schema.clj` for examples).
For example, when operating with the MyColumnFamily column family, you can provide default name and value serializers as follows:
- (defschema MyColumnFamily [:n-serializer :string
+ (defschema MyColumnFamily [:name "MyColumnFamily"
+ :n-serializer :string
:v-serializer :string])
Then, when querying, wrap the functions with the `with-schema` macro:
View
127 src/clj_hector/core.clj
@@ -47,62 +47,73 @@
([cluster name consistency-map]
(HFactory/createKeyspace name cluster (c/policy consistency-map))))
+(defn- schema-options
+ [opts column-family]
+ (let [defaults {:type :standard
+ :counter false
+ :ttl nil
+ :s-serializer :bytes
+ :n-serializer :bytes
+ :v-serializer :bytes}]
+ (merge defaults (apply hash-map opts) (get *schemas* column-family))))
+
+(defn- query-options
+ [opts]
+ (let [defaults {:start nil
+ :end nil
+ :reversed false
+ :limit Integer/MAX_VALUE}]
+ (merge defaults (apply hash-map opts))))
+
+(defn- extract-options
+ [opts cf]
+ (merge (query-options opts) (schema-options opts cf)))
+
+(def serializer-keys [:n-serializer :v-serializer :s-serializer])
+(defn convert-serializers [opts]
+ (merge opts (reduce (fn [m [k v]] (into m {k (s/serializer v)})) {} (select-keys opts serializer-keys))))
+
+(defn- super? [opts]
+ (= (opts :type :standard) :super))
+(defn- counter? [opts]
+ (get opts :counter false))
+
(defn- create-column
"Creates Column and SuperColumns.
Serializers for the super column name, column name, and column value default to an instance of TypeInferringSerializer.
Examples: (create-column \"name\" \"a value\") (create-column \"super column name\" {\"name\" \"value\"})"
- [name value ttl counter? & {:keys [n-serializer v-serializer s-serializer]
- :or {n-serializer type-inferring
- v-serializer type-inferring
- s-serializer type-inferring}}]
- (if (map? value)
- (let [cols (map (fn [[n v]] (create-column n v ttl counter? :n-serializer n-serializer :v-serializer v-serializer)) value)]
- (if counter?
- (HFactory/createCounterSuperColumn name cols s-serializer n-serializer)
- (HFactory/createSuperColumn name cols s-serializer n-serializer v-serializer)))
- (if counter?
- (HFactory/createCounterColumn name value n-serializer)
- (if ttl
- (HFactory/createColumn name value (int ttl) n-serializer v-serializer)
- (HFactory/createColumn name value n-serializer v-serializer)))))
-
-(defn- schema-options
- [column-family]
- (get *schemas* column-family))
-
-(defn- extract-options
- [opts cf]
- (let [defaults {:s-serializer :bytes
- :n-serializer :bytes
- :v-serializer :bytes
- :start nil
- :end nil
- :reversed false
- :limit Integer/MAX_VALUE}]
- (merge defaults (apply hash-map opts) (schema-options cf))))
+ [name value options]
+ (let [opts (convert-serializers options)
+ n-serializer (opts :n-serializer)
+ s-serializer (opts :s-serializer)
+ v-serializer (opts :v-serializer)
+ ttl (opts :ttl)]
+ (if (super? opts)
+ (let [cols (map (fn [[n v]] (create-column n v (dissoc options :type))) value)]
+ (if (counter? opts)
+ (HFactory/createCounterSuperColumn name cols s-serializer n-serializer)
+ (HFactory/createSuperColumn name cols s-serializer n-serializer v-serializer)))
+ (if (counter? opts)
+ (HFactory/createCounterColumn name value n-serializer)
+ (if ttl
+ (HFactory/createColumn name value (int ttl) n-serializer v-serializer)
+ (HFactory/createColumn name value n-serializer v-serializer))))))
(defn put
"Stores values in columns in map m against row key pk"
- ([ks cf pk m] (put ks cf pk m nil))
- ([ks cf pk m ttl]
- (let [^Mutator mut (HFactory/createMutator ks type-inferring)]
- (doseq [[k v] m] (.addInsertion mut pk cf (create-column k v ttl false)))
- (.execute mut))))
-
-(defn put-counter
- "Stores a counter value. Column Family must have the name validator
- type set to :counter (CounterColumnType).
-
- pk is the row key. m is a map of column names and the (long) counter
- value to store.
-
- Counter columns allow atomic increment/decrement."
- [ks cf pk m]
- (let [^Mutator mut (HFactory/createMutator ks type-inferring)]
- (doseq [[n v] m]
- (.addCounter mut pk cf (create-column n v nil true)))
+ [ks cf pk m & opts]
+ (let [^Mutator mut (HFactory/createMutator ks type-inferring)
+ defaults (merge {:n-serializer :type-inferring
+ :v-serializer :type-inferring
+ :s-serializer :type-inferring}
+ (apply hash-map opts))
+ opts (extract-options (apply concat (seq defaults)) cf)]
+ ;opts (dissoc (extract-options opts cf) :n-serializer :v-serializer :s-serializer)]
+ (if (counter? opts)
+ (doseq [[n v] m] (.addCounter mut pk cf (create-column n v opts)))
+ (doseq [[k v] m] (.addInsertion mut pk cf (create-column k v opts))))
(.execute mut)))
(defn- execute-query [^Query query]
@@ -246,11 +257,7 @@
(doseq [[sc-name v] nv]
(.addSubDelete mut k cf (create-column sc-name
(apply hash-map (interleave v v))
- nil
- false
- :s-serializer (s/serializer (:s-serializer opts))
- :n-serializer (s/serializer (:n-serializer opts))
- :v-serializer (s/serializer (:v-serializer opts))))))
+ opts))))
(.execute mut)))
(defn delete-rows
@@ -275,23 +282,11 @@
(.setRange start end limit)
(.setColumnFamily cf))))
-
-(defmacro defschema
- "Defines a schema for the named column family. The provided
- serializers will be used when operations are performed with
- the with-schemas macro.
-
- Example (defschema ColumnFamily [:n-serializer :string :v-serializer :string])"
- [cf-name ks]
- (let [name-str (name cf-name)]
- `(def ~cf-name {:name ~name-str
- :serializers (apply hash-map ~ks)})))
-
(defn schemas-by-name
[schemas]
(->> schemas
- (map (fn [{:keys [name serializers]}]
- [name serializers]))
+ (map (fn [{:keys [name] :as opts}]
+ [name opts]))
(into {})))
(defmacro with-schemas
View
3 src/clj_hector/serialize.clj
@@ -89,7 +89,8 @@
:char (CharSerializer/get)
:double (DoubleSerializer/get)
:float (FloatSerializer/get)
- :short (ShortSerializer/get)})
+ :short (ShortSerializer/get)
+ :type-inferring (TypeInferringSerializer/get)})
(defn serializer
"Returns an instance of the specified serializer.
View
16 test/clj_hector/test/core.clj
@@ -76,10 +76,10 @@
(deftest super-columns
(let [column-family "A"
- opts [:s-serializer :string :n-serializer :string :v-serializer :string]]
+ opts [:s-serializer :string :n-serializer :string :v-serializer :string :type :super]]
(with-test-keyspace keyspace [{:name column-family :type :super}]
(put keyspace column-family "row-key" {"SuperCol" {"n" "v" "n2" "v2"}
- "SuperCol2" {"n" "v" "n2" "v2"}})
+ "SuperCol2" {"n" "v" "n2" "v2"}} :type :super)
(testing "querying"
(is (= {"row-key" [{"SuperCol" {"n" "v"
"n2" "v2"}}
@@ -90,7 +90,7 @@
(apply get-super-columns keyspace column-family "row-key" "SuperCol" ["n" "n2"] opts))))
(testing "deletion"
(put keyspace column-family "row-key" {"SuperCol" {"n" "v" "n2" "v2"}
- "SuperCol2" {"n" "v"}})
+ "SuperCol2" {"n" "v"}} :type :super)
(apply delete-super-columns keyspace column-family {"row-key" {"SuperCol" ["n2"]}} opts)
(is (= {"n" "v"}
(apply get-super-columns keyspace column-family "row-key" "SuperCol" ["n" "n2"] opts)))))))
@@ -102,7 +102,7 @@
pk "row-key"]
(with-test-keyspace keyspace [{:name column-family
:validator :counter}]
- (put-counter keyspace column-family pk {"n" 1 "n2" 2})
+ (put keyspace column-family pk {"n" 1 "n2" 2} :counter true)
(is (= {"n" 1
"n2" 2}
(apply get-counter-columns keyspace column-family pk ["n" "n2"] opts))))))
@@ -113,7 +113,7 @@
(with-test-keyspace keyspace [{:name column-family
:validator :counter
:type :super}]
- (put-counter keyspace column-family pk {"SuperCol" {"n" 1 "n2" 2}})
+ (put keyspace column-family pk {"SuperCol" {"n" 1 "n2" 2}} :type :super :counter true)
(is (= {"SuperCol" {"n" 1 "n2" 2}}
(apply get-counter-super-columns keyspace column-family pk "SuperCol" ["n" "n2"] opts))))))
(testing "counter column range query"
@@ -122,7 +122,7 @@
pk "row-key"]
(with-test-keyspace keyspace [{:name column-family
:validator :counter}]
- (put-counter keyspace column-family "row-key" {"a" 1 "b" 2 "c" 1 "d" 3})
+ (put keyspace column-family "row-key" {"a" 1 "b" 2 "c" 1 "d" 3} :counter true)
(is (= {"a" 1 "b" 2 "c" 1}
(apply get-counter-column-range keyspace column-family pk "a" "c" opts)))))))
@@ -132,7 +132,7 @@
opts [:n-serializer :string :v-serializer :integer]
pk "row-key1"]
(with-test-keyspace keyspace [{:name column-family}]
- (put keyspace column-family pk {"n" 1 "n2" 2} 1)
+ (put keyspace column-family pk {"n" 1 "n2" 2} :ttl 1)
(is (= {"n" 1 "n2" 2}
(apply get-columns keyspace column-family pk ["n" "n2"] opts)))
(Thread/sleep 2000)
@@ -144,7 +144,7 @@
pk "row-key"]
(with-test-keyspace keyspace [{:name column-family
:type :super}]
- (put keyspace column-family pk {"SuperCol" {"n" 1 "n2" 2}} 1)
+ (put keyspace column-family pk {"SuperCol" {"n" 1 "n2" 2}} :ttl 1 :type :super)
(is (= {"n" 1 "n2" 2}
(apply get-super-columns keyspace column-family pk "SuperCol" ["n" "n2"] opts)))
(Thread/sleep 2000)
View
6 test/clj_hector/test/schema.clj
@@ -5,9 +5,9 @@
[clj-hector.core] :reload))
(def column-family "MyColumnFamily")
-
-(defschema MyColumnFamily [:n-serializer :string
- :v-serializer :string])
+(def MyColumnFamily {:name column-family
+ :n-serializer :string
+ :v-serializer :string})
(deftest string-key-values
(with-test-keyspace ks [{:name column-family}]

0 comments on commit e2171d5

Please sign in to comment.
Something went wrong with that request. Please try again.