Skip to content

Commit

Permalink
Allow user to specify the database name
Browse files Browse the repository at this point in the history
MongoHQ will not allow two different users to have databases with the
same name. (This *might* not be the case for paid MongoHQ accounts, but
it is the case for the free "sandbox" databases.) Therefore, we cannot
hard-code the database name; instead, we need to prompt the user to
enter his/her unique database name.

  - Update UI to prompt user to enter the database name
  - Inside the :state atom, enhance the :database-configuration to
    include the database name
  - For all functions that formerly took the MongoHQ API key as an
    argument, update those functions to instead take the database
    configuration map as an argument. (This map includes both the API key
    and the database name.)
  - Move clj->js from one.repmax.mongohq to new one.repmax.util
    namespace
  - Introduce one.repmax.url-blueprint
  • Loading branch information
jasonrudolph committed Aug 3, 2012
1 parent 661d7ac commit 5090de2
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 156 deletions.
52 changes: 27 additions & 25 deletions src/app/cljs/one/repmax/datastore_configuration/observer.cljs
Expand Up @@ -8,44 +8,45 @@
(defmulti do-initialization-step
(fn [& args] (first args)))

(defmethod do-initialization-step :verify-credentials [_ api-key]
(mongo/find-databases api-key
(defmethod do-initialization-step :verify-credentials [_ config]
(mongo/find-databases config
#(do
(cookies/set-cookie :api-key api-key)
(dispatch/fire :action {:action :datastore-configuration/credentials-verified, :api-key api-key}))
#(initialization-error-callback api-key %)))

(defmethod do-initialization-step :verify-database [_ api-key]
(mongo/find-database api-key
#(dispatch/fire :action {:action :datastore-configuration/database-verified, :api-key api-key})
#(initialization-error-callback api-key %)))

(defmethod do-initialization-step :verify-collections [_ api-key]
(mongo/find-collections api-key
#(find-collections-success-callback api-key %)
#(initialization-error-callback api-key %)))

(defmethod do-initialization-step :ready [_ api-key]
(cookies/set-cookie :api-key (:api-key config))
(cookies/set-cookie :database (:database config))
(dispatch/fire :action {:action :datastore-configuration/credentials-verified, :configuration config}))
#(initialization-error-callback config %)))

(defmethod do-initialization-step :verify-database [_ config]
(mongo/find-database config
#(dispatch/fire :action {:action :datastore-configuration/database-verified, :configuration config})
#(initialization-error-callback config %)))

(defmethod do-initialization-step :verify-collections [_ config]
(mongo/find-collections config
#(find-collections-success-callback config %)
#(initialization-error-callback config %)))

(defmethod do-initialization-step :ready [_ _]
(dispatch/fire :action {:action :datastore-configuration/ready}))

;; No-op. No action necessary when we transition to the :initialization-failed state.
(defmethod do-initialization-step :default [_ _])

;; TODO Enhance function to recurse through the list of necessary collections
;; and create each one. Fire action :datastore-configuration/collections-verified.
(defn find-collections-success-callback [api-key collections]
(defn find-collections-success-callback [config collections]
(if (contains-collection? collections "exercises") ;; TODO Get collection name from elsewhere
(dispatch/fire :action {:action :datastore-configuration/collections-verified, :api-key api-key})
(mongo/create-collection api-key "exercises" ;; TODO Get collection name from elsewhere
#(dispatch/fire :action {:action :datastore-configuration/collections-verified, :api-key api-key})
#(dispatch/fire :action {:action :datastore-configuration/initialization-failed, :api-key api-key}))))
(dispatch/fire :action {:action :datastore-configuration/collections-verified, :configuration config})
(mongo/create-collection config "exercises" ;; TODO Get collection name from elsewhere
#(dispatch/fire :action {:action :datastore-configuration/collections-verified, :configuration config})
#(dispatch/fire :action {:action :datastore-configuration/initialization-failed, :configuration config}))))

(defn contains-collection? [collections collection-name]
(some #(= collection-name (% "name")) collections))

(defn initialization-error-callback [api-key response]
(defn initialization-error-callback [config response]
(dispatch/fire :action {:action :datastore-configuration/initialization-failed
:api-key api-key
:configuration config
:error response}))

;;; Register reactors
Expand All @@ -55,4 +56,5 @@
(let [old-config-state (-> event :old :datastore-configuration :state)
new-config-state (-> event :new :datastore-configuration :state)]
(if-not (= old-config-state new-config-state)
(do-initialization-step new-config-state (-> event :new :datastore-configuration :api-key))))))
(let [config (dissoc (-> event :new :datastore-configuration) :state)]
(do-initialization-step new-config-state config))))))
8 changes: 6 additions & 2 deletions src/app/cljs/one/repmax/datastore_configuration/view.cljs
Expand Up @@ -44,11 +44,13 @@
(d/swap-content! header (:datastore-configuration-header snippets))
(d/swap-content! content (:datastore-configuration-form snippets))
(d/set-value! (d/by-id "api-key-input") (:api-key datastore-configuration))
(d/set-value! (d/by-id "database-input") (:database datastore-configuration))
(event/listen (d/by-id "datastore-configuration-form-button")
event-type/CLICK
#(dispatch/fire :action
{:action :datastore-configuration/update
:api-key (d/value (d/by-id "api-key-input"))}))))
{:action :datastore-configuration/update
:api-key (d/value (d/by-id "api-key-input"))
:database (d/value (d/by-id "database-input"))}))))

(defmulti render-datastore-configuration-state
(fn [datastore-configuration] (:state datastore-configuration)))
Expand Down Expand Up @@ -100,10 +102,12 @@

(defn disable-datastore-configuration-form []
(disable "api-key-input")
(disable "database-input")
(disable "datastore-configuration-form-button"))

(defn enable-datastore-configuration-form []
(enable "api-key-input")
(enable "database-input")
(enable "datastore-configuration-form-button"))

;;; Register reactors
Expand Down
2 changes: 1 addition & 1 deletion src/app/cljs/one/repmax/exercises/observer.cljs
Expand Up @@ -10,7 +10,7 @@

; TODO Add on-error callback
(defmethod do-after :datastore-configuration/ready [{:keys [new]}]
(mongo/find-documents (-> new :datastore-configuration :api-key)
(mongo/find-documents (:datastore-configuration new)
"exercises"
(fn [data]
(dispatch/fire :action {:action :exercises/initialized-from-datastore, :exercises data}))
Expand Down
25 changes: 14 additions & 11 deletions src/app/cljs/one/repmax/model.cljs
Expand Up @@ -6,7 +6,7 @@
[one.repmax.mongohq :as mongo]))

(def initial-state {:state :start
:datastore-configuration {:state :obtain-credentials, :api-key ""}
:datastore-configuration {:state :obtain-credentials, :api-key "", :database ""}
:exercises nil
:exercise-search {:query nil, :exercise-ids nil}})

Expand Down Expand Up @@ -38,9 +38,11 @@
; The :datastore-configuration map contains the following elements:
;
; 1. :api-key => the user-provided API key for use in accessing MongoHQ
; 2. :state => the overall state of the datastore configuration (i.e.,
; 2. :database => the user-provided MongoHQ database name, indicating
; the database from which the app will read/write its data
; 3. :state => the overall state of the datastore configuration (i.e.,
; the state of the datastore initialization/verification process)
; 3. :error => a map containing a description of the error that occured
; 4. :error => a map containing a description of the error that occured
; during the initialization process (in the :text key) and the state
; in which the error occured (in the :occured-in-state key); this map
; is only present if an error has occured
Expand All @@ -62,16 +64,17 @@
(assoc :datastore-configuration (datastore-configuration-from-cookies))))

(defn datastore-configuration-from-cookies []
(let [api-key (cookies/get-cookie :api-key)]
(if (nil? api-key)
(:datastore-configuration initial-state)
(datastore-configuration-for-new-api-key api-key))))
(let [api-key (cookies/get-cookie :api-key)
database (cookies/get-cookie :database)]
(new-datastore-configuration api-key database)))

(defn datastore-configuration-for-new-api-key [api-key]
{:api-key api-key :state :verify-credentials})
(defn new-datastore-configuration [api-key database]
(if (or (nil? api-key) (nil? database))
(:datastore-configuration initial-state)
{:state :verify-credentials :api-key api-key :database database}))

(defmethod update-model :datastore-configuration/update [state {:keys [api-key]}]
(assoc state :datastore-configuration (datastore-configuration-for-new-api-key api-key)))
(defmethod update-model :datastore-configuration/update [state {:keys [api-key database]}]
(assoc state :datastore-configuration (new-datastore-configuration api-key database)))

(defmethod update-model :datastore-configuration/credentials-verified [state _]
(assoc-in state [:datastore-configuration :state] :verify-database))
Expand Down

0 comments on commit 5090de2

Please sign in to comment.