rails-salesforce-connect 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []