atomics_resource 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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ ## production gems
4
+ gem "nokogiri"
5
+
6
+ ## dev gems
7
+ group :development do
8
+ gem "shoulda", ">= 0"
9
+ gem "bundler", "~> 1.0.0"
10
+ gem "jeweler", "~> 1.6.4"
11
+ gem "rcov", ">= 0"
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,22 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.6.4)
6
+ bundler (~> 1.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ nokogiri (1.5.0)
10
+ rake (0.9.2)
11
+ rcov (0.9.10)
12
+ shoulda (2.11.3)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ bundler (~> 1.0.0)
19
+ jeweler (~> 1.6.4)
20
+ nokogiri
21
+ rcov
22
+ shoulda
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Richard Lister
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,92 @@
1
+ = Atomics Resource
2
+
3
+ Ruby and/or Rails interface for Atomics queries. Atomics is MySQL over
4
+ HTTP, originally developed at CNET and has similar intent to DBSlayer.
5
+
6
+ == Philosophy
7
+
8
+ This module use a different approach from
9
+ e.g. activerecord-dbslayer-adapter, which subclasses the MySQL adapter
10
+ in order to use ActiveRecord. Rather, AtomicsResource is a lightweight
11
+ re-implementation of some ActiveRecord-style methods, which means the
12
+ module can be used in non-Rails apps, or mixed with non-MySQL
13
+ connections in a Rails app.
14
+
15
+ == Overview
16
+
17
+ Classes representing resources in atomics are created by subclassing
18
+ AtomicsResource::Base. Class find methods are mapped to HTTP GET
19
+ requests. XML responses are parsed and mapped to an instance of the
20
+ class.
21
+
22
+ === Configuration
23
+
24
+ To use an instance, you will need to create a yaml file with atomics
25
+ configs, e.g. config/atomics.yml:
26
+
27
+ hr:
28
+ host: hr-atomics.newco.com
29
+ port: 8080
30
+ path: /jAtomics/select/?version=1
31
+
32
+ then load the file into a hash called ATOMICS_CONFIG; in Rails this is
33
+ best done from an initializer, e.g. config/initializers/atomics_config.rb:
34
+
35
+ ATOMICS_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/atomics.yml")
36
+
37
+ === Usage
38
+
39
+ Your model will look like this:
40
+
41
+ class Employee < AtomicsResource::Base
42
+ set_atomics_type :hr #section of config file to read
43
+ set_table_name :employee_display #default table for requests
44
+ set_primary_key :id #default key for find() methods
45
+
46
+ ## default columns to SELECT, if none-given default will be '*'
47
+ column :first_name
48
+ column :last_name
49
+ column :title
50
+ column :team_id
51
+ end
52
+
53
+ and a simple controller:
54
+
55
+ class EmployeesController < ApplicationController
56
+ def index
57
+ @employees = Employee.all(:conditions => [ "team_id = ?", params[:team] ]
58
+ :order => [ :last_name, :first_name ])
59
+ end
60
+
61
+ def show
62
+ @employee = Employee.find(params[:id])
63
+ end
64
+ end
65
+
66
+ Conditions may be given as follows:
67
+
68
+ :conditions => "team_id = 156 AND title = 'Manager'"
69
+ :conditions => [ "team_id = ? AND title = ?", 156, 'Manager' ]
70
+ :conditions => [ "team_id = %d AND title = %s", 156 , 'Manager' ]
71
+ :conditions => { :team_id => 156, :title => :Manager }
72
+
73
+ Columns: in general you don't want to do "SELECT *" from Atomics
74
+ tables, which are frequently huge, denormalized beasts which will put
75
+ a lot of extra data on the wire that you don't want. Instead, list in
76
+ the model the columns you normally want, using 'column'. These will be
77
+ used to create the default 'SELECT' statement in find(). This can be
78
+ overridden using something like find(:all, :select=>'*').
79
+
80
+ Convenience functions:
81
+
82
+ Employee.all(99) ## equivalent to Employee.find(:all, :conditions => {:id = 99})
83
+ Employee.first(99) ## equivalent to Employee.find(:first, :conditions => {:id = 99})
84
+ Employee.last(99) ## equivalent to Employee.find(:last, :conditions => {:id = 99})
85
+
86
+ == Contributing to atomics_resource
87
+
88
+ The project is available for forking at github.
89
+
90
+ == Copyright
91
+
92
+ Copyright (c) 2011 Richard Lister. See LICENSE.txt for further details.
data/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ gem.name = "atomics_resource"
17
+ gem.homepage = "http://github.com/rlister/atomics_resource"
18
+ gem.license = "MIT"
19
+ gem.summary = %Q{Active Model for Atomics MySQL lookups}
20
+ gem.description = %Q{Model Atomics (MySQL over HTTP) records for ruby and rails projects}
21
+ gem.email = "rlister@github"
22
+ gem.authors = ["Richard Lister"]
23
+ end
24
+ Jeweler::RubygemsDotOrgTasks.new
25
+
26
+ require 'rake/testtask'
27
+ Rake::TestTask.new(:test) do |test|
28
+ test.libs << 'lib' << 'test'
29
+ test.pattern = 'test/**/test_*.rb'
30
+ test.verbose = true
31
+ end
32
+
33
+ require 'rcov/rcovtask'
34
+ Rcov::RcovTask.new do |test|
35
+ test.libs << 'test'
36
+ test.pattern = 'test/**/test_*.rb'
37
+ test.verbose = true
38
+ test.rcov_opts << '--exclude "gems/*"'
39
+ end
40
+
41
+ task :default => :test
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
46
+
47
+ rdoc.rdoc_dir = 'rdoc'
48
+ rdoc.title = "atomics_resource #{version}"
49
+ rdoc.rdoc_files.include('README*')
50
+ rdoc.rdoc_files.include('lib/**/*.rb')
51
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ## this does not run, but will show you how to configure against your local Atomics instance
4
+
5
+ require 'rubygems'
6
+ require 'atomics_resource'
7
+
8
+ ATOMICS_CONFIG = {
9
+ 'hr' => {
10
+ 'host' => 'hr-atomics.newco.com',
11
+ 'port' => '8080',
12
+ 'path' => '/jAtomics/select/?version=1',
13
+ },
14
+ 'other' => {
15
+ 'host' => 'other-atomics.for.illustration.com',
16
+ 'port' => '80',
17
+ 'path' => '/atomics/raw',
18
+ },
19
+ }
20
+
21
+ class Employee < AtomicsResource::Base
22
+ set_atomics_type :hr
23
+ set_table_name :employee_display
24
+ set_primary_key :id
25
+
26
+ column :first_name
27
+ column :last_name
28
+ column :title
29
+ column :team_id
30
+ end
31
+
32
+ employees = Employee.all(:conditions => {:team_id => 1},
33
+ :order => [:last_name, :first_name])
34
+
35
+ employees.each do |e|
36
+ puts "#{e.last_name},#{e.first_name}: #{e.title}"
37
+ end
@@ -0,0 +1,30 @@
1
+ #--
2
+ # Copyright (c) 2011 Richard Lister
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ ## ActiveModel-style interface for Atomics queries.
25
+
26
+ require 'atomics_resource/base.rb'
27
+
28
+ module AtomicsResource
29
+ ## noop
30
+ end
@@ -0,0 +1,246 @@
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+ require 'net/http'
4
+
5
+ module AtomicsResource
6
+
7
+ class Base
8
+
9
+ ## class instance variables
10
+ class << self
11
+ attr_accessor :atomics_type, :table_name, :primary_key
12
+ alias_method :set_atomics_type, :atomics_type=
13
+ alias_method :set_table_name, :table_name=
14
+ alias_method :set_primary_key, :primary_key=
15
+ end
16
+
17
+ ## Get method for array of columns (attr_accessor will break for arrays on inheritance).
18
+ def self.columns
19
+ @columns ||= []
20
+ end
21
+
22
+ ## Add a column.
23
+ def self.column(value)
24
+ columns << value
25
+ end
26
+
27
+ ## Quote value for Atomics in SQL statment; numeric arguments returned unquoted,
28
+ ## strings in single quotes.
29
+ def self.quote_value(value)
30
+ value.match(/^\d+$/) ? value : "'#{value}'"
31
+ end
32
+
33
+ ## Build a SQL query string from hash of options passed to find.
34
+ def self.construct_sql(options)
35
+ sql = []
36
+ sql << "SELECT " + construct_sql_for_params(options[:select])
37
+ sql << "FROM " + construct_sql_for_params(options[:from])
38
+ sql << "WHERE " + construct_sql_for_conditions(options[:conditions]) if options[:conditions]
39
+ sql << "ORDER BY " + construct_sql_for_params(options[:order]) if options[:order]
40
+ sql << "LIMIT " + options[:limit].to_s if options[:limit]
41
+ sql << "OFFSET " + options[:offset].to_s if options[:offset]
42
+ sql.join(' ')
43
+ end
44
+
45
+ ## Return string for SQL conditions from values params as string, array, or hash.
46
+ def self.construct_sql_for_params(parms)
47
+ case parms
48
+ when Array; parms.map(&:to_s).join(',')
49
+ when Hash; parms.keys.map(&:to_s).join(',')
50
+ else parms.to_s
51
+ end
52
+ end
53
+
54
+ ## Return string for SQL conditions from options params as string, array, or hash.
55
+ def self.construct_sql_for_conditions(option)
56
+ case option
57
+ when Array; construct_sql_for_array(option)
58
+ when Hash; construct_sql_for_hash (option) ## :TODO: implement this
59
+ else option
60
+ end
61
+ end
62
+
63
+ ## Construct string of conditions from an array of format plus values to substitute.
64
+ ## Examples:
65
+ ## [ 'foo = ? AND bar = ?', 'hello', 99 ]
66
+ ## [ 'foo = %s AND bar = %d", 'hello', 99 ]
67
+ def self.construct_sql_for_array(a)
68
+ format, *values = a
69
+ if format.include?("\?")
70
+ raise ArgumentError unless format.count('\?') == values.size # sanity check right number args
71
+ format.gsub(/\?/) { quote_value(values.shift.to_s) } # replace all ? with args
72
+ elsif format.blank?
73
+ format
74
+ else # replace sprintf escapes
75
+ format % values.collect { |value| quote_value(value.to_s) }
76
+ end
77
+ end
78
+
79
+ ## Construct string of conditions from a hash of format plus values to substitute.
80
+ ## Allows conditions as hash of key/value pairs to be ANDed together.
81
+ ## Examples:
82
+ ## { :foo => :hello, :bar => 99 }
83
+ def self.construct_sql_for_hash(h)
84
+ h.map{|k,v| "#{k}=#{quote_value(v.to_s)}"}.join(' AND ')
85
+ end
86
+
87
+ ## Calls find and returns array of all matches.
88
+ def self.all(*args)
89
+ find(:all, *args)
90
+ end
91
+
92
+ ## Calls find and returns first matching object.
93
+ def self.first(*args)
94
+ find(:first, *args)
95
+ end
96
+
97
+ ## Calls find and returns last matching object.
98
+ def self.last(*args)
99
+ find(:last, *args)
100
+ end
101
+
102
+ ## Find takes a list of conditions as a hash, and returns array of matching objects.
103
+ ## If single argument is numeric, return first object to match by primary key.
104
+ def self.find(*arguments)
105
+ scope = arguments.slice!(0)
106
+ options = arguments.slice!(0) || {}
107
+
108
+ case scope
109
+ when :all then find_every(options) # Employee.find(:all, :conditions => 'team_id = 156')
110
+ when :first then find_every(options).first # Employee.find(:first, :conditions => 'team_id = 156')
111
+ when :last then find_every(options).last # Employee.find(:last, :conditions => 'team_id = 156')
112
+ else find_single(scope, options) # Employee.find(7923113)
113
+ end
114
+ end
115
+
116
+ ## Return array of columns to use for SELECT statements, ensuring we get primary_key, or single
117
+ ## string '*' if no columns set.
118
+ def self.columns_or_default
119
+ columns.empty? ? '*' : ([primary_key]+columns).uniq
120
+ end
121
+
122
+ ## Find array of all matching records.
123
+ def self.find_every(options)
124
+ defaults = { :select => columns_or_default, :from => table_name }
125
+ sql = construct_sql(defaults.merge(options))
126
+ find_by_sql(sql)
127
+ end
128
+
129
+ ## Find a single record with given primary key.
130
+ def self.find_single(scope, options)
131
+ defaults = { :select => columns_or_default, :from => table_name, :conditions => {primary_key => scope} }
132
+ sql = construct_sql(defaults)
133
+ find_by_sql(sql).first
134
+ end
135
+
136
+ ## Return string with whole URL for request, adding given SQL string as query.
137
+ def self.construct_url_for_sql(sql)
138
+ (host, port, path) = ATOMICS_CONFIG[atomics_type.to_s].values_at('host', 'port', 'path')
139
+ "http://#{host}:#{port}#{path}&q=#{URI.escape(sql)}"
140
+ end
141
+
142
+ ## Find matches using raw SQL statement given as a string.
143
+ ## args:: string containing SQL statement.
144
+ ## returns:: array of objects.
145
+ def self.find_by_sql(sql)
146
+ url = construct_url_for_sql(sql)
147
+
148
+ ## get the xml doc as a nokogiri object
149
+ doc = Nokogiri::XML(open(url))
150
+
151
+
152
+ ## array of records
153
+ records = doc.xpath('//record').to_a.map do |record|
154
+
155
+ ## convert record into a hash with name => value
156
+ hash = record.xpath('./field').inject({}) do |hash, field|
157
+ hash[field.xpath('./name')[0].content] = field.xpath('./value')[0].content
158
+ hash
159
+ end
160
+
161
+ ## instantiate record object
162
+ new(hash)
163
+ end
164
+
165
+ end
166
+
167
+ ## What uses this?
168
+ def self.to_model
169
+ self
170
+ end
171
+
172
+ ## instance variables
173
+ attr_accessor :attributes
174
+
175
+ ## Constructor allows hash as arg to set attributes.
176
+ def initialize(attributes = {})
177
+ hsh = {}
178
+ @attributes = hsh.respond_to?(:with_indifferent_access) ? hsh.with_indifferent_access : hsh
179
+ load(attributes)
180
+ end
181
+
182
+ ## Set attributes for an existing instance of this object.
183
+ def load(attributes)
184
+ raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
185
+ attributes.each do |key, value|
186
+ @attributes[key.to_s] = value.dup rescue value
187
+ end
188
+ self
189
+ end
190
+
191
+ ## Return formatted inspection string for record with attributes listed.
192
+ def inspect
193
+ attributes_string = @attributes.map{|k,v| "#{k}: #{value_for_inspect(v)}"}.join(', ')
194
+ "#<#{self.class} #{attributes_string}>"
195
+ end
196
+
197
+ ## Returns inspect for a value, with strings shortened to 50 chars, for use in Object.inspect.
198
+ def value_for_inspect(value)
199
+ if value.is_a?(String) && value.length > 50
200
+ "#{value[0..50]}...".inspect
201
+ else
202
+ value.inspect
203
+ end
204
+ end
205
+
206
+ ## Get attributes as methods, like active_model.
207
+ def method_missing(method_symbol, *arguments)
208
+ method_name = method_symbol.to_s
209
+ if method_name =~ /=$/
210
+ attributes[$`] = arguments.first
211
+ elsif method_name =~ /\?$/
212
+ attributes[$`]
213
+ else
214
+ return attributes[method_name] if attributes.include?(method_name)
215
+ super
216
+ end
217
+ end
218
+
219
+ ## Get attributes using hash syntax.
220
+ def [](attr)
221
+ attributes[attr]
222
+ end
223
+
224
+ ## Value of primary key.
225
+ def id
226
+ attributes[self.class.primary_key].to_i
227
+ end
228
+
229
+ ## What uses this?
230
+ def to_key
231
+ [id]
232
+ end
233
+
234
+ ## Return primary_key as param for object, for polymorphic route generation to work from object in view.
235
+ def to_param
236
+ attributes[self.class.primary_key]
237
+ end
238
+
239
+ end
240
+
241
+ ## Do some mix-ins to get various bits of rails coolness, skip these for non-rails.
242
+ if defined? RAILS_ROOT
243
+ extend ActiveModel::Naming # need this for model_name and variants, used to get paths from objects
244
+ end
245
+
246
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,7 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+
7
+ require 'atomics_resource'
@@ -0,0 +1,52 @@
1
+ require File.dirname(__FILE__) + '/helper.rb'
2
+
3
+ # ATOMICS_CONFIG = YAML.load_file("atomics.yml")
4
+
5
+ ATOMICS_CONFIG = {
6
+ 'my_type' => {
7
+ 'host' => 'orb-atomics.ops.aol.com',
8
+ 'port' => '8080',
9
+ 'path' => '/jAtomics/select/?version=1'
10
+ }
11
+ }
12
+
13
+ module AtomicsResource
14
+ describe Base do
15
+ before :each do
16
+ class MyTest < AtomicsResource::Base
17
+ set_atomics_type :my_type
18
+ set_table_name :my_table
19
+ set_primary_key :my_pk
20
+ end
21
+ end
22
+
23
+ context "class variables" do
24
+ it "should have class settings" do
25
+ MyTest.atomics_type.should == :my_type
26
+ MyTest.table_name.should == :my_table
27
+ MyTest.primary_key.should == :my_pk
28
+ end
29
+ end
30
+
31
+ context "atomics config" do
32
+ require 'uri'
33
+ it "should create a valid base URL" do
34
+ sql = "select * from foo where bar = 'wibble'"
35
+ URI.parse(MyTest.construct_url_for_sql(sql)).class.should == URI::HTTP
36
+ end
37
+ end
38
+
39
+ context "sql construction" do
40
+ it "should construct sql from array conditions" do
41
+ a = MyTest.construct_sql_for_conditions(["foo = \? AND bar = \?", :hello, :world])
42
+ a.should == "foo = 'hello' AND bar = 'world'"
43
+ end
44
+ it "should contruct sql from hash conditions" do
45
+ b = MyTest.construct_sql_for_conditions({:foo => :hello, :bar => :world})
46
+ b.should == "foo='hello' AND bar='world'"
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestAtomicsResource < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: atomics_resource
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Richard Lister
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-08-15 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: nokogiri
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: shoulda
28
+ requirement: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: bundler
39
+ requirement: &id003 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 1.0.0
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: jeweler
50
+ requirement: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 1.6.4
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: rcov
61
+ requirement: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *id005
70
+ description: Model Atomics (MySQL over HTTP) records for ruby and rails projects
71
+ email: rlister@github
72
+ executables: []
73
+
74
+ extensions: []
75
+
76
+ extra_rdoc_files:
77
+ - LICENSE.txt
78
+ - README.rdoc
79
+ files:
80
+ - .document
81
+ - Gemfile
82
+ - Gemfile.lock
83
+ - LICENSE.txt
84
+ - README.rdoc
85
+ - Rakefile
86
+ - VERSION
87
+ - examples/employees.rb
88
+ - lib/atomics_resource.rb
89
+ - lib/atomics_resource/base.rb
90
+ - test/helper.rb
91
+ - test/spec_atomics_resource.rb
92
+ - test/test_atomics_resource.rb
93
+ homepage: http://github.com/rlister/atomics_resource
94
+ licenses:
95
+ - MIT
96
+ post_install_message:
97
+ rdoc_options: []
98
+
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 1985330703577403544
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: "0"
116
+ requirements: []
117
+
118
+ rubyforge_project:
119
+ rubygems_version: 1.8.5
120
+ signing_key:
121
+ specification_version: 3
122
+ summary: Active Model for Atomics MySQL lookups
123
+ test_files: []
124
+