rails-salesforce-connect 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 24d46e2a699ac425544c94272cce0fec1de9ac76427befc47693749f5d833b88
4
+ data.tar.gz: 49dd59365919bc269e7b1d06f5e2d59b92609df361e711a73a60b4a1640b2929
5
+ SHA512:
6
+ metadata.gz: '085671312fc11e7d2a18f1578542afcf469dbcd3a028f795346a53134770cfd19534471920a3ca353de46770fb1fc5e5701f180b3a6c317409d4986bce279c9e'
7
+ data.tar.gz: 9efd38e2d532d0e1988d50249e177fa8c54b158ea03c20a032d04df95129dc286c0b584e0c2f0c02ce520e70942165503ac97841098a3916b25d04b33620ec18
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.5.1
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rails-salesforce-connect (0.1.0)
5
+ activerecord
6
+ pg
7
+ rake
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (5.2.0)
13
+ activesupport (= 5.2.0)
14
+ activerecord (5.2.0)
15
+ activemodel (= 5.2.0)
16
+ activesupport (= 5.2.0)
17
+ arel (>= 9.0)
18
+ activesupport (5.2.0)
19
+ concurrent-ruby (~> 1.0, >= 1.0.2)
20
+ i18n (>= 0.7, < 2)
21
+ minitest (~> 5.1)
22
+ tzinfo (~> 1.1)
23
+ arel (9.0.0)
24
+ concurrent-ruby (1.0.5)
25
+ i18n (1.0.1)
26
+ concurrent-ruby (~> 1.0)
27
+ minitest (5.11.3)
28
+ pg (1.0.0)
29
+ rake (12.3.1)
30
+ thread_safe (0.3.6)
31
+ tzinfo (1.2.5)
32
+ thread_safe (~> 0.1)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ rails-salesforce-connect!
39
+
40
+ BUNDLED WITH
41
+ 1.16.1
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ load './lib/tasks/diff_schema.rake'
data/Readme.md ADDED
@@ -0,0 +1,21 @@
1
+ # Rails Salesforce Connect
2
+
3
+ This gem eases heroku-connect based integrations with salesforce for rails projects.
4
+
5
+ It provides:
6
+
7
+ * A rails generator for commonly used salesforce models
8
+ * A concern, `Connect::Record`, to include in salesforce-connected activerecord models
9
+ * A concern, `Connect::Migration`, for migrations which should only run in development (eg because heroku connect is managing the schema in production).
10
+ * A rake task `db:diff_schema` for describing the difference between your mapped fields in heroku and your local database.
11
+
12
+ ## Usage
13
+
14
+ Add to your gemfile:
15
+
16
+ `gem "rails-salesforce-connect"`
17
+
18
+
19
+ ## Status
20
+
21
+ Alpha. This has been extracted from common code across couple of projects.
@@ -0,0 +1,14 @@
1
+ require 'active_support/concern'
2
+
3
+ module Connect
4
+ module Migration
5
+ extend ActiveSupport::Concern
6
+
7
+ # Skip running in production environments, since
8
+ # heroku connect manages those
9
+ def exec_migration(conn, direction)
10
+ super unless Rails.env.production?
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ class Connect::Railtie < Rails::Railtie
2
+ rake_tasks do
3
+ load 'tasks/diff_schema.rake'
4
+ end
5
+ end
@@ -0,0 +1,63 @@
1
+ require 'active_support/concern'
2
+
3
+ module Connect
4
+ module Record
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ self.inheritance_column = 'rails_type'
9
+ self.primary_key = :sfid
10
+
11
+ alias_attribute :created_at, :createddate
12
+ alias_attribute :updated_at, :systemmodstamp
13
+ end
14
+
15
+ class_methods do
16
+ # Automatically update timestamps on save
17
+ def timestamp_attributes_for_create
18
+ super << "createddate"
19
+ end
20
+
21
+ def timestamp_attributes_for_update
22
+ super << "systemmodstamp"
23
+ end
24
+ end
25
+
26
+ def synced?
27
+ _hc_err.blank? && sfid.present?
28
+ end
29
+
30
+ def sync_failed?
31
+ _hc_err.present?
32
+ end
33
+
34
+ # Waits until salesforce allocates an SFID and syncs it back to heroku connect.
35
+ # Persistent failures can occur E.G. if there are duplication rules on the
36
+ # salesforce side.
37
+ def await_sync(timeout: 25, poll: 5, allocate_sfid_locally: !Rails.env.production?)
38
+ return true if synced?
39
+
40
+ if allocate_sfid_locally
41
+ update sfid: SecureRandom.base58(18)
42
+ else
43
+ begin
44
+ Timeout::timeout(timeout) do
45
+ loop do
46
+ sleep poll
47
+
48
+ if reload.synced?
49
+ break
50
+ end
51
+
52
+ return false if sync_failed? # Bail immediately if sync fails
53
+ end
54
+ end
55
+ rescue Timeout::Error
56
+ return false
57
+ end
58
+ end
59
+ true
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,66 @@
1
+ module Connect
2
+ class ModelsGenerator < Rails::Generators::Base
3
+
4
+ desc "Generates commonly used models for heroku connect"
5
+
6
+ class_option :module, type: :string, default: 'Salesforce'
7
+
8
+ def create_account
9
+ create_file "#{directory}/account.rb", <<-FILE
10
+ module #{modname}
11
+ class Account < ApplicationRecord
12
+ require 'connect/record'
13
+ include Connect::Record
14
+ self.table_name = "salesforce.account"
15
+
16
+ has_many :salesforce_contacts, class_name: "#{modname}::Contact",
17
+ foreign_key: :accountid, primary_key: :sfid, dependent: :nullify
18
+
19
+ has_one :salesforce_contract, class_name: "#{modname}::Contract",
20
+ foreign_key: :accountid, primary_key: :sfid, dependent: :nullify
21
+ end
22
+ end
23
+ FILE
24
+ end
25
+
26
+ def create_contact
27
+ create_file "#{directory}/contact.rb", <<-FILE
28
+ module #{modname}
29
+ class Contact < ApplicationRecord
30
+ require 'connect/record'
31
+ include Connect::Record
32
+ self.table_name = "salesforce.contact"
33
+
34
+ validates :email, presence: true, uniqueness: true
35
+
36
+ belongs_to :salesforce_account, class_name: "Salesforce::Account",
37
+ primary_key: :sfid, foreign_key: :accountid, optional: true
38
+ end
39
+ end
40
+ FILE
41
+ end
42
+
43
+ def create_contract
44
+ create_file "#{directory}/contract.rb", <<-FILE
45
+ module #{modname}
46
+ class Contract < ApplicationRecord
47
+ require 'connect/record'
48
+ include Connect::Record
49
+ self.table_name = "salesforce.contract"
50
+
51
+ belongs_to :salesforce_account, class_name: "Salesforce::Account",
52
+ primary_key: :sfid, foreign_key: :accountid
53
+ end
54
+ end
55
+ FILE
56
+ end
57
+
58
+ def modname
59
+ options['module']
60
+ end
61
+
62
+ def directory
63
+ "app/models/#{modname.underscore}"
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,5 @@
1
+
2
+ module Connect
3
+ end
4
+
5
+ require "connect/railtie" if defined?(Rails)
@@ -0,0 +1,72 @@
1
+ namespace :db do
2
+ desc "Identify differences from your schema"
3
+ task :diff_schema, [:remote_connection_string] => [:environment] do |task, args|
4
+ require 'pg'
5
+
6
+ sql = <<-SQL
7
+ select
8
+ table_name,
9
+ column_name,
10
+ is_nullable,
11
+ data_type,
12
+ character_maximum_length,
13
+ numeric_precision
14
+ from
15
+ information_schema.columns
16
+ where
17
+ table_schema = 'salesforce' and
18
+ table_name != '_trigger_log_archive' and
19
+ table_name != '_trigger_log' and
20
+ table_name != '_sf_event_log' and
21
+ table_name != '_hcmeta'
22
+ order by
23
+ table_name,
24
+ ordinal_position
25
+ ;
26
+ SQL
27
+
28
+ remote_conn = args[:remote_connection_string] || ENV["HC_URL"] || fail(<<-MSG)
29
+ Must specify remote_connection_string or provide ENV[HC_URL].
30
+ Try
31
+ export HC_URL="$(heroku config:get DATABASE_URL)"
32
+
33
+ MSG
34
+ remote = PG::Connection.new(args[:remote_connection_string] || ENV["HC_URL"]).async_exec(sql).each.to_a
35
+ local = ApplicationRecord.connection.raw_connection.async_exec(sql).each.to_a
36
+
37
+ local.each do |column|
38
+ # Remove if it exists
39
+ if remote.delete(column)
40
+ # Same column exists in both.
41
+ local.delete(column)
42
+ next
43
+ end
44
+ end
45
+
46
+ if local.any?
47
+ puts "***************************************************"
48
+ puts "** Extra columns locally not in remote **"
49
+ puts "***************************************************"
50
+ local.each do |c|
51
+ nul = (c["is_nullable"] == "YES")
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}"
55
+ end
56
+
57
+ end
58
+
59
+ if remote.any?
60
+ puts "***************************************************"
61
+ puts "** Extra columns on remote not available locally **"
62
+ puts "***************************************************"
63
+ remote.each do |c|
64
+ nul = (c["is_nullable"] == "YES")
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}"
68
+ end
69
+ end
70
+ abort "Differences found" if local.any? or remote.any?
71
+ end
72
+ end
@@ -0,0 +1,16 @@
1
+ # gem 'activerecord'
2
+ Gem::Specification.new do |s|
3
+ s.name = 'rails-salesforce-connect'
4
+ s.version = '0.0.1'
5
+ s.licenses = ['MIT']
6
+ s.summary = "Tools for using heroku connect with rails"
7
+ s.description = "Base class for salesforce migrations, activerecord types; deduplication rules aware, and rake tasks to sync schema"
8
+ s.authors = ["Daniel Heath"]
9
+ s.email = 'daniel@heath.cc'
10
+ s.files = `git ls-files`.lines.map( &:strip)
11
+ s.homepage = 'https://github.com/reinteractive/rails-salesforce-connect'
12
+ s.metadata = { "source_code_uri" => "https://github.com/reinteractive/rails-salesforce-connect" }
13
+ s.add_runtime_dependency "activerecord", '~> 0'
14
+ s.add_runtime_dependency "rake", '~> 0'
15
+ s.add_runtime_dependency "pg", '~> 0'
16
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails-salesforce-connect
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Heath
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-05-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pg
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Base class for salesforce migrations, activerecord types; deduplication
56
+ rules aware, and rake tasks to sync schema
57
+ email: daniel@heath.cc
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".ruby-version"
63
+ - Gemfile
64
+ - Gemfile.lock
65
+ - Rakefile
66
+ - Readme.md
67
+ - lib/connect/migration.rb
68
+ - lib/connect/railtie.rb
69
+ - lib/connect/record.rb
70
+ - lib/generators/connect/models_generator.rb
71
+ - lib/rails-salesforce-connect.rb
72
+ - lib/tasks/diff_schema.rake
73
+ - rails-salesforce-connect.gemspec
74
+ homepage: https://github.com/reinteractive/rails-salesforce-connect
75
+ licenses:
76
+ - MIT
77
+ metadata:
78
+ source_code_uri: https://github.com/reinteractive/rails-salesforce-connect
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.7.6
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Tools for using heroku connect with rails
99
+ test_files: []