salesforce_id 1.0.0
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 +7 -0
- data/.gitignore +30 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +86 -0
- data/Rakefile +13 -0
- data/bin/bundler +16 -0
- data/bin/byebug +16 -0
- data/bin/cc-tddium-post-worker +16 -0
- data/bin/coderay +16 -0
- data/bin/console +14 -0
- data/bin/htmldiff +16 -0
- data/bin/ldiff +16 -0
- data/bin/pry +16 -0
- data/bin/rake +16 -0
- data/bin/rake-compiler +16 -0
- data/bin/rspec +16 -0
- data/bin/setup +7 -0
- data/ext/salesforce_id/charmap.c +17 -0
- data/ext/salesforce_id/charmap.h +10 -0
- data/ext/salesforce_id/extconf.rb +5 -0
- data/ext/salesforce_id/insensitive_to_sensitive.c +19 -0
- data/ext/salesforce_id/insensitive_to_sensitive.h +8 -0
- data/ext/salesforce_id/repair_casing.c +49 -0
- data/ext/salesforce_id/repair_casing.h +6 -0
- data/ext/salesforce_id/salesforce_id_ext.c +151 -0
- data/ext/salesforce_id/salesforce_id_ext.h +67 -0
- data/ext/salesforce_id/sensitive_to_insensitive.c +54 -0
- data/ext/salesforce_id/sensitive_to_insensitive.h +8 -0
- data/ext/salesforce_id/validate_id.c +18 -0
- data/ext/salesforce_id/validate_id.h +11 -0
- data/lib/salesforce_id/version.rb +3 -0
- data/lib/salesforce_id.rb +6 -0
- data/salesforce_id.gemspec +37 -0
- metadata +179 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4898a0b33f8f54372cff05bd0b65c0705c544a8c
|
4
|
+
data.tar.gz: c9f1d80e51b4229bc9bd636fb5a684c050494cf6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4b6885c6be43f1ead7dc991a006278faaad1968b734324eed060b13f9801f7ca8868ca8602735fb1a7c5992b9772a50426d0d8ab96e7c32aae11ff49086b4f88
|
7
|
+
data.tar.gz: fe2d8cab75769f2eba6f618a9ab9072e09e3c8938a6d4f633ef5a338afa8926cff19e0e6ff25d7ed6748bb60b6434d06926f73a740bab010ab8e5b7325ddd444
|
data/.gitignore
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/Gemfile.lock
|
4
|
+
/_yardoc/
|
5
|
+
/coverage/
|
6
|
+
/doc/
|
7
|
+
/pkg/
|
8
|
+
/spec/reports/
|
9
|
+
/tmp/
|
10
|
+
.DS_Store
|
11
|
+
|
12
|
+
.project
|
13
|
+
.directory
|
14
|
+
*.swp
|
15
|
+
*~
|
16
|
+
.DS_Store
|
17
|
+
.idea
|
18
|
+
.envrc
|
19
|
+
.nvmrc
|
20
|
+
.ruby-gemset
|
21
|
+
.ruby-version
|
22
|
+
.rspec-local
|
23
|
+
*.backup
|
24
|
+
npm-debug.log
|
25
|
+
|
26
|
+
*.bundle
|
27
|
+
*.so
|
28
|
+
*.o
|
29
|
+
*.a
|
30
|
+
mkmf.log
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Fire-Dragon-DoL
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# SalesforceId [](https://travis-ci.org/Fire-Dragon-DoL/salesforce_id.svg?branch=master) [](https://codeclimate.com/github/Fire-Dragon-DoL/salesforce_id) [](https://codeclimate.com/github/Fire-Dragon-DoL/salesforce_id/coverage)
|
2
|
+
|
3
|
+
Gem to properly convert from and to 15 characters case sensitive format and
|
4
|
+
18 characters case insensitive format for salesforce record ID.
|
5
|
+
|
6
|
+
It's implemented as a C library to make the conversion as fast and performant
|
7
|
+
as possible.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'salesforce_id'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install salesforce_id
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
The gem can be used as easily as:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
id15 = "003G000001SUbc4"
|
31
|
+
id18 = "003G000001SUbc4IAD"
|
32
|
+
|
33
|
+
# Convert to insensitive id, 18 characters
|
34
|
+
SalesforceId.to_insensitive(id15) == id18 # => true
|
35
|
+
|
36
|
+
# Convert to sensitive id, 15 characters
|
37
|
+
SalesforceId.to_sensitive(id18) == id15 # => true
|
38
|
+
|
39
|
+
# Check if salesforce id is valid
|
40
|
+
SalesforceId.valid?(id15) # => true
|
41
|
+
SalesforceId.valid?(id18) # => true
|
42
|
+
SalesforceId.valid?("foo") # => false
|
43
|
+
|
44
|
+
# Fixes casing for case-insensitive ids
|
45
|
+
SalesforceId.repair_casing(id18.downcase) == id18 # => true
|
46
|
+
|
47
|
+
# Check if id is case-sensitive format
|
48
|
+
SalesforceId.sensitive?(id15) # => true
|
49
|
+
SalesforceId.sensitive?(id18) # => false
|
50
|
+
SalesforceId.sensitive?(nil) # => false
|
51
|
+
|
52
|
+
# Check if id is case-insensitive format
|
53
|
+
SalesforceId.insensitive?(id18) # => true
|
54
|
+
SalesforceId.insensitive?(id15) # => false
|
55
|
+
SalesforceId.insensitive?(nil) # => false
|
56
|
+
```
|
57
|
+
|
58
|
+
## Documentation
|
59
|
+
|
60
|
+
Methods are documented in [salesforce_id_ext.h](https://github.com/Fire-Dragon-DoL/salesforce_id/blob/master/ext/salesforce_id/salesforce_id_ext.h), this file is
|
61
|
+
the only public API of the gem, everything else must be considered private.
|
62
|
+
|
63
|
+
## Links
|
64
|
+
|
65
|
+
Some useful links related to this Salesforce ID issue:
|
66
|
+
|
67
|
+
- [What are salesforce ids composed of](http://salesforce.stackexchange.com/questions/1653/what-are-salesforce-ids-composed-of)
|
68
|
+
- [How I can view 18 characters long Salesforce ID in reports?](https://success.salesforce.com/answers?id=90630000000gy8oAAA)
|
69
|
+
- [Why does 18-character ID casing matter in a SOQL WHERE clause?](http://salesforce.stackexchange.com/questions/50163/why-does-18-character-id-casing-matter-in-a-soql-where-clause)
|
70
|
+
- [Creating a link using an 18 character ID](http://salesforce.stackexchange.com/questions/9568/creating-a-link-using-an-18-character-id/9569#9569)
|
71
|
+
|
72
|
+
## Development
|
73
|
+
|
74
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
75
|
+
|
76
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
77
|
+
|
78
|
+
## Contributing
|
79
|
+
|
80
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Fire-Dragon-DoL/salesforce_id.
|
81
|
+
|
82
|
+
|
83
|
+
## License
|
84
|
+
|
85
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
86
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
task :default => [:compile, :spec]
|
7
|
+
require "rake/extensiontask"
|
8
|
+
|
9
|
+
task :build => :compile
|
10
|
+
|
11
|
+
Rake::ExtensionTask.new("salesforce_id") do |ext|
|
12
|
+
ext.lib_dir = "lib/salesforce_id"
|
13
|
+
end
|
data/bin/bundler
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'bundler' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('bundler', 'bundler')
|
data/bin/byebug
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'byebug' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('byebug', 'byebug')
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'cc-tddium-post-worker' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('codeclimate-test-reporter', 'cc-tddium-post-worker')
|
data/bin/coderay
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'coderay' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('coderay', 'coderay')
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "salesforce_id"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/htmldiff
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'htmldiff' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('diff-lcs', 'htmldiff')
|
data/bin/ldiff
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'ldiff' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('diff-lcs', 'ldiff')
|
data/bin/pry
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'pry' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('pry', 'pry')
|
data/bin/rake
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rake' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rake', 'rake')
|
data/bin/rake-compiler
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rake-compiler' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rake-compiler', 'rake-compiler')
|
data/bin/rspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rspec' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/bin/setup
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#include "charmap.h"
|
2
|
+
#include <ctype.h>
|
3
|
+
|
4
|
+
const char CHARMAP[CHARMAP_SIZE] = {
|
5
|
+
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
6
|
+
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5'
|
7
|
+
};
|
8
|
+
|
9
|
+
int charmap_index(const char character)
|
10
|
+
{
|
11
|
+
char upped = toupper(character);
|
12
|
+
|
13
|
+
for (int index = 0; index < CHARMAP_SIZE; ++index)
|
14
|
+
if (CHARMAP[index] == upped) return index;
|
15
|
+
|
16
|
+
return (-1);
|
17
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "insensitive_to_sensitive.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include <string.h>
|
4
|
+
#include "salesforce_id_ext.h"
|
5
|
+
#include "repair_casing.h"
|
6
|
+
|
7
|
+
// rb_sId MUST be a string and of size 18
|
8
|
+
VALUE insensitive_to_sensitive(VALUE rb_sId)
|
9
|
+
{
|
10
|
+
const int new_id_size = SALESFORCE_ID_INSENSITIVE_STRING_LENGTH;
|
11
|
+
char* id = StringValueCStr(rb_sId);
|
12
|
+
char new_id[SALESFORCE_ID_INSENSITIVE_STRING_LENGTH] = {0};
|
13
|
+
|
14
|
+
memcpy(new_id, id, new_id_size);
|
15
|
+
repair_casing(new_id);
|
16
|
+
memset(&new_id[15], '\0', sizeof(new_id[0]) * 4u);
|
17
|
+
|
18
|
+
return rb_str_new2(new_id);
|
19
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#include "repair_casing.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include <stddef.h>
|
4
|
+
#include <string.h>
|
5
|
+
#include <ctype.h>
|
6
|
+
#include <stdbool.h>
|
7
|
+
#include "salesforce_id_ext.h"
|
8
|
+
#include "charmap.h"
|
9
|
+
|
10
|
+
static void chunk_casing(const char character, bool* casing);
|
11
|
+
|
12
|
+
void repair_casing(char* id)
|
13
|
+
{
|
14
|
+
const int chunk_index = SALESFORCE_ID_SENSITIVE_LENGTH;
|
15
|
+
const size_t casing_size = (size_t)SALESFORCE_ID_SENSITIVE_LENGTH;
|
16
|
+
bool casing[SALESFORCE_ID_SENSITIVE_LENGTH] = {false};
|
17
|
+
|
18
|
+
chunk_casing(id[chunk_index], casing);
|
19
|
+
chunk_casing(id[chunk_index + 1], &casing[5]);
|
20
|
+
chunk_casing(id[chunk_index + 2], &casing[10]);
|
21
|
+
|
22
|
+
for (size_t index = 0u; index < casing_size; ++index)
|
23
|
+
{
|
24
|
+
if (casing[index])
|
25
|
+
id[index] = toupper(id[index]);
|
26
|
+
else
|
27
|
+
id[index] = tolower(id[index]);
|
28
|
+
}
|
29
|
+
|
30
|
+
id[chunk_index] = toupper(id[chunk_index]);
|
31
|
+
id[chunk_index + 1] = toupper(id[chunk_index]);
|
32
|
+
id[chunk_index + 2] = toupper(id[chunk_index]);
|
33
|
+
}
|
34
|
+
|
35
|
+
// Casing is an array of size 5
|
36
|
+
void chunk_casing(const char character, bool* casing)
|
37
|
+
{
|
38
|
+
const size_t casing_size = 5u;
|
39
|
+
int map_index = charmap_index(character);
|
40
|
+
|
41
|
+
if (map_index < 0)
|
42
|
+
{
|
43
|
+
rb_raise(rb_eArgError, "Salesforce ID contains invalid character");
|
44
|
+
return;
|
45
|
+
}
|
46
|
+
|
47
|
+
for (size_t bit_index = 0u; bit_index < casing_size; ++bit_index)
|
48
|
+
casing[bit_index] = (map_index & (1u << bit_index)) != 0u;
|
49
|
+
}
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#include "salesforce_id_ext.h"
|
2
|
+
#include <string.h>
|
3
|
+
#include <ctype.h>
|
4
|
+
#include <stddef.h>
|
5
|
+
#include "repair_casing.h"
|
6
|
+
#include "insensitive_to_sensitive.h"
|
7
|
+
#include "sensitive_to_insensitive.h"
|
8
|
+
#include "validate_id.h"
|
9
|
+
|
10
|
+
VALUE rb_mSalesforceId;
|
11
|
+
|
12
|
+
void Init_salesforce_id()
|
13
|
+
{
|
14
|
+
// Module
|
15
|
+
rb_mSalesforceId = rb_define_module("SalesforceId");
|
16
|
+
|
17
|
+
// Constants
|
18
|
+
rb_define_const(
|
19
|
+
rb_mSalesforceId,
|
20
|
+
"SENSITIVE_SIZE",
|
21
|
+
INT2FIX(SALESFORCE_ID_SENSITIVE_LENGTH)
|
22
|
+
);
|
23
|
+
rb_define_const(
|
24
|
+
rb_mSalesforceId,
|
25
|
+
"INSENSITIVE_SIZE",
|
26
|
+
INT2FIX(SALESFORCE_ID_INSENSITIVE_LENGTH)
|
27
|
+
);
|
28
|
+
|
29
|
+
// Methods
|
30
|
+
rb_define_method(
|
31
|
+
rb_mSalesforceId,
|
32
|
+
"to_sensitive",
|
33
|
+
salesforce_id_to_sensitive,
|
34
|
+
1
|
35
|
+
);
|
36
|
+
rb_define_method(
|
37
|
+
rb_mSalesforceId,
|
38
|
+
"to_insensitive",
|
39
|
+
salesforce_id_to_insensitive,
|
40
|
+
1
|
41
|
+
);
|
42
|
+
rb_define_method(
|
43
|
+
rb_mSalesforceId,
|
44
|
+
"valid?",
|
45
|
+
salesforce_id_is_valid,
|
46
|
+
1
|
47
|
+
);
|
48
|
+
rb_define_method(
|
49
|
+
rb_mSalesforceId,
|
50
|
+
"repair_casing",
|
51
|
+
salesforce_insensitive_repair_casing,
|
52
|
+
1
|
53
|
+
);
|
54
|
+
rb_define_method(
|
55
|
+
rb_mSalesforceId,
|
56
|
+
"sensitive?",
|
57
|
+
salesforce_id_is_sensitive,
|
58
|
+
1
|
59
|
+
);
|
60
|
+
rb_define_method(
|
61
|
+
rb_mSalesforceId,
|
62
|
+
"insensitive?",
|
63
|
+
salesforce_id_is_insensitive,
|
64
|
+
1
|
65
|
+
);
|
66
|
+
}
|
67
|
+
|
68
|
+
// Convert to 15 character case-sensitive id
|
69
|
+
VALUE salesforce_id_to_sensitive(VALUE self, VALUE rb_sId)
|
70
|
+
{
|
71
|
+
VALUE id = rb_obj_as_string(rb_sId);
|
72
|
+
|
73
|
+
if (!is_id_valid(id))
|
74
|
+
{
|
75
|
+
rb_raise(rb_eArgError, "Invalid Salesforce ID");
|
76
|
+
return Qnil;
|
77
|
+
}
|
78
|
+
|
79
|
+
if (RSTRING_LEN(id) == SALESFORCE_ID_SENSITIVE_LENGTH) return id;
|
80
|
+
|
81
|
+
return insensitive_to_sensitive(id);
|
82
|
+
}
|
83
|
+
|
84
|
+
// Convert to 18 character case-insensitive id
|
85
|
+
VALUE salesforce_id_to_insensitive(VALUE self, VALUE rb_sId)
|
86
|
+
{
|
87
|
+
VALUE id = rb_obj_as_string(rb_sId);
|
88
|
+
|
89
|
+
if (!is_id_valid(id))
|
90
|
+
{
|
91
|
+
rb_raise(rb_eArgError, "Invalid Salesforce ID");
|
92
|
+
return Qnil;
|
93
|
+
}
|
94
|
+
|
95
|
+
if (RSTRING_LEN(id) == SALESFORCE_ID_INSENSITIVE_LENGTH) return id;
|
96
|
+
|
97
|
+
return sensitive_to_insensitive(id);
|
98
|
+
}
|
99
|
+
|
100
|
+
VALUE salesforce_id_is_valid(VALUE self, VALUE rb_sId)
|
101
|
+
{
|
102
|
+
VALUE id = rb_obj_as_string(rb_sId);
|
103
|
+
|
104
|
+
if (is_id_valid(id)) return Qtrue;
|
105
|
+
|
106
|
+
return Qfalse;
|
107
|
+
}
|
108
|
+
|
109
|
+
VALUE salesforce_insensitive_repair_casing(VALUE self, VALUE rb_sId)
|
110
|
+
{
|
111
|
+
VALUE id = rb_obj_as_string(rb_sId);
|
112
|
+
|
113
|
+
if (!is_id_valid(id) || RSTRING_LEN(id) != SALESFORCE_ID_INSENSITIVE_LENGTH)
|
114
|
+
rb_raise(rb_eArgError, "Salesforce ID is not case-insensitive format");
|
115
|
+
|
116
|
+
// Start for insensitive characters
|
117
|
+
const size_t istart = (size_t)SALESFORCE_ID_SENSITIVE_LENGTH;
|
118
|
+
const size_t sensitive_chars = 3u;
|
119
|
+
const int new_id_size = SALESFORCE_ID_INSENSITIVE_STRING_LENGTH;
|
120
|
+
char* old_id = StringValueCStr(id);
|
121
|
+
char new_id[SALESFORCE_ID_INSENSITIVE_STRING_LENGTH] = {0};
|
122
|
+
|
123
|
+
memcpy(new_id, old_id, new_id_size);
|
124
|
+
repair_casing(new_id);
|
125
|
+
memcpy(&new_id[istart], &old_id[istart], sizeof(new_id[0]) * sensitive_chars);
|
126
|
+
|
127
|
+
for (size_t index = 0u; index < sensitive_chars; ++index)
|
128
|
+
new_id[istart + index] = toupper(new_id[istart + index]);
|
129
|
+
|
130
|
+
return rb_str_new2(new_id);
|
131
|
+
}
|
132
|
+
|
133
|
+
VALUE salesforce_id_is_sensitive(VALUE self, VALUE rb_sId)
|
134
|
+
{
|
135
|
+
VALUE id = rb_obj_as_string(rb_sId);
|
136
|
+
|
137
|
+
if (is_id_valid(id) && (RSTRING_LEN(id) == SALESFORCE_ID_SENSITIVE_LENGTH))
|
138
|
+
return Qtrue;
|
139
|
+
|
140
|
+
return Qfalse;
|
141
|
+
}
|
142
|
+
|
143
|
+
VALUE salesforce_id_is_insensitive(VALUE self, VALUE rb_sId)
|
144
|
+
{
|
145
|
+
VALUE id = rb_obj_as_string(rb_sId);
|
146
|
+
|
147
|
+
if (is_id_valid(id) && (RSTRING_LEN(id) == SALESFORCE_ID_INSENSITIVE_LENGTH))
|
148
|
+
return Qtrue;
|
149
|
+
|
150
|
+
return Qfalse;
|
151
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#ifndef SALESFORCE_ID_H
|
2
|
+
#define SALESFORCE_ID_H 1
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
|
6
|
+
extern VALUE rb_mSalesforceId;
|
7
|
+
|
8
|
+
#define SALESFORCE_ID_SENSITIVE_LENGTH 15
|
9
|
+
#define SALESFORCE_ID_INSENSITIVE_LENGTH 18
|
10
|
+
#define SALESFORCE_ID_SENSITIVE_STRING_LENGTH 16
|
11
|
+
#define SALESFORCE_ID_INSENSITIVE_STRING_LENGTH 19
|
12
|
+
|
13
|
+
/*
|
14
|
+
* Entry point
|
15
|
+
*/
|
16
|
+
void Init_salesforce_id();
|
17
|
+
|
18
|
+
/*
|
19
|
+
* Converts any valid salesforce ID to case-sensitive version. Raises
|
20
|
+
* ArgumentError if ID contains invalid characters or it's not correct length
|
21
|
+
* @param rb_sId [String] valid salesforce id
|
22
|
+
* @return [String] salesforce id in case-sensitive version
|
23
|
+
*/
|
24
|
+
VALUE salesforce_id_to_sensitive(VALUE self, VALUE rb_sId);
|
25
|
+
|
26
|
+
/*
|
27
|
+
* Converts any valid salesforce ID to case-insensitive version. Raises
|
28
|
+
* ArgumentError if ID contains invalid characters or it's not correct length
|
29
|
+
* @param rb_sId [String] valid salesforce id
|
30
|
+
* @return [String] salesforce id in case-insensitive version
|
31
|
+
*/
|
32
|
+
VALUE salesforce_id_to_insensitive(VALUE self, VALUE rb_sId);
|
33
|
+
|
34
|
+
/*
|
35
|
+
* Performs a deep check of the ID ensuring characters are all valid and length
|
36
|
+
* is valid too
|
37
|
+
* @param rb_sId [String] salesforce id (valid or not)
|
38
|
+
* @return [Boolean] true if the deep check has success and salesforce id is
|
39
|
+
* valid
|
40
|
+
*/
|
41
|
+
VALUE salesforce_id_is_valid(VALUE self, VALUE rb_sId);
|
42
|
+
|
43
|
+
/*
|
44
|
+
* Fixes a valid case-insensitive salesforce id casing by using the last 3
|
45
|
+
* letters
|
46
|
+
* @param rb_sId [String] valid salesforce id in case-insensitive format
|
47
|
+
* @return [String] case-insensitive salesforce id with casing fixed, which
|
48
|
+
* means you can strip the last 3 characters to obtain the case-sensitive
|
49
|
+
* format
|
50
|
+
*/
|
51
|
+
VALUE salesforce_insensitive_repair_casing(VALUE self, VALUE rb_sId);
|
52
|
+
|
53
|
+
/*
|
54
|
+
* Detects if given ID is case-sensitive
|
55
|
+
* @param rb_sId [String] salesforce id (valid or not)
|
56
|
+
* @return [Boolean] true if passed ID is valid case-sensitive salesforce ID
|
57
|
+
*/
|
58
|
+
VALUE salesforce_id_is_sensitive(VALUE self, VALUE rb_sId);
|
59
|
+
|
60
|
+
/*
|
61
|
+
* Detects if given ID is case-insensitive
|
62
|
+
* @param rb_sId [String] salesforce id (valid or not)
|
63
|
+
* @return [Boolean] true if passed ID is valid case-insensitive salesforce ID
|
64
|
+
*/
|
65
|
+
VALUE salesforce_id_is_insensitive(VALUE self, VALUE rb_sId);
|
66
|
+
|
67
|
+
#endif /* SALESFORCE_ID_H */
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#include "sensitive_to_insensitive.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include <stddef.h>
|
4
|
+
#include <string.h>
|
5
|
+
#include <stdint.h>
|
6
|
+
#include <ctype.h>
|
7
|
+
#include "salesforce_id_ext.h"
|
8
|
+
#include "charmap.h"
|
9
|
+
|
10
|
+
static void append_casing_hash(char* id);
|
11
|
+
static char char_from_chunk(char* id, size_t chunk);
|
12
|
+
|
13
|
+
// rb_sId MUST be a string and of size 15
|
14
|
+
VALUE sensitive_to_insensitive(VALUE rb_sId)
|
15
|
+
{
|
16
|
+
const int id_size = SALESFORCE_ID_SENSITIVE_STRING_LENGTH;
|
17
|
+
char* id = StringValueCStr(rb_sId);
|
18
|
+
char new_id[SALESFORCE_ID_INSENSITIVE_STRING_LENGTH] = {0};
|
19
|
+
|
20
|
+
memcpy(new_id, id, sizeof(char) * id_size);
|
21
|
+
append_casing_hash(new_id);
|
22
|
+
|
23
|
+
return rb_str_new2(new_id);
|
24
|
+
}
|
25
|
+
|
26
|
+
void append_casing_hash(char* id)
|
27
|
+
{
|
28
|
+
const int insensitive_index = SALESFORCE_ID_SENSITIVE_LENGTH;
|
29
|
+
const size_t chunks = 3u;
|
30
|
+
char hash[3] = {'\0', '\0', '\0'};
|
31
|
+
|
32
|
+
for (size_t chunk = 0u; chunk < chunks; ++chunk)
|
33
|
+
hash[chunk] = char_from_chunk(id, chunk);
|
34
|
+
|
35
|
+
id[insensitive_index] = hash[0];
|
36
|
+
id[insensitive_index + 1] = hash[1];
|
37
|
+
id[insensitive_index + 2] = hash[2];
|
38
|
+
}
|
39
|
+
|
40
|
+
// Chunk must be within 0 and 2
|
41
|
+
char char_from_chunk(char* id, size_t chunk)
|
42
|
+
{
|
43
|
+
const size_t chars_per_chunk = 5u;
|
44
|
+
uint8_t map_index = 0u;
|
45
|
+
|
46
|
+
for (size_t index = 0u; index < chars_per_chunk; ++index)
|
47
|
+
{
|
48
|
+
char current = id[(chars_per_chunk * chunk) + index];
|
49
|
+
|
50
|
+
if (isupper(current)) map_index = (map_index | (1u << index));
|
51
|
+
}
|
52
|
+
|
53
|
+
return CHARMAP[map_index];
|
54
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#include "validate_id.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include <stdbool.h>
|
4
|
+
#include <string.h>
|
5
|
+
#include <stddef.h>
|
6
|
+
#include "salesforce_id_ext.h"
|
7
|
+
#include "charmap.h"
|
8
|
+
|
9
|
+
// rb_sId MUST be a string
|
10
|
+
bool is_id_valid(VALUE rb_sId)
|
11
|
+
{
|
12
|
+
VALUE id = rb_sId;
|
13
|
+
|
14
|
+
if (RSTRING_LEN(id) == SALESFORCE_ID_SENSITIVE_LENGTH) return true;
|
15
|
+
if (RSTRING_LEN(id) == SALESFORCE_ID_INSENSITIVE_LENGTH) return true;
|
16
|
+
|
17
|
+
return false;
|
18
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'salesforce_id/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "salesforce_id"
|
8
|
+
spec.version = SalesforceId::VERSION
|
9
|
+
spec.authors = ["Fire-Dragon-DoL"]
|
10
|
+
spec.email = ["francesco.belladonna@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Gem to handle 15 characters and 18 characters salesforce IDs}
|
13
|
+
spec.description = %q{Gem to properly convert from and to 15 characters case sensitive format and 18 characters case insensitive format for salesforce record ID}
|
14
|
+
spec.homepage = "https://github.com/Fire-Dragon-DoL/salesforce_id"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
17
|
+
# delete this section to allow pushing this gem to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
20
|
+
else
|
21
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
22
|
+
end
|
23
|
+
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
spec.bindir = "exe"
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
spec.extensions = ["ext/salesforce_id/extconf.rb"]
|
29
|
+
|
30
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
31
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
32
|
+
spec.add_development_dependency "rake-compiler"
|
33
|
+
spec.add_development_dependency "rspec"
|
34
|
+
spec.add_development_dependency "fuubar"
|
35
|
+
spec.add_development_dependency "pry"
|
36
|
+
spec.add_development_dependency "pry-byebug"
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: salesforce_id
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Fire-Dragon-DoL
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake-compiler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
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: fuubar
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
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: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry-byebug
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Gem to properly convert from and to 15 characters case sensitive format
|
112
|
+
and 18 characters case insensitive format for salesforce record ID
|
113
|
+
email:
|
114
|
+
- francesco.belladonna@gmail.com
|
115
|
+
executables: []
|
116
|
+
extensions:
|
117
|
+
- ext/salesforce_id/extconf.rb
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- ".gitignore"
|
121
|
+
- ".rspec"
|
122
|
+
- ".travis.yml"
|
123
|
+
- Gemfile
|
124
|
+
- LICENSE
|
125
|
+
- README.md
|
126
|
+
- Rakefile
|
127
|
+
- bin/bundler
|
128
|
+
- bin/byebug
|
129
|
+
- bin/cc-tddium-post-worker
|
130
|
+
- bin/coderay
|
131
|
+
- bin/console
|
132
|
+
- bin/htmldiff
|
133
|
+
- bin/ldiff
|
134
|
+
- bin/pry
|
135
|
+
- bin/rake
|
136
|
+
- bin/rake-compiler
|
137
|
+
- bin/rspec
|
138
|
+
- bin/setup
|
139
|
+
- ext/salesforce_id/charmap.c
|
140
|
+
- ext/salesforce_id/charmap.h
|
141
|
+
- ext/salesforce_id/extconf.rb
|
142
|
+
- ext/salesforce_id/insensitive_to_sensitive.c
|
143
|
+
- ext/salesforce_id/insensitive_to_sensitive.h
|
144
|
+
- ext/salesforce_id/repair_casing.c
|
145
|
+
- ext/salesforce_id/repair_casing.h
|
146
|
+
- ext/salesforce_id/salesforce_id_ext.c
|
147
|
+
- ext/salesforce_id/salesforce_id_ext.h
|
148
|
+
- ext/salesforce_id/sensitive_to_insensitive.c
|
149
|
+
- ext/salesforce_id/sensitive_to_insensitive.h
|
150
|
+
- ext/salesforce_id/validate_id.c
|
151
|
+
- ext/salesforce_id/validate_id.h
|
152
|
+
- lib/salesforce_id.rb
|
153
|
+
- lib/salesforce_id/version.rb
|
154
|
+
- salesforce_id.gemspec
|
155
|
+
homepage: https://github.com/Fire-Dragon-DoL/salesforce_id
|
156
|
+
licenses: []
|
157
|
+
metadata:
|
158
|
+
allowed_push_host: https://rubygems.org
|
159
|
+
post_install_message:
|
160
|
+
rdoc_options: []
|
161
|
+
require_paths:
|
162
|
+
- lib
|
163
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
requirements: []
|
174
|
+
rubyforge_project:
|
175
|
+
rubygems_version: 2.4.6
|
176
|
+
signing_key:
|
177
|
+
specification_version: 4
|
178
|
+
summary: Gem to handle 15 characters and 18 characters salesforce IDs
|
179
|
+
test_files: []
|