├── spec ├── spec_helper.rb └── scope_spec.rb ├── Gemfile ├── lib ├── databasedotcom │ └── isolated │ │ ├── version.rb │ │ ├── runner.rb │ │ └── scope.rb └── databasedotcom-isolated.rb ├── Rakefile ├── .travis.yml ├── .gitignore ├── LICENSE.txt ├── databasedotcom-isolated.gemspec └── README.md /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'databasedotcom-isolated' 2 | 3 | class SomeLocalClass 4 | end 5 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in databasedotcom-isolated.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /lib/databasedotcom/isolated/version.rb: -------------------------------------------------------------------------------- 1 | module Databasedotcom 2 | module Isolated 3 | VERSION = "0.1.0" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require 'rspec/core/rake_task' 3 | 4 | RSpec::Core::RakeTask.new(:spec) 5 | 6 | task :default => :spec 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 1.9.3 4 | - 1.8.7 5 | - jruby-18mode # JRuby in 1.8 mode 6 | - jruby-19mode # JRuby in 1.9 mode 7 | - rbx-18mode 8 | - rbx-19mode 9 | -------------------------------------------------------------------------------- /lib/databasedotcom/isolated/runner.rb: -------------------------------------------------------------------------------- 1 | module Databasedotcom 2 | module Isolated 3 | def self.perform(options,&block) 4 | Scope.new(options).perform(&block) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/databasedotcom-isolated.rb: -------------------------------------------------------------------------------- 1 | require "sourcify" 2 | require "databasedotcom" 3 | require "databasedotcom/isolated/version" 4 | require "databasedotcom/isolated/scope" 5 | require "databasedotcom/isolated/runner" 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Seba Gamboa 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /databasedotcom-isolated.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'databasedotcom/isolated/version' 5 | 6 | Gem::Specification.new do |gem| 7 | gem.name = "databasedotcom-isolated" 8 | gem.version = Databasedotcom::Isolated::VERSION 9 | gem.authors = ["Seba Gamboa"] 10 | gem.email = ["me@sagmor.com"] 11 | gem.description = %q{Isolate databasedotcom materialized clases to work with multiple orgs safely} 12 | gem.summary = %q{Isolate databasedotcom materialized clases to work with multiple orgs safely} 13 | gem.homepage = "https://github.com/sagmor/databasedotcom-isolated" 14 | 15 | gem.files = `git ls-files`.split($/) 16 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 17 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 18 | gem.require_paths = ["lib"] 19 | 20 | gem.add_dependency "databasedotcom" 21 | gem.add_dependency "sourcify" 22 | gem.add_development_dependency "rake" 23 | gem.add_development_dependency "rspec" 24 | end 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # databasedotcom-isolated 2 | 3 | [![Build Status](https://travis-ci.org/sagmor/databasedotcom-isolated.png)](https://travis-ci.org/sagmor/databasedotcom-isolated) 4 | [![Dependency Status](https://gemnasium.com/sagmor/databasedotcom-isolated.png)](https://gemnasium.com/sagmor/databasedotcom-isolated) 5 | 6 | 7 | This gem let's you perform actions using the databasedotcom gem without having 8 | to worry about constant pollution and modules namespacing. 9 | 10 | ## Installation 11 | 12 | Add this line to your application's Gemfile: 13 | 14 | gem 'databasedotcom-isolated' 15 | 16 | And then execute: 17 | 18 | $ bundle 19 | 20 | Or install it yourself as: 21 | 22 | $ gem install databasedotcom-isolated 23 | 24 | ## Usage 25 | 26 | ```ruby 27 | # define your connection options 28 | options = { 29 | # App credentials 30 | client_id: 'YOUR_CLIENT_ID', 31 | client_secret: 'YOUR_CLIENT_SECRET', 32 | 33 | # Oauth token authentication 34 | token: 'YOUR_AUTHENTICATION_TOKEN', 35 | 36 | # Or alternatively 37 | username: 'YOUR_USERNAME', 38 | password: 'YOUR_PASSWORD_AND_SECRET_TOKEN' 39 | } 40 | 41 | # Perform everything inside a block 42 | Databasedotcom::Isolated.perform(options) do 43 | contact = Contact.last 44 | 45 | puts contact.inspect 46 | end 47 | 48 | # And everything get's cleaned up behind you. 49 | defined? Contact # => nil 50 | ``` 51 | 52 | ## Contributing 53 | 54 | 1. Fork it 55 | 2. Create your feature branch (`git checkout -b my-new-feature`) 56 | 3. Commit your changes (`git commit -am 'Add some feature'`) 57 | 4. Push to the branch (`git push origin my-new-feature`) 58 | 5. Create new Pull Request 59 | -------------------------------------------------------------------------------- /lib/databasedotcom/isolated/scope.rb: -------------------------------------------------------------------------------- 1 | module Databasedotcom 2 | module Isolated 3 | # Shared functionatily of an isolated scope 4 | class Scope 5 | CLIENT_OPTIONS = [:client_id,:client_secret] 6 | AUTHENTICATION_OPTIONS = [:username, :password, :token] 7 | 8 | def Scope.new(options = {}) 9 | Class.new(self).tap do |scope| 10 | scope.options = options 11 | scope.client = options[:client] 12 | end 13 | end 14 | 15 | class << self 16 | attr_accessor :options, :client, :binding 17 | 18 | def client 19 | @client ||= Databasedotcom::Client.new(self.options.slice(*CLIENT_OPTIONS)).tap do |client| 20 | client.sobject_module = self 21 | self.options.slice(*AUTHENTICATION_OPTIONS).tap do |auth_options| 22 | client.authenticate(auth_options) unless auth_options.empty? 23 | end 24 | end 25 | end 26 | 27 | def perform(&block) 28 | # self.new.instance_eval(&block) 29 | self.binding = block.binding 30 | (self.class_eval(block.to_source)).call 31 | self.binding = nil 32 | 33 | # self.class_eval( &eval(block.to_source) ) 34 | 35 | self 36 | end 37 | 38 | # Force a class materialization 39 | def materialize(klass) 40 | self.const_set(klass, self.client.materialize(klass.to_s)) 41 | end 42 | 43 | #materalized any cased string into a Custom object 44 | def materialize_custom(obj) 45 | self.const_set('Custom', self.client.materialize(obj)) 46 | end 47 | 48 | def method_missing(sym,*args) 49 | if args.empty? 50 | eval(sym.to_s,binding) 51 | else 52 | context = eval("self",binding) 53 | context.send(sym,*args) 54 | end 55 | end 56 | 57 | # Search for missing constants on the current list of sobjects if available 58 | def const_missing(sym) 59 | if self.list_sobjects.include?(sym.to_s) 60 | self.client.materialize(sym.to_s) 61 | else 62 | super 63 | end 64 | end 65 | 66 | def list_sobjects 67 | @list_sobjects ||= self.client.list_sobjects 68 | end 69 | end 70 | end 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /spec/scope_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Databasedotcom::Isolated::Scope do 4 | before(:each) do 5 | @scope = Databasedotcom::Isolated::Scope.new({ 6 | :client => double('client', { 7 | :list_sobjects => %w{Contact Account} 8 | }) 9 | }) 10 | end 11 | 12 | it "Initializes as new anonimous subclass rather than an instance" do 13 | expect(@scope).to be_kind_of Class 14 | end 15 | 16 | it "can connect to diferent clients at hte same time" do 17 | another_scope = Databasedotcom::Isolated::Scope.new({ 18 | :client => double('client2') 19 | }) 20 | 21 | expect(@scope.client).not_to be_eql another_scope.client 22 | end 23 | 24 | context "#perform" do 25 | it "performs the code on the block" do 26 | @scope.perform do 27 | 'DO SOMETHING' 28 | end 29 | end 30 | 31 | it "search for constants on the database.com client" do 32 | @scope.client.should_receive(:list_sobjects) 33 | expect{ 34 | @scope.perform do 35 | UnknownContact 36 | end 37 | }.to raise_error NameError 38 | end 39 | 40 | it "materializes known database.com classes" do 41 | @scope.client.should_receive(:materialize).with('Contact').and_return(Class.new) 42 | 43 | @scope.perform do 44 | Contact.new 45 | end 46 | end 47 | 48 | it "doesn't pollutes known namespaces with constants" do 49 | @scope.client.should_receive(:materialize).with('Contact').and_return(Class.new) 50 | 51 | @scope.perform do 52 | Contact.new 53 | end 54 | 55 | expect(defined?( Contact )).to be_nil 56 | expect(defined?( ::Contact )).to be_nil 57 | expect(defined?( Databasedotcom::Isolated::Scope::Contact )).to be_nil 58 | expect(defined?( Databasedotcom::Isolated::Scope.new::Contact )).to be_nil 59 | end 60 | 61 | it "materialized classes take precedence over other classes, but need to be materialized manually" do 62 | @scope.client.should_receive(:materialize).with('SomeLocalClass').and_return(Class.new) 63 | 64 | @scope.perform do 65 | materialize 'SomeLocalClass' 66 | expect(SomeLocalClass).not_to be(::SomeLocalClass) 67 | end 68 | end 69 | 70 | 71 | it "properly pass outside variables into the block" do 72 | variable = 1 73 | 74 | @scope.perform do 75 | expect(variable).to be 1 76 | end 77 | end 78 | end 79 | end 80 | --------------------------------------------------------------------------------