Skip to content
This repository
Browse code

New postgres addon to replace heroku-shared-postgresql

  • Loading branch information...
commit dca0096ef1a9632c58f9464b0ce38d41c29cca46 1 parent ccc86bc
authored March 26, 2012
84  lib/heroku-postgres-addon/client.rb
... ...
@@ -0,0 +1,84 @@
  1
+require "heroku/helpers"
  2
+require "digest/sha2"
  3
+
  4
+ module HerokuPostgresAddon
  5
+   class Client
  6
+
  7
+     include Heroku::Helpers
  8
+
  9
+     def initialize(url)
  10
+       @heroku_postgres_addon_host = ENV["HEROKU_POSTGRES_ADDON_HOST"] || "https://postgres-addon.herokuapp.com"
  11
+       @database_sha = sha(url)
  12
+       @heroku_postgres_resource = RestClient::Resource.new(
  13
+         "#{@heroku_postgres_addon_host}/client/v1",
  14
+         :headers => {
  15
+           :x_heroku_gem_version => Heroku::Client.version,
  16
+           :x_heroku_shared_postgresql_token => @database_sha,
  17
+           :accept => 'application/json'
  18
+         }
  19
+       )
  20
+    end
  21
+
  22
+    def reset_database
  23
+      http_post("/reset-database")
  24
+    end
  25
+
  26
+    def reset_password
  27
+      http_post("/reset-password")
  28
+    end
  29
+
  30
+    def show_info
  31
+      http_get("/info")
  32
+    end
  33
+
  34
+    protected
  35
+
  36
+    def sha(url)
  37
+      Digest::SHA2.hexdigest(url)
  38
+    end
  39
+
  40
+    def checking_client_version
  41
+      begin
  42
+        yield
  43
+      rescue RestClient::BadRequest => e
  44
+        if message = json_decode(e.response.to_s)["upgrade_message"]
  45
+          abort(message)
  46
+        else
  47
+          raise e
  48
+        end
  49
+      end
  50
+    end
  51
+
  52
+    def display_heroku_warning(response)
  53
+      warning = response.headers[:x_heroku_warning]
  54
+      display warning if warning
  55
+      response
  56
+    end
  57
+
  58
+    def http_get(path)
  59
+      checking_client_version do
  60
+        retry_on_exception(RestClient::Exception) do
  61
+          response = @heroku_postgres_resource[path].get
  62
+          display_heroku_warning response
  63
+          json_decode(response.to_s)
  64
+        end
  65
+      end
  66
+    end
  67
+
  68
+    def http_post(path, payload = {})
  69
+      checking_client_version do
  70
+        response = @heroku_postgres_resource[path].post(json_encode(payload))
  71
+        display_heroku_warning response
  72
+        json_decode(response.to_s)
  73
+      end
  74
+    end
  75
+
  76
+    def http_put(path, payload = {})
  77
+      checking_client_version do
  78
+        response = @heroku_postgres_resource[path].put(json_encode(payload))
  79
+        display_heroku_warning response
  80
+        json_decode(response.to_s)
  81
+      end
  82
+    end
  83
+  end
  84
+end
42  lib/heroku/command/pg.rb
@@ -2,6 +2,7 @@
2 2
 require "heroku/pgutils"
3 3
 require "heroku/pg_resolver"
4 4
 require "heroku-postgresql/client"
  5
+require "heroku-postgres-addon/client"
5 6
 require "heroku-shared-postgresql/client"
6 7
 
7 8
 module Heroku::Command
@@ -68,6 +69,9 @@ def reset
68 69
 
69 70
       working_display 'Resetting' do
70 71
         case db[:name]
  72
+        when /\A#{Resolver.postgres_addon_prefix}\w+/
  73
+          display " database, related tables and functions...", false
  74
+          response = heroku_postgres_addon_client(db[:url]).reset_database
71 75
         when /\A#{Resolver.shared_addon_prefix}\w+/
72 76
           display " database, related tables and functions...", false
73 77
           response = heroku_shared_postgresql_client(db[:url]).reset_database
@@ -90,6 +94,9 @@ def unfollow
90 94
       when 'SHARED_DATABASE'
91 95
         output_with_bang "#{follower_db[:name]} does not support forking and following."
92 96
         return
  97
+      when /\A#{Resolver.postgres_addon_prefix}\w+/
  98
+        output_with_bang "#{follower_db[:name]} does not support forking and following."
  99
+        return
93 100
       when /\A#{Resolver.shared_addon_prefix}\w+/
94 101
         output_with_bang "#{follower_db[:name]} does not support forking and following."
95 102
         return
@@ -126,6 +133,8 @@ def wait
126 133
         case db[:name]
127 134
         when 'SHARED_DATABASE'
128 135
           next
  136
+        when /\A#{Resolver.postgres_addon_prefix}\w+/
  137
