quandl_client 0.1.17 → 2.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.
- data/README.md +21 -5
- data/UPGRADE.md +4 -0
- data/lib/quandl/client/base/attributes.rb +16 -0
- data/lib/quandl/client/base/model.rb +14 -0
- data/lib/quandl/client/base/search.rb +45 -0
- data/lib/quandl/client/{concerns/properties.rb → base/validation.rb} +9 -31
- data/lib/quandl/client/base.rb +66 -7
- data/lib/quandl/client/models/dataset/data.rb +38 -0
- data/lib/quandl/client/models/dataset.rb +42 -27
- data/lib/quandl/client/models/sheet.rb +2 -6
- data/lib/quandl/client/models/source.rb +4 -7
- data/lib/quandl/client/version.rb +2 -2
- data/lib/quandl/client.rb +15 -7
- data/lib/quandl/her/{patch.rb → remove_method_data.rb} +2 -2
- data/quandl_client.gemspec +2 -2
- data/spec/lib/quandl/client/dataset/data_spec.rb +36 -4
- data/spec/lib/quandl/client/dataset/persistence_spec.rb +7 -7
- data/spec/lib/quandl/client/dataset/search_spec.rb +1 -1
- data/spec/lib/quandl/client/dataset/trim_spec.rb +3 -3
- data/spec/spec_helper.rb +6 -4
- metadata +12 -12
- data/lib/quandl/client/concerns/search.rb +0 -26
- data/lib/quandl/client/concerns.rb +0 -17
- data/lib/quandl/client/her.rb +0 -57
- data/lib/quandl/client/models.rb +0 -25
data/README.md
CHANGED
@@ -32,7 +32,7 @@ Quandl::Client.token = ENV['QUANDL_AUTH_TOKEN']
|
|
32
32
|
|
33
33
|
#### Search
|
34
34
|
|
35
|
-
|
35
|
+
scope :rows, :exclude_data, :exclude_headers, :trim_start, :trim_end, :transform, :collapse
|
36
36
|
|
37
37
|
```ruby
|
38
38
|
|
@@ -52,15 +52,15 @@ attributes :data, :source_code, :code, :name, :urlize_name,
|
|
52
52
|
|
53
53
|
d = Quandl::Client::Dataset.find('OFDP/COBALT_51')
|
54
54
|
d.full_code
|
55
|
-
d.
|
55
|
+
d.data
|
56
56
|
|
57
57
|
|
58
58
|
d = Quandl::Client::Dataset.collapse('weekly').trim_start("2012-03-31").trim_end("2013-06-30").find('OFDP/COBALT_51')
|
59
|
-
d.
|
59
|
+
d.data
|
60
60
|
|
61
61
|
|
62
62
|
d = Quandl::Client::Dataset.exclude_data('true').find('OFDP/COBALT_51')
|
63
|
-
d.
|
63
|
+
d.data
|
64
64
|
|
65
65
|
```
|
66
66
|
|
@@ -95,7 +95,7 @@ d = Dataset.create( attributes )
|
|
95
95
|
|
96
96
|
d = Dataset.find( d.full_code )
|
97
97
|
d.name = 'New Name'
|
98
|
-
d.data = Quandl::Fabricate::Data
|
98
|
+
d.data = Quandl::Fabricate::Data.rand.to_csv
|
99
99
|
d.save
|
100
100
|
|
101
101
|
d = Dataset.collapse(:weekly).find( d.full_code )
|
@@ -118,6 +118,22 @@ Dataset.find('SOME_SOURCE/SOME_CODE')
|
|
118
118
|
```
|
119
119
|
|
120
120
|
|
121
|
+
#### Delete Data
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
|
125
|
+
d = Dataset.find('SOME_SOURCE/SOME_CODE')
|
126
|
+
d.delete_data
|
127
|
+
d.data
|
128
|
+
=> nil
|
129
|
+
|
130
|
+
d.delete_rows( '1998-02-01','1998-03-03' )
|
131
|
+
d.data
|
132
|
+
=> # given rows are deleted
|
133
|
+
|
134
|
+
```
|
135
|
+
|
136
|
+
|
121
137
|
#### Error Handling
|
122
138
|
|
123
139
|
```ruby
|
data/UPGRADE.md
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
class Quandl::Client::Base
|
2
|
+
module Attributes
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def write_attribute(attribute, value)
|
7
|
+
self.send(:"#{attribute}_will_change!") if @attributes[:"#{attribute}"] != value
|
8
|
+
@attributes[:"#{attribute}"] = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def read_attribute(attribute)
|
12
|
+
@attributes[:"#{attribute}"]
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Quandl::Client::Base
|
2
|
+
module Search
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def forwardable_scope_methods
|
8
|
+
@forwardable_scope_methods ||= Array.forwardable_methods.reject{|m| [:find, :fetch].include?(m) }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
included do
|
13
|
+
|
14
|
+
include ScopeComposer::Model
|
15
|
+
|
16
|
+
has_scope_composer
|
17
|
+
|
18
|
+
scope :with_id, ->(value) { where( id: value.to_i )}
|
19
|
+
scope_helper :all, ->{ connection.where(attributes).fetch }
|
20
|
+
scope_helper :connection, -> { self.class.parent }
|
21
|
+
|
22
|
+
scope.class_eval do
|
23
|
+
|
24
|
+
delegate *Array.forwardable_methods.reject{|m| [:find, :fetch].include?(m) }, to: :all
|
25
|
+
|
26
|
+
def fetch_once
|
27
|
+
@fetch_once ||= fetch
|
28
|
+
end
|
29
|
+
|
30
|
+
def fetch
|
31
|
+
find(attributes[:id])
|
32
|
+
end
|
33
|
+
|
34
|
+
def find(id)
|
35
|
+
result = self.class.parent.where(attributes).find(id)
|
36
|
+
result = self.class.parent.new(id: id) if result.nil?
|
37
|
+
result
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -1,18 +1,10 @@
|
|
1
|
-
|
2
|
-
module
|
3
|
-
module Concerns
|
1
|
+
class Quandl::Client::Base
|
2
|
+
module Validation
|
4
3
|
|
5
|
-
module Properties
|
6
4
|
extend ActiveSupport::Concern
|
7
5
|
|
8
6
|
included do
|
9
|
-
|
10
|
-
include Her::Model
|
11
|
-
use_api Client.her_api
|
12
7
|
|
13
|
-
before_save :touch_save_time
|
14
|
-
after_save :log_save_time
|
15
|
-
|
16
8
|
before_save :halt_unless_valid!
|
17
9
|
|
18
10
|
def valid_with_server?
|
@@ -42,6 +34,10 @@ module Properties
|
|
42
34
|
status >= 200 && status <= 210
|
43
35
|
end
|
44
36
|
|
37
|
+
def queried?
|
38
|
+
status > 0
|
39
|
+
end
|
40
|
+
|
45
41
|
def status
|
46
42
|
metadata[:status].to_i
|
47
43
|
end
|
@@ -69,30 +65,12 @@ module Properties
|
|
69
65
|
response_errors.present? ? { response_errors: response_errors } : {}
|
70
66
|
end
|
71
67
|
|
72
|
-
|
73
68
|
protected
|
74
69
|
|
75
70
|
def halt_unless_valid!
|
76
71
|
return false unless valid?
|
77
72
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
def save_timer
|
82
|
-
@save_timer
|
83
|
-
end
|
84
|
-
|
85
|
-
def touch_save_time
|
86
|
-
@save_timer = Time.now
|
87
|
-
end
|
88
|
-
|
89
|
-
def log_save_time
|
90
|
-
Quandl::Logger.info("#{self.class.name}.save (#{save_timer.elapsed_ms})")
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
97
|
-
end
|
73
|
+
|
74
|
+
end
|
98
75
|
end
|
76
|
+
end
|
data/lib/quandl/client/base.rb
CHANGED
@@ -1,12 +1,71 @@
|
|
1
|
-
require
|
2
|
-
require "
|
1
|
+
require "active_support"
|
2
|
+
require "active_support/inflector"
|
3
|
+
require "active_support/core_ext/hash"
|
4
|
+
require "active_support/core_ext/object"
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
+
require 'quandl/client/base/model'
|
7
|
+
require 'quandl/client/base/attributes'
|
8
|
+
require 'quandl/client/base/validation'
|
9
|
+
require 'quandl/client/base/search'
|
6
10
|
|
7
|
-
class Base
|
11
|
+
class Quandl::Client::Base
|
8
12
|
|
9
|
-
|
13
|
+
class << self
|
14
|
+
|
15
|
+
attr_accessor :url, :token
|
16
|
+
|
17
|
+
def use(url)
|
18
|
+
self.url = File.join( url, Quandl::Client.api_version )
|
19
|
+
models_use_her_api!
|
20
|
+
end
|
21
|
+
|
22
|
+
def token=(token)
|
23
|
+
@token = token
|
24
|
+
models_use_her_api!
|
25
|
+
end
|
26
|
+
|
27
|
+
def her_api
|
28
|
+
Her::API.new.setup url: url do |c|
|
29
|
+
c.use TokenAuthentication
|
30
|
+
c.use Faraday::Request::UrlEncoded
|
31
|
+
c.use Quandl::Client::Middleware::ParseJSON
|
32
|
+
c.use Faraday::Adapter::NetHttp
|
33
|
+
end
|
34
|
+
end
|
10
35
|
|
11
|
-
|
36
|
+
def url
|
37
|
+
@url ||= "http://localhost:3000/api/"
|
38
|
+
end
|
39
|
+
|
40
|
+
def inherited(subclass)
|
41
|
+
# remember models that inherit from base
|
42
|
+
models << subclass unless models.include?(subclass)
|
43
|
+
# include model behaviour
|
44
|
+
subclass.class_eval do
|
45
|
+
include Quandl::Client::Base::Model
|
46
|
+
include Quandl::Client::Base::Attributes
|
47
|
+
include Quandl::Client::Base::Validation
|
48
|
+
include Quandl::Client::Base::Search
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def models
|
53
|
+
@@models ||= []
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
|
58
|
+
def models_use_her_api!
|
59
|
+
models.each{|m| m.use_api( her_api ) }
|
60
|
+
end
|
61
|
+
|
62
|
+
class TokenAuthentication < Faraday::Middleware
|
63
|
+
def call(env)
|
64
|
+
env[:request_headers]["X-API-Token"] = Quandl::Client::Base.token if Quandl::Client::Base.token.present?
|
65
|
+
@app.call(env)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
12
71
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Quandl::Client::Dataset::Data < Quandl::Client::Base
|
2
|
+
|
3
|
+
@_her_resource_path = "datasets/:id/data"
|
4
|
+
|
5
|
+
has_scope_composer
|
6
|
+
|
7
|
+
scope *[:row, :rows, :limit, :offset, :accuracy, :column, :order,
|
8
|
+
:trim_start, :trim_end, :transform, :collapse, :exclude_headers]
|
9
|
+
|
10
|
+
scope_helper :to_table, -> { fetch_once.data }
|
11
|
+
|
12
|
+
scope.class_eval do
|
13
|
+
delegate *Quandl::Client::Dataset::Data.forwardable_scope_methods, :to_h, to: :to_table, allow_nil: true
|
14
|
+
delegate *Quandl::Data.forwardable_methods, to: :to_table, allow_nil: true
|
15
|
+
end
|
16
|
+
|
17
|
+
attributes :id, :limit, :collapse, :transformation, :trim_start, :trim_end,
|
18
|
+
:rows, :row, :frequency, :data, :from_date, :to_date
|
19
|
+
|
20
|
+
def data
|
21
|
+
read_data
|
22
|
+
end
|
23
|
+
|
24
|
+
def data=(value)
|
25
|
+
write_data(value)
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def read_data
|
31
|
+
Quandl::Data.new( read_attribute(:data) )
|
32
|
+
end
|
33
|
+
|
34
|
+
def write_data(value )
|
35
|
+
write_attribute(:data, Quandl::Data.new(value).to_csv )
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -1,27 +1,15 @@
|
|
1
|
-
|
2
|
-
module Client
|
3
|
-
|
4
|
-
class Dataset
|
5
|
-
|
6
|
-
include Concerns::Search
|
7
|
-
include Concerns::Properties
|
1
|
+
class Quandl::Client::Dataset < Quandl::Client::Base
|
8
2
|
|
3
|
+
require 'quandl/client/models/dataset/data'
|
9
4
|
|
10
5
|
##########
|
11
6
|
# SCOPES #
|
12
7
|
##########
|
13
8
|
|
14
9
|
# SEARCH
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
# SHOW
|
20
|
-
scope_composer_for :show
|
21
|
-
show_scope :rows, :exclude_data, :exclude_headers, :trim_start, :trim_end, :transform, :collapse
|
22
|
-
show_helper :find, ->(id){ connection.where(attributes).find( id ) }
|
23
|
-
show_helper :connection, -> { self.class.parent }
|
24
|
-
|
10
|
+
scope :query, :rows
|
11
|
+
scope :page, ->(p){ where( page: p.to_i )}
|
12
|
+
scope :source_code, ->(c){ where( code: c.to_s.upcase )}
|
25
13
|
|
26
14
|
###############
|
27
15
|
# ASSOCIATIONS #
|
@@ -31,7 +19,6 @@ class Dataset
|
|
31
19
|
@source ||= Source.find(self.source_code)
|
32
20
|
end
|
33
21
|
|
34
|
-
|
35
22
|
###############
|
36
23
|
# VALIDATIONS #
|
37
24
|
###############
|
@@ -48,7 +35,7 @@ class Dataset
|
|
48
35
|
:description, :updated_at, :frequency,
|
49
36
|
:from_date, :to_date, :column_names, :private, :type,
|
50
37
|
:display_url, :column_spec, :import_spec, :import_url,
|
51
|
-
:locations_attributes, :
|
38
|
+
:locations_attributes, :availability_delay, :refreshed_at
|
52
39
|
|
53
40
|
before_save :enforce_required_formats
|
54
41
|
|
@@ -58,23 +45,51 @@ class Dataset
|
|
58
45
|
def full_code
|
59
46
|
@full_code ||= File.join(self.source_code, self.code)
|
60
47
|
end
|
48
|
+
|
49
|
+
# DATA
|
50
|
+
|
51
|
+
def data
|
52
|
+
dataset_data.data? ? dataset_data.data : Dataset::Data.with_id(id)
|
53
|
+
end
|
54
|
+
|
55
|
+
def data=(value)
|
56
|
+
dataset_data.data = value
|
57
|
+
end
|
58
|
+
|
59
|
+
def delete_data
|
60
|
+
# cant delete unsaved records
|
61
|
+
return false if new_record?
|
62
|
+
# delete and return success / failure
|
63
|
+
self.class.destroy_existing("#{id}/data").saved?
|
64
|
+
end
|
61
65
|
|
62
|
-
def
|
63
|
-
|
66
|
+
def delete_rows(*dates)
|
67
|
+
# cant delete unsaved records
|
68
|
+
return false if new_record?
|
69
|
+
# collect dates
|
70
|
+
query = { dates: Array(dates).flatten }.to_query
|
71
|
+
# delete and return success / failure
|
72
|
+
self.class.destroy_existing("#{id}/data/rows?#{query}").saved?
|
64
73
|
end
|
65
74
|
|
66
|
-
def
|
67
|
-
@
|
75
|
+
def dataset_data
|
76
|
+
@dataset_data ||= Dataset::Data.new( id: id )
|
68
77
|
end
|
69
78
|
|
79
|
+
after_save :save_dataset_data
|
80
|
+
|
70
81
|
protected
|
71
82
|
|
83
|
+
def save_dataset_data
|
84
|
+
dataset_data.id = id
|
85
|
+
dataset_data.save
|
86
|
+
# update dataset's attributes with dataset_data's attributes
|
87
|
+
attributes.each{|k,v| attributes[k] = dataset_data.attributes[k] if dataset_data.attributes.has_key?(k) }
|
88
|
+
end
|
89
|
+
|
72
90
|
def enforce_required_formats
|
73
|
-
self.data = Quandl::Data
|
91
|
+
# self.data = Quandl::Data.new(data).to_csv
|
74
92
|
self.locations_attributes = locations_attributes.to_json if locations_attributes.respond_to?(:to_json) && !locations_attributes.kind_of?(String)
|
75
93
|
end
|
76
94
|
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
95
|
end
|
@@ -1,17 +1,13 @@
|
|
1
1
|
module Quandl
|
2
2
|
module Client
|
3
3
|
|
4
|
-
class Sheet
|
5
|
-
|
6
|
-
include Concerns::Search
|
7
|
-
include Concerns::Properties
|
8
|
-
|
4
|
+
class Sheet < Quandl::Client::Base
|
9
5
|
|
10
6
|
##########
|
11
7
|
# SCOPES #
|
12
8
|
##########
|
13
9
|
|
14
|
-
|
10
|
+
scope :query, :page, :parent_url_title
|
15
11
|
|
16
12
|
|
17
13
|
################
|
@@ -1,18 +1,15 @@
|
|
1
1
|
module Quandl
|
2
2
|
module Client
|
3
3
|
|
4
|
-
class Source
|
5
|
-
|
6
|
-
include Concerns::Search
|
7
|
-
include Concerns::Properties
|
4
|
+
class Source < Quandl::Client::Base
|
8
5
|
|
9
6
|
##########
|
10
7
|
# SCOPES #
|
11
8
|
##########
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
scope :query
|
11
|
+
scope :page, ->(p){ where( page: p.to_i )}
|
12
|
+
scope :code, ->(c){ where( code: c.to_s.upcase )}
|
16
13
|
|
17
14
|
|
18
15
|
###############
|
data/lib/quandl/client.rb
CHANGED
@@ -1,17 +1,25 @@
|
|
1
1
|
require "quandl/client/version"
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require 'scope_composer'
|
4
|
+
require 'her'
|
5
|
+
require 'quandl/her/remove_method_data'
|
6
|
+
require 'quandl/logger'
|
7
|
+
require "quandl/data"
|
7
8
|
|
8
9
|
require 'quandl/client/middleware'
|
9
|
-
require 'quandl/client/her'
|
10
|
-
require 'quandl/client/concerns'
|
11
10
|
require 'quandl/client/base'
|
12
|
-
require 'quandl/client/models'
|
11
|
+
require 'quandl/client/models/dataset'
|
12
|
+
require 'quandl/client/models/sheet'
|
13
|
+
require 'quandl/client/models/source'
|
13
14
|
|
14
15
|
module Quandl
|
15
16
|
module Client
|
17
|
+
def self.use(url)
|
18
|
+
Quandl::Client::Base.use(url)
|
19
|
+
end
|
20
|
+
def self.token=(value)
|
21
|
+
Quandl::Client::Base.token = value
|
22
|
+
end
|
23
|
+
|
16
24
|
end
|
17
25
|
end
|
@@ -4,8 +4,8 @@ module Her
|
|
4
4
|
module Model
|
5
5
|
# remove deprecated data method since cassinatra returns data: []
|
6
6
|
module DeprecatedMethods
|
7
|
-
remove_method :data
|
8
|
-
remove_method :data=
|
7
|
+
remove_method( :data ) if method_defined?( :data )
|
8
|
+
remove_method( :data= ) if method_defined?( :data= )
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
data/quandl_client.gemspec
CHANGED
@@ -28,9 +28,9 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.add_runtime_dependency "yajl-ruby", "~> 1.1.0"
|
29
29
|
s.add_runtime_dependency 'json', '~> 1.7.7'
|
30
30
|
|
31
|
-
s.add_runtime_dependency "scope_composer", "~> 0.
|
31
|
+
s.add_runtime_dependency "scope_composer", "~> 0.3"
|
32
32
|
s.add_runtime_dependency "quandl_logger", "~> 0.1"
|
33
33
|
s.add_runtime_dependency "quandl_operation", "~> 0.1"
|
34
|
-
s.add_runtime_dependency "quandl_data", "~> 0
|
34
|
+
s.add_runtime_dependency "quandl_data", "~> 1.0"
|
35
35
|
|
36
36
|
end
|
@@ -4,12 +4,13 @@ require 'spec_helper'
|
|
4
4
|
describe Dataset do
|
5
5
|
|
6
6
|
let(:dataset){
|
7
|
-
create(:dataset, source_code: "QUANDL_CLIENT_TEST_SOURCE", data: Quandl::Fabricate::Data
|
7
|
+
create(:dataset, source_code: "QUANDL_CLIENT_TEST_SOURCE", data: Quandl::Fabricate::Data.rand( rows: 10, columns: 4 ) )
|
8
8
|
}
|
9
9
|
|
10
10
|
describe "#data" do
|
11
11
|
subject{ Dataset.find( dataset.id ).data }
|
12
12
|
its(:count){ should eq 10 }
|
13
|
+
its(:to_h){ should be_a Hash }
|
13
14
|
end
|
14
15
|
|
15
16
|
context "updated" do
|
@@ -20,19 +21,50 @@ describe Dataset do
|
|
20
21
|
}
|
21
22
|
|
22
23
|
describe "#data" do
|
23
|
-
before(:each){ subject.data = Quandl::Fabricate::Data
|
24
|
+
before(:each){ subject.data = Quandl::Fabricate::Data.rand( rows: 12, columns: 4 ); sleep(1); subject.save }
|
24
25
|
its(:updated_at){ should_not eq dataset.updated_at }
|
25
26
|
its(:data){ should_not eq dataset.data }
|
26
27
|
its(:refreshed_at){ should_not eq dataset.refreshed_at }
|
27
28
|
end
|
28
29
|
|
29
30
|
context "#column_spec" do
|
30
|
-
before(:each){ subject.column_spec = "[0,[\"Date \\n\",{}],[\"Column 1 \",{}],[\"New Column Name \",{}]]"; subject.save }
|
31
|
+
before(:each){ subject.column_spec = "[0,[\"Date \\n\",{}],[\"Column 1 \",{}],[\"New Column Name \",{}]]"; sleep(1); subject.save }
|
31
32
|
its(:updated_at){ should_not eq dataset.updated_at }
|
32
33
|
its(:column_spec){ should_not eq dataset.column_spec }
|
33
34
|
end
|
34
35
|
|
35
36
|
end
|
36
37
|
|
37
|
-
|
38
|
+
describe "#delete_data" do
|
39
|
+
subject{ Dataset.find( dataset.id ) }
|
40
|
+
before(:each){ subject.delete_data }
|
41
|
+
its(:data){ should be_blank }
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#delete_rows" do
|
45
|
+
subject{ Dataset.find( dataset.id ) }
|
46
|
+
|
47
|
+
let(:dates_slice){ dataset.data.to_h.keys[5..8] }
|
48
|
+
|
49
|
+
it "should have the dates" do
|
50
|
+
dates = Dataset.find( dataset.id ).data.to_h.keys
|
51
|
+
dates_slice.each{|date| dates.include?(date).should be_true }
|
52
|
+
end
|
53
|
+
|
54
|
+
context "after deleting rows" do
|
55
|
+
|
56
|
+
before(:each){ subject.delete_rows(dates_slice) }
|
57
|
+
|
58
|
+
it "data count should be 16" do
|
59
|
+
Dataset.find( dataset.id ).data.count.should eq 6
|
60
|
+
end
|
61
|
+
|
62
|
+
it "data should have dates" do
|
63
|
+
dates = Dataset.find( dataset.id ).data.to_h
|
64
|
+
dates.each{|date| dates_slice.include?(date).should be_false }
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
38
70
|
end
|
@@ -31,7 +31,7 @@ describe Dataset do
|
|
31
31
|
end
|
32
32
|
context "with data" do
|
33
33
|
|
34
|
-
let(:dataset){ create(:dataset, source_code: "QUANDL_CLIENT_TEST_SOURCE", data: Quandl::Fabricate::Data
|
34
|
+
let(:dataset){ create(:dataset, source_code: "QUANDL_CLIENT_TEST_SOURCE", data: Quandl::Fabricate::Data.rand(rows: 20, columns: 2, nils: false) ) }
|
35
35
|
subject{ dataset }
|
36
36
|
|
37
37
|
its(:saved?){ should be_true }
|
@@ -42,25 +42,25 @@ describe Dataset do
|
|
42
42
|
|
43
43
|
context "when updated" do
|
44
44
|
|
45
|
-
let(:dataset){ create(:dataset, source_code: "QUANDL_CLIENT_TEST_SOURCE", data: Quandl::Fabricate::Data
|
45
|
+
let(:dataset){ create(:dataset, source_code: "QUANDL_CLIENT_TEST_SOURCE", data: Quandl::Fabricate::Data.rand(rows: 20, columns: 2, nils: false).to_csv ) }
|
46
46
|
subject{ Dataset.find(dataset.id) }
|
47
47
|
|
48
48
|
it "should include new row" do
|
49
49
|
new_data = 10.times.collect{|i| [Date.parse(subject.to_date) + i + 1, rand(12), rand(12) ] }
|
50
|
-
new_data = Quandl::Data
|
50
|
+
new_data = Quandl::Data.new(new_data).sort_descending
|
51
51
|
subject.data = new_data
|
52
52
|
subject.save
|
53
53
|
updated_dataset = Dataset.find(subject.id)
|
54
|
-
updated_dataset.
|
54
|
+
updated_dataset.data.to_date[0].should eq new_data.to_date[0]
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should include old rows" do
|
58
58
|
new_data = 10.times.collect{|i| [Date.parse(subject.to_date) + i + 2, rand(12), rand(12) ] }
|
59
|
-
new_data = Quandl::Data
|
59
|
+
new_data = Quandl::Data.new(new_data).sort_descending
|
60
60
|
subject.data = new_data
|
61
61
|
subject.save
|
62
62
|
updated_dataset = Dataset.find(subject.id)
|
63
|
-
updated_dataset.
|
63
|
+
updated_dataset.data.count.should eq 30
|
64
64
|
end
|
65
65
|
|
66
66
|
end
|
@@ -75,7 +75,7 @@ describe Dataset do
|
|
75
75
|
end
|
76
76
|
|
77
77
|
context "as a user" do
|
78
|
-
|
78
|
+
|
79
79
|
it "should not delete the dataset with a user token" do
|
80
80
|
id = dataset.id
|
81
81
|
# behave as a user
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe Dataset do
|
5
5
|
|
6
|
-
subject{ build(:dataset, source_code: "QUANDL_CLIENT_TEST_SOURCE", data: Quandl::Fabricate::Data
|
6
|
+
subject{ build(:dataset, source_code: "QUANDL_CLIENT_TEST_SOURCE", data: Quandl::Fabricate::Data.rand(rows: 20, columns: 2) ) }
|
7
7
|
|
8
8
|
describe "#from_date" do
|
9
9
|
context "before_save" do
|
@@ -14,7 +14,7 @@ describe Dataset do
|
|
14
14
|
context "after_save" do
|
15
15
|
before(:each){ subject.save }
|
16
16
|
it "should equal the last date" do
|
17
|
-
subject.from_date.should eq subject.
|
17
|
+
subject.from_date.should eq subject.data.to_date[-1][0].to_s
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -28,7 +28,7 @@ describe Dataset do
|
|
28
28
|
context "after_save" do
|
29
29
|
before(:each){ subject.save }
|
30
30
|
it "should equal the first date" do
|
31
|
-
subject.to_date.should eq subject.
|
31
|
+
subject.to_date.should eq subject.data.to_date[0][0].to_s
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -11,11 +11,13 @@ require "quandl/client"
|
|
11
11
|
require "quandl/fabricate"
|
12
12
|
|
13
13
|
include Quandl::Client
|
14
|
-
Quandl::Client.use '
|
15
|
-
|
16
|
-
|
14
|
+
Quandl::Client.use ENV['QUANDL_API_HOST']
|
15
|
+
Quandl::Client.use 'http://staging.quandl.com/api/'
|
16
|
+
|
17
17
|
Quandl::Client.token = ENV['QUANDL_AUTH_TOKEN']
|
18
18
|
|
19
19
|
RSpec.configure do |config|
|
20
20
|
config.include FactoryGirl::Syntax::Methods
|
21
|
-
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# binding.pry
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quandl_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-10-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -162,7 +162,7 @@ dependencies:
|
|
162
162
|
requirements:
|
163
163
|
- - ~>
|
164
164
|
- !ruby/object:Gem::Version
|
165
|
-
version: '0.
|
165
|
+
version: '0.3'
|
166
166
|
type: :runtime
|
167
167
|
prerelease: false
|
168
168
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -170,7 +170,7 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - ~>
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: '0.
|
173
|
+
version: '0.3'
|
174
174
|
- !ruby/object:Gem::Dependency
|
175
175
|
name: quandl_logger
|
176
176
|
requirement: !ruby/object:Gem::Requirement
|
@@ -210,7 +210,7 @@ dependencies:
|
|
210
210
|
requirements:
|
211
211
|
- - ~>
|
212
212
|
- !ruby/object:Gem::Version
|
213
|
-
version: '0
|
213
|
+
version: '1.0'
|
214
214
|
type: :runtime
|
215
215
|
prerelease: false
|
216
216
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -218,7 +218,7 @@ dependencies:
|
|
218
218
|
requirements:
|
219
219
|
- - ~>
|
220
220
|
- !ruby/object:Gem::Version
|
221
|
-
version: '0
|
221
|
+
version: '1.0'
|
222
222
|
description: An orm for the cassinatra rest interface.
|
223
223
|
email:
|
224
224
|
- blake@hilscher.ca
|
@@ -237,18 +237,18 @@ files:
|
|
237
237
|
- UPGRADE.md
|
238
238
|
- lib/quandl/client.rb
|
239
239
|
- lib/quandl/client/base.rb
|
240
|
-
- lib/quandl/client/
|
241
|
-
- lib/quandl/client/
|
242
|
-
- lib/quandl/client/
|
243
|
-
- lib/quandl/client/
|
240
|
+
- lib/quandl/client/base/attributes.rb
|
241
|
+
- lib/quandl/client/base/model.rb
|
242
|
+
- lib/quandl/client/base/search.rb
|
243
|
+
- lib/quandl/client/base/validation.rb
|
244
244
|
- lib/quandl/client/middleware.rb
|
245
245
|
- lib/quandl/client/middleware/parse_json.rb
|
246
|
-
- lib/quandl/client/models.rb
|
247
246
|
- lib/quandl/client/models/dataset.rb
|
247
|
+
- lib/quandl/client/models/dataset/data.rb
|
248
248
|
- lib/quandl/client/models/sheet.rb
|
249
249
|
- lib/quandl/client/models/source.rb
|
250
250
|
- lib/quandl/client/version.rb
|
251
|
-
- lib/quandl/her/
|
251
|
+
- lib/quandl/her/remove_method_data.rb
|
252
252
|
- quandl_client.gemspec
|
253
253
|
- spec/factories/dataset.rb
|
254
254
|
- spec/factories/sheet.rb
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Quandl
|
2
|
-
module Client
|
3
|
-
module Concerns
|
4
|
-
|
5
|
-
module Search
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
included do
|
9
|
-
|
10
|
-
include ScopeComposer::Model
|
11
|
-
|
12
|
-
scope_composer_for :search
|
13
|
-
|
14
|
-
search_helper :all, ->{ connection.where(attributes).fetch }
|
15
|
-
search_helper :connection, -> { self.class.parent }
|
16
|
-
|
17
|
-
search_scope.class_eval do
|
18
|
-
delegate *Array.forwardable_methods, to: :all
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require "active_support"
|
2
|
-
require "active_support/inflector"
|
3
|
-
require "active_support/core_ext/hash"
|
4
|
-
require "active_support/core_ext/object"
|
5
|
-
|
6
|
-
require 'quandl/client/concerns/search'
|
7
|
-
require 'quandl/client/concerns/properties'
|
8
|
-
|
9
|
-
module Quandl
|
10
|
-
module Client
|
11
|
-
|
12
|
-
module Concerns
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
data/lib/quandl/client/her.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'her'
|
2
|
-
require 'quandl/her/patch'
|
3
|
-
|
4
|
-
module Quandl
|
5
|
-
module Client
|
6
|
-
class << self
|
7
|
-
|
8
|
-
def use(url)
|
9
|
-
self.rest_url = url
|
10
|
-
end
|
11
|
-
|
12
|
-
def token
|
13
|
-
@token
|
14
|
-
end
|
15
|
-
def token=(token)
|
16
|
-
@token = token
|
17
|
-
reload_models
|
18
|
-
end
|
19
|
-
|
20
|
-
def her_api
|
21
|
-
# setup api
|
22
|
-
api = Her::API.new
|
23
|
-
api.setup url: rest_url do |c|
|
24
|
-
c.use TokenAuthentication
|
25
|
-
c.use Faraday::Request::UrlEncoded
|
26
|
-
# c.use Her::Middleware::DefaultParseJSON
|
27
|
-
c.use Quandl::Client::Middleware::ParseJSON
|
28
|
-
c.use Faraday::Adapter::NetHttp
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def rest_url
|
33
|
-
@rest_url ||= "http://localhost:3000/api/#{API_VERSION}/"
|
34
|
-
end
|
35
|
-
|
36
|
-
def rest_url=(url)
|
37
|
-
url = "http://#{url}" if ( url =~ /^http:\/\// ) == nil
|
38
|
-
url = File.join(url, "#{API_VERSION}/")
|
39
|
-
@rest_url = url
|
40
|
-
reload_models
|
41
|
-
@rest_url
|
42
|
-
end
|
43
|
-
|
44
|
-
def reload_models
|
45
|
-
Models.use_api( her_api )
|
46
|
-
end
|
47
|
-
|
48
|
-
class TokenAuthentication < Faraday::Middleware
|
49
|
-
def call(env)
|
50
|
-
env[:request_headers]["X-API-Token"] = Quandl::Client.token if Quandl::Client.token.present?
|
51
|
-
@app.call(env)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/lib/quandl/client/models.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'quandl/client/models/source'
|
2
|
-
require 'quandl/client/models/dataset'
|
3
|
-
require 'quandl/client/models/sheet'
|
4
|
-
|
5
|
-
module Quandl
|
6
|
-
module Client
|
7
|
-
module Models
|
8
|
-
class << self
|
9
|
-
|
10
|
-
def use_api(api)
|
11
|
-
each{|k| k.use_api(api) }
|
12
|
-
end
|
13
|
-
|
14
|
-
def each(&block)
|
15
|
-
types.each{|k| block.call(k) }
|
16
|
-
end
|
17
|
-
|
18
|
-
def types
|
19
|
-
[Source, Dataset, Sheet]
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|