quandl_client 0.1.17 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|