rails-salesforce-connect 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Readme.md +25 -0
- data/lib/connect/api_adapter.rb +24 -0
- data/lib/connect/migration.rb +1 -0
- data/lib/connect/railtie.rb +1 -0
- data/lib/connect/record.rb +21 -1
- data/lib/generators/connect/models_generator.rb +1 -0
- data/lib/rails-salesforce-connect.rb +1 -0
- data/lib/tasks/diff_salesforce.rake +62 -0
- data/lib/tasks/diff_schema.rake +25 -23
- data/rails-salesforce-connect.gemspec +4 -1
- metadata +46 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ad61d450dcdb23872b876fc2686f3fa0f81bcff71193b6114071336325ba82a
|
4
|
+
data.tar.gz: e2e316121c58fc32652f7c5a3d9dbea7356de4c3cb1caeac69f1814f0bcb0f66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccaab598ba67b116fb6db22fc21381a5cf38055a18061e68c3cc5135c3aa1fb4ac4edac43928b21eb20dd4a7e9c3b803e5bae338b16f4e5eaef63f427794cf75
|
7
|
+
data.tar.gz: edb3ef5bd8eae1c70199cb9332ae0a2a34df291e8ee873f61d6d4c20044368f6e1a336a00e0aebb4b7b962608c10a796f486cab7e177e7a30fa8d67600ee6bd7
|
data/Readme.md
CHANGED
@@ -5,16 +5,41 @@ This gem eases heroku-connect based integrations with salesforce for rails proje
|
|
5
5
|
It provides:
|
6
6
|
|
7
7
|
* A rails generator for commonly used salesforce models (`rails g connect:models`)
|
8
|
+
* An API client constructor for RestForce (`Connect::ApiAdapter`)
|
8
9
|
* A concern, `Connect::Record`, to include in salesforce-connected activerecord models (`require 'connect/record'`)
|
9
10
|
* A concern, `Connect::Migration`, for migrations which should only run in development (eg because heroku connect is managing the schema in production).
|
10
11
|
* A rake task `db:diff_schema` for describing the difference between your mapped fields in heroku and your local database.
|
12
|
+
* A rake task `salesforce:schema:dump[heroku-app-name]` to serialize your salesforce configuration to JSON
|
13
|
+
* A rake task `salesforce:schema:diff[old_file,new_file]` to compare two serialized salesforce configurations
|
11
14
|
|
12
15
|
## Usage
|
13
16
|
|
14
17
|
Add to your gemfile:
|
15
18
|
|
19
|
+
### Classes
|
20
|
+
|
21
|
+
To use `Connect::ApiAdapter`, you must provide the following environment variables:
|
22
|
+
|
23
|
+
* SALESFORCE_REST_API_HOST
|
24
|
+
* SALESFORCE_REST_API_CLIENT_ID
|
25
|
+
* SALESFORCE_REST_API_CLIENT_SECRET
|
26
|
+
* SALESFORCE_REST_API_USERNAME
|
27
|
+
* SALESFORCE_REST_API_PASSWORD
|
28
|
+
* SALESFORCE_REST_API_SECURITY_TOKEN
|
29
|
+
|
30
|
+
### Rake tasks
|
31
|
+
|
16
32
|
`gem "rails-salesforce-connect"`
|
17
33
|
|
34
|
+
To use `rake db:diff_schema` you must specify a connection string or HC_URL env var.
|
35
|
+
For instance:
|
36
|
+
|
37
|
+
`export HC_URL="$(heroku config:get DATABASE_URL)"`
|
38
|
+
|
39
|
+
To use `rake salesforce:schema:dump`, you must provide one of:
|
40
|
+
|
41
|
+
* Environment variables for `Connect::ApiAdapter`, or
|
42
|
+
* A heroku app name, which the current machine is authorized to read environment variabes from, with those variables set.
|
18
43
|
|
19
44
|
## Status
|
20
45
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Connect
|
4
|
+
class ApiAdapter
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def describe(env=ENV)
|
8
|
+
client(env).describe
|
9
|
+
end
|
10
|
+
|
11
|
+
def client(env=ENV)
|
12
|
+
@client ||= Restforce.new(
|
13
|
+
api_version: env.fetch('API_VERSION', "41.0"),
|
14
|
+
host: env["SALESFORCE_REST_API_HOST"],
|
15
|
+
client_id: env["SALESFORCE_REST_API_CLIENT_ID"],
|
16
|
+
client_secret: env["SALESFORCE_REST_API_CLIENT_SECRET"],
|
17
|
+
username: env["SALESFORCE_REST_API_USERNAME"],
|
18
|
+
password: env["SALESFORCE_REST_API_PASSWORD"],
|
19
|
+
security_token: env["SALESFORCE_REST_API_SECURITY_TOKEN"],
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/connect/migration.rb
CHANGED
data/lib/connect/railtie.rb
CHANGED
data/lib/connect/record.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'active_support/concern'
|
2
3
|
|
3
4
|
module Connect
|
@@ -6,10 +7,12 @@ module Connect
|
|
6
7
|
|
7
8
|
included do
|
8
9
|
self.inheritance_column = 'rails_type'
|
9
|
-
self.primary_key = :sfid
|
10
10
|
|
11
11
|
alias_attribute :created_at, :createddate
|
12
12
|
alias_attribute :updated_at, :systemmodstamp
|
13
|
+
|
14
|
+
class_attribute :syncs_to_salesforce
|
15
|
+
validates :sfid, presence: true, unless: :syncs_to_salesforce?
|
13
16
|
end
|
14
17
|
|
15
18
|
class_methods do
|
@@ -21,6 +24,23 @@ module Connect
|
|
21
24
|
def timestamp_attributes_for_update
|
22
25
|
super << "systemmodstamp"
|
23
26
|
end
|
27
|
+
|
28
|
+
def syncs_to_salesforce!
|
29
|
+
self.syncs_to_salesforce = true
|
30
|
+
end
|
31
|
+
|
32
|
+
# Lets you insert to salesforce tables from tests on an opt-in basis
|
33
|
+
def seeding_development_data
|
34
|
+
old_value = self.syncs_to_salesforce
|
35
|
+
self.syncs_to_salesforce = true
|
36
|
+
yield
|
37
|
+
self.syncs_to_salesforce = old_value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def readonly?
|
42
|
+
return false unless self.class.syncs_to_salesforce?
|
43
|
+
super
|
24
44
|
end
|
25
45
|
|
26
46
|
def synced?
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
namespace :salesforce do
|
3
|
+
|
4
|
+
namespace :schema do
|
5
|
+
desc "Save the salesforce schema for the given app"
|
6
|
+
task :dump, [:app_name] => [:environment] do |_t, args|
|
7
|
+
env = ENV
|
8
|
+
outfile = 'salesforce-schema.json'
|
9
|
+
|
10
|
+
if args[:app_name].present?
|
11
|
+
env = Dotenv::Parser.call(`heroku config --app #{args[:app_name]} --shell`)
|
12
|
+
raise "Error fetching heroku config for #{args[:app_name]}" unless $?.success?
|
13
|
+
outfile = "salesforce-schema-#{args[:app_name]}.json"
|
14
|
+
end
|
15
|
+
|
16
|
+
description = Salesforce::ApiAdapter.describe(env).group_by {|e| e["name"] }
|
17
|
+
description.each do |k, v|
|
18
|
+
raise "Expected name to be unique" unless v.one?
|
19
|
+
description[k] = v.first
|
20
|
+
description[k].delete("name")
|
21
|
+
end
|
22
|
+
File.write(
|
23
|
+
outfile,
|
24
|
+
JSON.pretty_generate(description)
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Diff two schema files against one another"
|
29
|
+
task :diff, [:old, :new] => [:environment] do |_t, args|
|
30
|
+
old_h = JSON.parse(File.read(args[:old]))
|
31
|
+
new_h = JSON.parse(File.read(args[:new]))
|
32
|
+
|
33
|
+
removed = old_h.keys - new_h.keys
|
34
|
+
added = new_h.keys - old_h.keys
|
35
|
+
diff = false
|
36
|
+
removed.each do |r|
|
37
|
+
puts "Removed object: #{r}"
|
38
|
+
diff = true
|
39
|
+
end
|
40
|
+
added.each do |a|
|
41
|
+
puts "Added object: #{a}"
|
42
|
+
diff = true
|
43
|
+
end
|
44
|
+
|
45
|
+
HashDiff.diff(old_h.except(*removed), new_h.except(*added)).each do |sym, key, old, new_val|
|
46
|
+
diff = true
|
47
|
+
case sym
|
48
|
+
when "~"
|
49
|
+
puts "Changed #{key} from #{old} to #{new_val}"
|
50
|
+
when "-"
|
51
|
+
puts "Removed #{key}"
|
52
|
+
when "+"
|
53
|
+
puts "Added #{key} = #{old}"
|
54
|
+
else
|
55
|
+
raise "Unknown HashDiff symbol '#{sym}', expected one of '~', '+' or '-'."
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
exit(1) if diff
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/tasks/diff_schema.rake
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
namespace :db do
|
2
3
|
desc "Identify differences from your schema"
|
3
|
-
task :
|
4
|
+
task :dif_schema, [:remote_connection_string] => [:environment] do |task, args|
|
4
5
|
require 'pg'
|
5
6
|
|
6
7
|
sql = <<-SQL
|
@@ -25,48 +26,49 @@ namespace :db do
|
|
25
26
|
;
|
26
27
|
SQL
|
27
28
|
|
28
|
-
remote_conn = args[:remote_connection_string] || ENV["HC_URL"] || fail(<<-MSG)
|
29
|
+
remote_conn = args[:remote_connection_string] || ENV["HC_URL"] || ENV["HEROKUCONNECT_URL"] || fail(<<-MSG)
|
29
30
|
Must specify remote_connection_string or provide ENV[HC_URL].
|
30
31
|
Try
|
31
32
|
export HC_URL="$(heroku config:get DATABASE_URL)"
|
32
33
|
|
33
34
|
MSG
|
34
|
-
remote = PG::Connection.new(
|
35
|
+
remote = PG::Connection.new(remote_conn).async_exec(sql).each.to_a
|
35
36
|
local = ApplicationRecord.connection.raw_connection.async_exec(sql).each.to_a
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
remote.each {|c| c["character_maximum_length"] = c["character_maximum_length"].to_i }
|
39
|
+
local.each {|c| c["character_maximum_length"] = c["character_maximum_length"].to_i }
|
40
|
+
|
41
|
+
def format_column(c)
|
42
|
+
nul = (c["is_nullable"] == "YES")
|
43
|
+
length = c["character_maximum_length"] ? ", limit: #{c["character_maximum_length"]}" : ""
|
44
|
+
precision = c["numeric_precision"] ? ", precision: #{c["numeric_precision"]}" : ""
|
45
|
+
type = c["data_type"].inspect
|
46
|
+
type = ':string' if c["data_type"] == "character varying"
|
47
|
+
"_column :#{c["table_name"]}, :#{c["column_name"]}, #{type}, null: #{nul.to_s} #{length} #{precision}"
|
44
48
|
end
|
45
49
|
|
46
|
-
|
50
|
+
local = local.map &method(:format_column)
|
51
|
+
remote = remote.map &method(:format_column)
|
52
|
+
|
53
|
+
if (local - remote).any?
|
47
54
|
puts "***************************************************"
|
48
55
|
puts "** Extra columns locally not in remote **"
|
49
56
|
puts "***************************************************"
|
50
|
-
local.each do |c|
|
51
|
-
|
52
|
-
length = c["character_maximum_length"] ? ", length: #{c["character_maximum_length"]}" : ""
|
53
|
-
precision = c["numeric_precision"] ? ", precision: #{c["numeric_precision"]}" : ""
|
54
|
-
puts "remove_column :#{c["table_name"]}, :#{c["column_name"]}, #{c["data_type"].inspect}, null: #{nul.to_s}#{length}#{precision}"
|
57
|
+
(local - remote).each do |c|
|
58
|
+
puts "remove" + c
|
55
59
|
end
|
56
60
|
|
57
61
|
end
|
58
62
|
|
59
|
-
if remote.any?
|
63
|
+
if (remote - local).any?
|
60
64
|
puts "***************************************************"
|
61
65
|
puts "** Extra columns on remote not available locally **"
|
62
66
|
puts "***************************************************"
|
63
|
-
remote.each do |c|
|
64
|
-
|
65
|
-
length = c["character_maximum_length"] ? ", length: #{c["character_maximum_length"]}" : ""
|
66
|
-
precision = c["numeric_precision"] ? ", precision: #{c["numeric_precision"]}" : ""
|
67
|
-
puts "add_column :#{c["table_name"]}, :#{c["column_name"]}, #{c["data_type"].inspect}, null: #{nul.to_s} #{length} #{precision}"
|
67
|
+
(remote - local).each do |c|
|
68
|
+
puts "add" + c
|
68
69
|
end
|
69
70
|
end
|
70
|
-
|
71
|
+
|
72
|
+
abort "Differences found" if (local - remote).any? or (remote - local).any?
|
71
73
|
end
|
72
74
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# gem 'activerecord'
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = 'rails-salesforce-connect'
|
4
|
-
s.version = '0.0.
|
4
|
+
s.version = '0.0.4'
|
5
5
|
s.licenses = ['MIT']
|
6
6
|
s.summary = "Tools for using heroku connect with rails"
|
7
7
|
s.description = "Base class for salesforce migrations, activerecord types; deduplication rules aware, and rake tasks to sync schema"
|
@@ -13,4 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.add_runtime_dependency "activerecord"
|
14
14
|
s.add_runtime_dependency "rake"
|
15
15
|
s.add_runtime_dependency "pg"
|
16
|
+
s.add_runtime_dependency "dotenv"
|
17
|
+
s.add_runtime_dependency "hashdiff"
|
18
|
+
s.add_runtime_dependency "restforce"
|
16
19
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-salesforce-connect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Heath
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05
|
11
|
+
date: 2018-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -52,6 +52,48 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: dotenv
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: hashdiff
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: restforce
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
55
97
|
description: Base class for salesforce migrations, activerecord types; deduplication
|
56
98
|
rules aware, and rake tasks to sync schema
|
57
99
|
email: daniel@heath.cc
|
@@ -64,11 +106,13 @@ files:
|
|
64
106
|
- Gemfile
|
65
107
|
- Rakefile
|
66
108
|
- Readme.md
|
109
|
+
- lib/connect/api_adapter.rb
|
67
110
|
- lib/connect/migration.rb
|
68
111
|
- lib/connect/railtie.rb
|
69
112
|
- lib/connect/record.rb
|
70
113
|
- lib/generators/connect/models_generator.rb
|
71
114
|
- lib/rails-salesforce-connect.rb
|
115
|
+
- lib/tasks/diff_salesforce.rake
|
72
116
|
- lib/tasks/diff_schema.rake
|
73
117
|
- rails-salesforce-connect.gemspec
|
74
118
|
homepage: https://github.com/reinteractive/rails-salesforce-connect
|