+          next
129 138
         when /\A#{Resolver.shared_addon_prefix}\w+/
130 139
           next
131 140
         else
@@ -148,6 +157,13 @@ def credentials
148 157
         case db[:name]
149 158
         when "SHARED_DATABASE"
150 159
           output_with_bang "Resetting password not currently supported for #{db[:pretty_name]}"
  160
+        when /\A#{Resolver.postgres_addon_prefix}\w+/
  161
+          working_display 'Resetting' do
  162
+            return unless confirm_command
  163
+            output_with_arrow("Resetting password for #{db[:pretty_name]}")
  164
+            response = heroku_postgres_addon_client(db[:url]).reset_password
  165
+            heroku.add_config_vars(app, {"DATABASE_URL" => response["url"]}) if db[:default]
  166
+          end
151 167
         when /\A#{Resolver.shared_addon_prefix}\w+/
152 168
           working_display 'Resetting' do
153 169
             return unless confirm_command
@@ -185,6 +201,10 @@ def heroku_shared_postgresql_client(url)
185 201
       HerokuSharedPostgresql::Client.new(url)
186 202
     end
187 203
 
  204
+    def heroku_postgres_addon_client(url)
  205
+      HerokuPostgresAddon::Client.new(url)
  206
+    end
  207
+
188 208
     def wait_for(db)
189 209
       ticking do |ticks|
190 210
         wait_status = heroku_postgresql_client(db[:url]).get_wait_status
@@ -203,6 +223,8 @@ def display_db_info(db)
203 223
       case db[:name]
204 224
       when "SHARED_DATABASE"
205 225
         display_info_shared
  226
+      when /\A#{Resolver.postgres_addon_prefix}\w+/
  227
+        display_info_postgres_addon(db)
206 228
       when /\A#{Resolver.shared_addon_prefix}\w+/
207 229
         display_info_shared_postgresql(db)
208 230
       else
@@ -215,6 +237,23 @@ def display_info_shared
215 237
       display_info("Data Size", "#{format_bytes(attrs[:database_size].to_i)}")
216 238
     end
217 239
 
  240
+    def display_info_postgres_addon(db)
  241
+      db_info = heroku_postgres_addon_client(db[:url]).show_info
  242
+
  243
+      db_info["info"].each do |i|
  244
+        if i['value']
  245
+          val = i['resolve_db_name'] ? name_from_url(i['value']) : i['value']
  246
+          display_info i['name'], val
  247
+        elsif i['values']
  248
+          i['values'].each_with_index do |val,idx|
  249
+            name = idx.zero? ? i['name'] : nil
  250
+            val = i['resolve_db_name'] ? name_from_url(val) : val
  251
+            display_info name, val
  252
+          end
  253
+        end
  254
+      end
  255
+    end
  256
+
218 257
     def display_info_shared_postgresql(db)
219 258
       response = heroku_shared_postgresql_client(db[:url]).show_info
220 259
       response.each do |key, value|
@@ -244,6 +283,9 @@ def generate_ingress_uri(action=nil)
244 283
       case db[:name]
245 284
       when "SHARED_DATABASE"
246 285
         error "Cannot ingress to a shared database" if "SHARED_DATABASE" == db[:name]
  286
+      when /\A#{Resolver.postgres_addon_prefix}\w+/
  287
+        working_display("#{action} to #{db[:name]}") if action
  288
+        return URI.parse(db[:url])
247 289
       when /\A#{Resolver.shared_addon_prefix}\w+/
248 290
         working_display("#{action} to #{db[:name]}") if action
249 291
         return URI.parse(db[:url])
6  lib/heroku/pg_resolver.rb
@@ -120,6 +120,10 @@ def self.addon_prefix
120 120
       ENV["HEROKU_POSTGRESQL_ADDON_PREFIX"] || "HEROKU_POSTGRESQL"
121 121
     end
122 122
 
  123
+    def self.postgres_addon_prefix
  124
+      ENV["HEROKU_POSTGRES_ADDON_PREFIX"] || "POSTGRES"
  125
+    end
  126
+
123 127
     def self.shared_addon_prefix
124 128
       ENV["HEROKU_SHARED_POSTGRESQL_ADDON_PREFIX"] || "HEROKU_SHARED_POSTGRESQL"
125 129
     end
@@ -132,6 +136,8 @@ def self.parse_config(config_vars)
132 136
           dbs['DATABASE'] = val
133 137
         when 'SHARED_DATABASE_URL'
134 138
           dbs['SHARED_DATABASE'] = val
  139
+        when /\A(#{postgres_addon_prefix}\w+)_URL\Z/
  140
+          dbs[$1] = val
135 141
         when /\A(#{shared_addon_prefix}\w+)_URL\Z/
136 142
           dbs[$1] = val
137 143
         when /^(#{addon_prefix}\w+)_URL$/

0 notes on commit dca0096

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