quandl_cassinatra 0.2.2 → 0.2.3
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 +8 -8
- data/UPGRADE.md +10 -0
- data/lib/quandl/cassinatra.rb +9 -15
- data/lib/quandl/cassinatra/base.rb +58 -0
- data/lib/quandl/cassinatra/base/attributes.rb +51 -0
- data/lib/quandl/cassinatra/base/model.rb +14 -0
- data/lib/quandl/cassinatra/base/search.rb +96 -0
- data/lib/quandl/cassinatra/{concerns/properties.rb → base/validation.rb} +9 -31
- data/lib/quandl/cassinatra/models/dataset.rb +33 -0
- data/lib/quandl/cassinatra/models/dataset/attributes.rb +61 -0
- data/lib/quandl/cassinatra/models/dataset/searchable.rb +68 -0
- data/lib/quandl/cassinatra/models/multiset.rb +27 -0
- data/lib/quandl/cassinatra/version.rb +1 -1
- data/lib/quandl/her/remove_method_data.rb +11 -0
- data/spec/factories/dataset.rb +1 -1
- data/spec/quandl/cassinatra/dataset/attributes_spec.rb +27 -0
- data/spec/quandl/cassinatra/dataset/delete_spec.rb +2 -2
- data/spec/quandl/cassinatra/dataset/persistence_spec.rb +26 -25
- data/spec/quandl/cassinatra/dataset/trim_spec.rb +2 -2
- data/spec/quandl/cassinatra/multiset_spec.rb +23 -14
- data/spec/spec_helper.rb +3 -1
- metadata +14 -14
- data/lib/quandl/cassinatra/concerns.rb +0 -17
- data/lib/quandl/cassinatra/concerns/search.rb +0 -26
- data/lib/quandl/cassinatra/core_ext.rb +0 -1
- data/lib/quandl/cassinatra/core_ext/string.rb +0 -8
- data/lib/quandl/cassinatra/her.rb +0 -32
- data/lib/quandl/cassinatra/model.rb +0 -27
- data/lib/quandl/cassinatra/model/dataset.rb +0 -56
- data/lib/quandl/cassinatra/model/dataset/searchable.rb +0 -96
- data/lib/quandl/cassinatra/model/dataset_attribute.rb +0 -13
- data/lib/quandl/cassinatra/model/multiset.rb +0 -36
- data/lib/quandl/her/patch.rb +0 -30
data/README.md
CHANGED
@@ -11,7 +11,7 @@ include Quandl::Cassinatra
|
|
11
11
|
```
|
12
12
|
|
13
13
|
|
14
|
-
### Quandl::Cassinatra::
|
14
|
+
### Quandl::Cassinatra::Dataset
|
15
15
|
|
16
16
|
#### Find / Scope
|
17
17
|
|
@@ -19,8 +19,8 @@ include Quandl::Cassinatra
|
|
19
19
|
|
20
20
|
require 'quandl/cassinatra'
|
21
21
|
|
22
|
-
d = Quandl::Cassinatra::
|
23
|
-
d.
|
22
|
+
d = Quandl::Cassinatra::Dataset.limit(10).transform(:rdiff).collapse(:weekly).find(293)
|
23
|
+
d.data
|
24
24
|
=> [...]
|
25
25
|
|
26
26
|
d.column_ids
|
@@ -41,25 +41,25 @@ d.updated_at
|
|
41
41
|
|
42
42
|
require 'quandl/cassinatra'
|
43
43
|
|
44
|
-
d = Quandl::Cassinatra::
|
44
|
+
d = Quandl::Cassinatra::Dataset.new
|
45
45
|
d.id = 5893853
|
46
46
|
d.data = Quandl::Fabricate::Data::Table.rand(rows: 10, columns: 4, nils: false).to_csv
|
47
47
|
d.save
|
48
48
|
|
49
|
-
d = Quandl::Cassinatra::
|
50
|
-
d.
|
49
|
+
d = Quandl::Cassinatra::Dataset.find(5893853)
|
50
|
+
d.data
|
51
51
|
=> [...]
|
52
52
|
|
53
53
|
```
|
54
54
|
|
55
55
|
|
56
|
-
### Quandl::Cassinatra::
|
56
|
+
### Quandl::Cassinatra::Multiset
|
57
57
|
|
58
58
|
```ruby
|
59
59
|
|
60
60
|
require 'quandl/cassinatra'
|
61
61
|
|
62
|
-
m = Quandl::Cassinatra::
|
62
|
+
m = Quandl::Cassinatra::Multiset.with_columns('5893853.1,293.2').limit(10).collapse(:monthly)
|
63
63
|
m.data
|
64
64
|
=> [...]
|
65
65
|
|
data/UPGRADE.md
CHANGED
data/lib/quandl/cassinatra.rb
CHANGED
@@ -1,26 +1,20 @@
|
|
1
1
|
require "quandl/cassinatra/version"
|
2
2
|
|
3
|
-
require 'quandl/logger'
|
4
|
-
|
5
|
-
require "active_support"
|
6
|
-
require "active_support/inflector"
|
7
|
-
require "active_support/core_ext/hash"
|
8
|
-
require "active_support/core_ext/object"
|
9
|
-
|
10
|
-
require 'her'
|
11
|
-
require 'quandl/her/patch'
|
12
3
|
require 'scope_composer'
|
4
|
+
require 'her'
|
5
|
+
require 'quandl/her/remove_method_data'
|
6
|
+
require 'quandl/logger'
|
13
7
|
require "quandl/data"
|
14
8
|
|
15
|
-
require "quandl/cassinatra/core_ext"
|
16
9
|
require 'quandl/cassinatra/middleware'
|
17
|
-
|
18
|
-
require 'quandl/cassinatra/
|
19
|
-
require 'quandl/cassinatra/
|
20
|
-
require 'quandl/cassinatra/model'
|
10
|
+
require 'quandl/cassinatra/base'
|
11
|
+
require 'quandl/cassinatra/models/dataset'
|
12
|
+
require 'quandl/cassinatra/models/multiset'
|
21
13
|
|
22
14
|
module Quandl
|
23
15
|
module Cassinatra
|
24
|
-
|
16
|
+
def self.use(url)
|
17
|
+
Quandl::Cassinatra::Base.use(url)
|
18
|
+
end
|
25
19
|
end
|
26
20
|
end
|
@@ -0,0 +1,58 @@
|
|
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/cassinatra/base/model'
|
7
|
+
require 'quandl/cassinatra/base/attributes'
|
8
|
+
require 'quandl/cassinatra/base/validation'
|
9
|
+
require 'quandl/cassinatra/base/search'
|
10
|
+
|
11
|
+
class Quandl::Cassinatra::Base
|
12
|
+
|
13
|
+
class << self
|
14
|
+
|
15
|
+
attr_accessor :url
|
16
|
+
|
17
|
+
def use(url)
|
18
|
+
self.url = url
|
19
|
+
models_use_her_api!
|
20
|
+
end
|
21
|
+
|
22
|
+
def her_api
|
23
|
+
Her::API.new.setup url: url do |c|
|
24
|
+
c.use Faraday::Request::UrlEncoded
|
25
|
+
c.use Quandl::Cassinatra::Middleware::ParseJSON
|
26
|
+
c.use Faraday::Adapter::NetHttp
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def url
|
31
|
+
@url ||= 'http://localhost:9292/'
|
32
|
+
end
|
33
|
+
|
34
|
+
def inherited(subclass)
|
35
|
+
# remember models that inherit from base
|
36
|
+
models << subclass unless models.include?(subclass)
|
37
|
+
# include model behaviour
|
38
|
+
subclass.class_eval do
|
39
|
+
include Quandl::Cassinatra::Base::Model
|
40
|
+
include Quandl::Cassinatra::Base::Attributes
|
41
|
+
include Quandl::Cassinatra::Base::Validation
|
42
|
+
include Quandl::Cassinatra::Base::Search
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def models
|
47
|
+
@@models ||= []
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def models_use_her_api!
|
53
|
+
models.each{|m| m.use_api( her_api ) }
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Quandl::Cassinatra::Base
|
2
|
+
module Attributes
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
def find_existing(id)
|
9
|
+
self.new(id: id)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
"#{self.class.name} " + attributes.inspect
|
16
|
+
end
|
17
|
+
|
18
|
+
def imprint(record)
|
19
|
+
# ensure matching classes
|
20
|
+
raise(ArgumentError, "record must be kind_of?(#{self.class})") unless record.kind_of?( self.class )
|
21
|
+
# copy variables
|
22
|
+
copy_instance_variables(record)
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def copy_instance_variables(record)
|
28
|
+
# copy attributes if record was found
|
29
|
+
@attributes = record.attributes if record.exists?
|
30
|
+
# copy metadata and errors
|
31
|
+
[:metadata, :response_errors].each do |ivar|
|
32
|
+
self.instance_variable_set("@#{ivar}", record.instance_variable_get("@#{ivar}") )
|
33
|
+
end
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def write_attributes(hash)
|
38
|
+
@attributes = hash
|
39
|
+
end
|
40
|
+
|
41
|
+
def write_attribute(attribute, value)
|
42
|
+
self.send(:"#{attribute}_will_change!") if @attributes[:"#{attribute}"] != value
|
43
|
+
@attributes[:"#{attribute}"] = value
|
44
|
+
end
|
45
|
+
|
46
|
+
def read_attribute(attribute)
|
47
|
+
@attributes[:"#{attribute}"]
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
class Quandl::Cassinatra::Base
|
2
|
+
module Search
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
|
8
|
+
include ScopeComposer::Model
|
9
|
+
|
10
|
+
has_scope_composer
|
11
|
+
|
12
|
+
scope.class_eval do
|
13
|
+
|
14
|
+
def fetch_once
|
15
|
+
@fetch_once ||= fetch
|
16
|
+
end
|
17
|
+
|
18
|
+
def fetch
|
19
|
+
result = find(attributes[:id])
|
20
|
+
result = references.imprint( result ) unless references.nil?
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def find(id)
|
25
|
+
begin
|
26
|
+
t1 = Time.now
|
27
|
+
result = self.class.parent.where(attributes).find(id)
|
28
|
+
Quandl::Logger.debug "#{self.class.name}.where(#{attributes.to_param if attributes.respond_to?(:to_param)}).find(#{id}) (#{t1.elapsed_ms})"
|
29
|
+
rescue => error
|
30
|
+
Quandl::Logger.error "#{self.class.name}.find #{error}"
|
31
|
+
end
|
32
|
+
result = self.class.parent.new(id: id) if result.nil?
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
def references(*args)
|
37
|
+
return @references if args.first.nil?
|
38
|
+
@references = args.first
|
39
|
+
attributes[:id] = @references.id
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
def format_trim_date(date, start_or_end)
|
46
|
+
# parse
|
47
|
+
date = parse_date(date)
|
48
|
+
# format
|
49
|
+
if date.is_a?(Date)
|
50
|
+
date = date.send("#{start_or_end}_of_frequency", collapse) if collapse.present?
|
51
|
+
date.jd
|
52
|
+
else
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def parse_date( date )
|
58
|
+
begin
|
59
|
+
date = Date.jd(date.to_i) if date.kind_of?(String) && numeric?(date)
|
60
|
+
date = Date.jd(date) if date.is_a?(Integer)
|
61
|
+
date = Date.parse(date) if date.is_a?(String) && date =~ /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/
|
62
|
+
date
|
63
|
+
rescue
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def numeric?(string)
|
69
|
+
string = string.to_s
|
70
|
+
if string =~ /^\d+$/
|
71
|
+
true
|
72
|
+
else
|
73
|
+
Float(string).is_a?(Float) rescue false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
def reload
|
82
|
+
# reset attributes
|
83
|
+
@attributes = { 'id' => self.id }
|
84
|
+
@metadata = {}
|
85
|
+
# return self
|
86
|
+
true
|
87
|
+
end
|
88
|
+
|
89
|
+
module ClassMethods
|
90
|
+
def scope_names
|
91
|
+
self.scope.scope_names
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -1,18 +1,10 @@
|
|
1
|
-
|
2
|
-
module
|
3
|
-
module Concerns
|
1
|
+
class Quandl::Cassinatra::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 Quandl::Cassinatra.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
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Quandl::Cassinatra::Dataset < Quandl::Cassinatra::Base
|
2
|
+
|
3
|
+
require 'quandl/cassinatra/models/dataset/searchable'
|
4
|
+
require 'quandl/cassinatra/models/dataset/attributes'
|
5
|
+
|
6
|
+
include Quandl::Cassinatra::Dataset::Searchable
|
7
|
+
include Quandl::Cassinatra::Dataset::Attributes
|
8
|
+
|
9
|
+
def rows_count
|
10
|
+
count_data
|
11
|
+
end
|
12
|
+
|
13
|
+
def count_data
|
14
|
+
@count_data ||= self.class.get("datasets/#{id}/count").attributes[:count]
|
15
|
+
end
|
16
|
+
|
17
|
+
def delete_data
|
18
|
+
# cant delete unsaved records
|
19
|
+
return false if new_record?
|
20
|
+
# delete and return success / failure
|
21
|
+
self.class.destroy_existing("#{id}/data").saved?
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_rows(*dates)
|
25
|
+
# cant delete unsaved records
|
26
|
+
return false if new_record?
|
27
|
+
# collect dates
|
28
|
+
query = { dates: Array(dates).flatten }.to_query
|
29
|
+
# delete and return success / failure
|
30
|
+
self.class.destroy_existing("#{id}/data/rows?#{query}").saved?
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Quandl::Cassinatra::Dataset::Attributes
|
2
|
+
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
included do
|
10
|
+
|
11
|
+
attributes :id, :data, :trim_start, :trim_end, :columns, :frequency,
|
12
|
+
:rows_count, :type, :updated_at, :created_at
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def column_units
|
17
|
+
@column_units ||= columns.collect{|c| c['units'] } if columns.present?
|
18
|
+
end
|
19
|
+
|
20
|
+
def column_names
|
21
|
+
@column_names ||= columns.collect{|c| c['name'] } if columns.present?
|
22
|
+
end
|
23
|
+
|
24
|
+
def column_ids
|
25
|
+
@column_ids ||= columns.collect{|c| c['id'] } if columns.present?
|
26
|
+
end
|
27
|
+
|
28
|
+
def trim_start
|
29
|
+
@trim_start ||= parse_julian_date( read_attribute(:trim_start) )
|
30
|
+
end
|
31
|
+
|
32
|
+
def trim_end
|
33
|
+
@trim_end ||= parse_julian_date( read_attribute(:trim_end) )
|
34
|
+
end
|
35
|
+
|
36
|
+
def created_at
|
37
|
+
@created_at ||= Time.parse(read_attribute(:created_at)) rescue nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def updated_at
|
41
|
+
@updated_at ||= Time.parse(read_attribute(:updated_at)) rescue nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def reload
|
45
|
+
# reset instance variables
|
46
|
+
[:column_units, :column_names, :column_ids, :count_data, :scope,
|
47
|
+
:updated_at, :created_at, :trim_start, :trim_end
|
48
|
+
].each{|n| instance_variable_set("@#{n}", nil) }
|
49
|
+
# onwards
|
50
|
+
super
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def parse_julian_date(date)
|
56
|
+
date = date.to_i unless date.is_a?(Integer)
|
57
|
+
date = ( date > 0 ) ? Date.jd(date) : nil
|
58
|
+
date
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Quandl::Cassinatra::Dataset::Searchable
|
2
|
+
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
def search_scopes
|
8
|
+
@search_scopes ||+ search_scope.scopes.keys
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
included do
|
14
|
+
|
15
|
+
scope.class_eval do
|
16
|
+
delegate :each, :collect, :to_a, :to_h, :count, :inspect, :[], to: :to_table, allow_nil: true
|
17
|
+
delegate *Quandl::Data::Table.forwardable_methods, to: :to_table, allow_nil: true
|
18
|
+
end
|
19
|
+
|
20
|
+
scope_helper :to_table, -> { fetch_once.data }
|
21
|
+
|
22
|
+
scope :row, ->(v) { where( row: v.to_i ) }
|
23
|
+
scope :limit, ->(v) { where( limit: v.to_i ) }
|
24
|
+
scope :offset, ->(v) { where( offset: v.to_i ) }
|
25
|
+
scope :accuracy, ->(v) { where( accuracy: v.to_i ) }
|
26
|
+
scope :column, ->(v) { where( column: v.to_i ) }
|
27
|
+
scope :order, ->(dir) { where( order: (dir.to_sym == :asc) ? 'asc' : 'desc' ) }
|
28
|
+
scope :trim_start, ->(date) { where( trim_start: format_trim_date(date, :start)) }
|
29
|
+
scope :trim_end, ->(date) { where( trim_end: format_trim_date(date, :end)) }
|
30
|
+
scope :with_id, ->(value) { where( id: value.to_i )}
|
31
|
+
scope :transform, ->(value) { where( transform: value.to_sym ) if Quandl::Operation::Transform.valid_transformation?( value.try(:to_sym) ) }
|
32
|
+
|
33
|
+
scope :collapse, ->(value){
|
34
|
+
# set collapse
|
35
|
+
where( collapse: value ) if Quandl::Operation::Collapse.valid_collapse?( value.try(:to_sym) )
|
36
|
+
# reset trims to force them to edge of frequency
|
37
|
+
trim_start(trim_start) if trim_start
|
38
|
+
trim_end(trim_end) if trim_end
|
39
|
+
}
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def data
|
44
|
+
return read_data if data?
|
45
|
+
return scope unless queried?
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def data=(value)
|
50
|
+
write_data(value)
|
51
|
+
end
|
52
|
+
|
53
|
+
def scope
|
54
|
+
@scope ||= self.class.scope.new.references( self )
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
def read_data
|
61
|
+
Quandl::Data::Table.new( read_attribute(:data) )
|
62
|
+
end
|
63
|
+
|
64
|
+
def write_data(value )
|
65
|
+
write_attribute(:data, Quandl::Data::Table.new(value).to_csv )
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Quandl::Cassinatra::Multiset < Quandl::Cassinatra::Base
|
2
|
+
|
3
|
+
include Quandl::Cassinatra::Dataset::Searchable
|
4
|
+
|
5
|
+
# scope_helper :record, -> { find('multiset') }
|
6
|
+
|
7
|
+
scope :columns, ->(v){ where( columns: v ) }
|
8
|
+
|
9
|
+
attributes :id, :data, :trim_start, :trim_end, :columns, :frequency, :type, :updated_at, :created_at
|
10
|
+
|
11
|
+
def column_units
|
12
|
+
@column_units ||= columns.collect{|c| c['units'] }
|
13
|
+
end
|
14
|
+
|
15
|
+
def column_names
|
16
|
+
@column_names ||= columns.collect{|c| c['name'] }
|
17
|
+
end
|
18
|
+
|
19
|
+
def column_ids
|
20
|
+
@column_ids ||= columns.collect{|c| c['id'] }
|
21
|
+
end
|
22
|
+
|
23
|
+
def save
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'yajl'
|
2
|
+
|
3
|
+
module Her
|
4
|
+
module Model
|
5
|
+
# remove deprecated data method since cassinatra returns data: []
|
6
|
+
module DeprecatedMethods
|
7
|
+
remove_method( :data ) if method_defined?( :data )
|
8
|
+
remove_method( :data= ) if method_defined?( :data= )
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/spec/factories/dataset.rb
CHANGED
@@ -2,7 +2,7 @@ FactoryGirl.define do
|
|
2
2
|
|
3
3
|
factory :dataset do
|
4
4
|
sequence(:id) { |n| (Time.now.to_f * 1000).to_i + n }
|
5
|
-
|
5
|
+
data{ Quandl::Fabricate::Data::Table.rand( rows: 730, columns: 3, nils: false ) }
|
6
6
|
end
|
7
7
|
|
8
8
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Dataset do
|
5
|
+
subject{ Dataset.find_existing(1) }
|
6
|
+
its(:attributes){ should eq({ 'id' => 1 }) }
|
7
|
+
its(:id){ should eq 1 }
|
8
|
+
|
9
|
+
context "#reload" do
|
10
|
+
before(:each){ subject.reload }
|
11
|
+
its(:attributes){ should eq({ 'id' => 1 }) }
|
12
|
+
its(:id){ should eq 1 }
|
13
|
+
end
|
14
|
+
|
15
|
+
context "#id" do
|
16
|
+
before(:each){ subject.id = 2 }
|
17
|
+
its(:attributes){ should eq({ 'id' => 2 }) }
|
18
|
+
its(:id){ should eq 2 }
|
19
|
+
|
20
|
+
context "#reload" do
|
21
|
+
before(:each){ subject.reload }
|
22
|
+
its(:attributes){ should eq({ 'id' => 2 }) }
|
23
|
+
its(:id){ should eq 2 }
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -17,14 +17,14 @@ describe Dataset do
|
|
17
17
|
|
18
18
|
describe "#delete_rows" do
|
19
19
|
|
20
|
-
let(:dates_slice){ dataset.
|
20
|
+
let(:dates_slice){ dataset.data.to_h.keys[10..19] }
|
21
21
|
|
22
22
|
before(:each){ subject.delete_rows( dates_slice ) }
|
23
23
|
|
24
24
|
its(:status){ should eq 200 }
|
25
25
|
|
26
26
|
it "data count should be 720" do
|
27
|
-
Dataset.find( dataset.id ).
|
27
|
+
Dataset.find( dataset.id ).data.count.should eq 720
|
28
28
|
end
|
29
29
|
|
30
30
|
end
|
@@ -3,41 +3,42 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe Dataset do
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
subject{ build(:dataset) }
|
6
|
+
let(:dataset){ build(:dataset) }
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
it "should have four columns" do
|
19
|
-
subject.data_table[0].count.should eq 4
|
20
|
-
end
|
21
|
-
|
8
|
+
subject{ dataset }
|
9
|
+
|
10
|
+
it { should respond_to :data }
|
11
|
+
|
12
|
+
describe "#data" do
|
13
|
+
subject{ dataset.data }
|
14
|
+
its(:count){ should eq 730 }
|
22
15
|
end
|
23
16
|
|
24
|
-
context "
|
17
|
+
context "#save" do
|
18
|
+
|
19
|
+
before(:each){ dataset.save }
|
25
20
|
|
26
|
-
subject{
|
21
|
+
subject{ Dataset.find(dataset.id) }
|
27
22
|
|
23
|
+
its(:count_data){ should eq dataset.data.count }
|
24
|
+
|
25
|
+
describe "#columns" do
|
26
|
+
subject{ dataset.columns }
|
27
|
+
its(:count){ should eq 3 }
|
28
|
+
end
|
29
|
+
|
28
30
|
describe "#column_ids" do
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
it "should
|
33
|
-
subject.
|
31
|
+
subject{ dataset.column_ids }
|
32
|
+
its(:count){ should eq 3 }
|
33
|
+
|
34
|
+
it "each should be present" do
|
35
|
+
subject.each{|cid| cid.present?.should be_true }
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
37
39
|
describe "#data" do
|
38
|
-
|
39
|
-
|
40
|
-
end
|
40
|
+
subject{ dataset.data }
|
41
|
+
its(:count){ should eq 730 }
|
41
42
|
end
|
42
43
|
|
43
44
|
end
|
@@ -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.trim_start.should eq subject.
|
17
|
+
subject.trim_start.should eq subject.data.to_date[-1][0]
|
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.trim_end.should eq subject.
|
31
|
+
subject.trim_end.should eq subject.data.to_date[0][0]
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -2,15 +2,26 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Multiset do
|
5
|
-
let(:d1){ create(:dataset,
|
6
|
-
let(:d2){ create(:dataset,
|
5
|
+
let(:d1){ create(:dataset, data: Quandl::Fabricate::Data::Table.rand( rows: 10, columns: 4, nils: false ) ) }
|
6
|
+
let(:d2){ create(:dataset, data: Quandl::Fabricate::Data::Table.rand( rows: 10, columns: 4, nils: false ) ) }
|
7
|
+
let(:multiset){ Multiset.find_existing('ephemeral') }
|
8
|
+
subject{ multiset }
|
9
|
+
|
10
|
+
describe "#data" do
|
11
|
+
subject{ multiset.data.columns("#{d1.id}.1,#{d2.id}.2") }
|
12
|
+
|
13
|
+
its(:count){ should eq 10 }
|
14
|
+
its(:to_h){ should be_present }
|
15
|
+
its(:to_a){ should be_present }
|
16
|
+
|
17
|
+
end
|
18
|
+
|
7
19
|
|
8
20
|
context "given ascending columns" do
|
9
21
|
|
10
22
|
it "should return the expected column_ids" do
|
11
|
-
|
12
|
-
|
13
|
-
m.column_ids.should eq [
|
23
|
+
subject.data.columns("#{d2.id.to_i}.1,#{d1.id.to_i}.1,#{d2.id.to_i}.3,#{d1.id.to_i}.2").to_a
|
24
|
+
subject.column_ids.should eq [
|
14
25
|
Dataset.find(d2.id).column_ids[0],
|
15
26
|
Dataset.find(d1.id).column_ids[0],
|
16
27
|
Dataset.find(d2.id).column_ids[2],
|
@@ -19,13 +30,11 @@ describe Multiset do
|
|
19
30
|
end
|
20
31
|
|
21
32
|
it "should return the expected columns" do
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
m.data_table[0][3].should eq d2.data_table[0][3]
|
28
|
-
m.data_table[0][4].should eq d1.data_table[0][2]
|
33
|
+
subject.data.columns("#{d2.id.to_i}.1,#{d1.id.to_i}.1,#{d2.id.to_i}.3,#{d1.id.to_i}.2")
|
34
|
+
subject.data[0][1].should eq d2.data[0][1]
|
35
|
+
subject.data[0][2].should eq d1.data[0][1]
|
36
|
+
subject.data[0][3].should eq d2.data[0][3]
|
37
|
+
subject.data[0][4].should eq d1.data[0][2]
|
29
38
|
end
|
30
39
|
|
31
40
|
end
|
@@ -33,8 +42,8 @@ describe Multiset do
|
|
33
42
|
context "given descending columns" do
|
34
43
|
|
35
44
|
it "should return the expected columns" do
|
36
|
-
|
37
|
-
|
45
|
+
subject.data.columns("#{d1.id.to_i}.2,#{d1.id.to_i}.1")
|
46
|
+
subject.data[0][1].should_not eq subject.data[0][2]
|
38
47
|
end
|
39
48
|
|
40
49
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -15,4 +15,6 @@ require "quandl/fabricate"
|
|
15
15
|
require "quandl/cassinatra"
|
16
16
|
Quandl::Cassinatra.use 'http://192.168.33.10:8983/wikiposit_cassandra/'
|
17
17
|
# Quandl::Cassinatra.use 'http://localhost:9292/'
|
18
|
-
include Quandl::Cassinatra
|
18
|
+
include Quandl::Cassinatra
|
19
|
+
|
20
|
+
# binding.pry
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quandl_cassinatra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
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-10-
|
12
|
+
date: 2013-10-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -236,23 +236,22 @@ files:
|
|
236
236
|
- Rakefile
|
237
237
|
- UPGRADE.md
|
238
238
|
- lib/quandl/cassinatra.rb
|
239
|
-
- lib/quandl/cassinatra/
|
240
|
-
- lib/quandl/cassinatra/
|
241
|
-
- lib/quandl/cassinatra/
|
242
|
-
- lib/quandl/cassinatra/
|
243
|
-
- lib/quandl/cassinatra/
|
244
|
-
- lib/quandl/cassinatra/her.rb
|
239
|
+
- lib/quandl/cassinatra/base.rb
|
240
|
+
- lib/quandl/cassinatra/base/attributes.rb
|
241
|
+
- lib/quandl/cassinatra/base/model.rb
|
242
|
+
- lib/quandl/cassinatra/base/search.rb
|
243
|
+
- lib/quandl/cassinatra/base/validation.rb
|
245
244
|
- lib/quandl/cassinatra/middleware.rb
|
246
245
|
- lib/quandl/cassinatra/middleware/parse_json.rb
|
247
|
-
- lib/quandl/cassinatra/
|
248
|
-
- lib/quandl/cassinatra/
|
249
|
-
- lib/quandl/cassinatra/
|
250
|
-
- lib/quandl/cassinatra/
|
251
|
-
- lib/quandl/cassinatra/model/multiset.rb
|
246
|
+
- lib/quandl/cassinatra/models/dataset.rb
|
247
|
+
- lib/quandl/cassinatra/models/dataset/attributes.rb
|
248
|
+
- lib/quandl/cassinatra/models/dataset/searchable.rb
|
249
|
+
- lib/quandl/cassinatra/models/multiset.rb
|
252
250
|
- lib/quandl/cassinatra/version.rb
|
253
|
-
- lib/quandl/her/
|
251
|
+
- lib/quandl/her/remove_method_data.rb
|
254
252
|
- quandl_cassinatra.gemspec
|
255
253
|
- spec/factories/dataset.rb
|
254
|
+
- spec/quandl/cassinatra/dataset/attributes_spec.rb
|
256
255
|
- spec/quandl/cassinatra/dataset/delete_spec.rb
|
257
256
|
- spec/quandl/cassinatra/dataset/persistence_spec.rb
|
258
257
|
- spec/quandl/cassinatra/dataset/searchable_spec.rb
|
@@ -286,6 +285,7 @@ specification_version: 3
|
|
286
285
|
summary: Cassinatra rest orm.
|
287
286
|
test_files:
|
288
287
|
- spec/factories/dataset.rb
|
288
|
+
- spec/quandl/cassinatra/dataset/attributes_spec.rb
|
289
289
|
- spec/quandl/cassinatra/dataset/delete_spec.rb
|
290
290
|
- spec/quandl/cassinatra/dataset/persistence_spec.rb
|
291
291
|
- spec/quandl/cassinatra/dataset/searchable_spec.rb
|
@@ -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/cassinatra/concerns/search'
|
7
|
-
require 'quandl/cassinatra/concerns/properties'
|
8
|
-
|
9
|
-
module Quandl
|
10
|
-
module Cassinatra
|
11
|
-
|
12
|
-
module Concerns
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Quandl
|
2
|
-
module Cassinatra
|
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 +0,0 @@
|
|
1
|
-
require "quandl/cassinatra/core_ext/string"
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module Quandl
|
2
|
-
module Cassinatra
|
3
|
-
class << self
|
4
|
-
|
5
|
-
def use(url)
|
6
|
-
self.rest_url = url
|
7
|
-
end
|
8
|
-
|
9
|
-
def her_api
|
10
|
-
# setup api
|
11
|
-
api = Her::API.new
|
12
|
-
api.setup url: rest_url do |c|
|
13
|
-
c.use Faraday::Request::UrlEncoded
|
14
|
-
c.use Quandl::Cassinatra::Middleware::ParseJSON
|
15
|
-
c.use Faraday::Adapter::NetHttp
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def rest_url
|
20
|
-
@rest_url ||= 'http://localhost:9292/'
|
21
|
-
end
|
22
|
-
|
23
|
-
def rest_url=(url)
|
24
|
-
url = "http://#{url}" if ( url =~ /^http:\/\// ) == nil
|
25
|
-
@rest_url = url
|
26
|
-
Model.use_api( her_api )
|
27
|
-
@rest_url
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'quandl/cassinatra/model/dataset'
|
2
|
-
require 'quandl/cassinatra/model/dataset_attribute'
|
3
|
-
require 'quandl/cassinatra/model/multiset'
|
4
|
-
|
5
|
-
module Quandl
|
6
|
-
module Cassinatra
|
7
|
-
module Model
|
8
|
-
class << self
|
9
|
-
|
10
|
-
def use_api(api)
|
11
|
-
each{|k| k.use_api(api) }
|
12
|
-
end
|
13
|
-
|
14
|
-
def each(&block)
|
15
|
-
models.each do |k|
|
16
|
-
block.call(k)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def models
|
21
|
-
[Dataset, DatasetAttribute, Multiset]
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'quandl/cassinatra/model/dataset/searchable'
|
2
|
-
|
3
|
-
module Quandl
|
4
|
-
module Cassinatra
|
5
|
-
module Model
|
6
|
-
|
7
|
-
class Dataset
|
8
|
-
|
9
|
-
include Concerns::Properties
|
10
|
-
include Searchable
|
11
|
-
|
12
|
-
attributes :id, :data, :trim_start, :trim_end, :columns
|
13
|
-
|
14
|
-
delegate :columns_count, :created_at, :frequency, :rows_count, :type, :updated_at, to: :dataset_attribute
|
15
|
-
|
16
|
-
def column_units
|
17
|
-
@column_units ||= columns.collect{|c| c['units'] }
|
18
|
-
end
|
19
|
-
|
20
|
-
def column_names
|
21
|
-
@column_names ||= columns.collect{|c| c['name'] }
|
22
|
-
end
|
23
|
-
|
24
|
-
def column_ids
|
25
|
-
@column_ids ||= columns.collect{|c| c['id'] }
|
26
|
-
end
|
27
|
-
|
28
|
-
def data_table
|
29
|
-
@data_table ||= Data::Table.new( self.data || [] )
|
30
|
-
end
|
31
|
-
def data_table=(value)
|
32
|
-
self.data = Data::Table.new(value).to_csv
|
33
|
-
end
|
34
|
-
|
35
|
-
def dataset_attribute(*args)
|
36
|
-
return @dataset_attribute if @dataset_attribute
|
37
|
-
# options
|
38
|
-
options = args.extract_options!
|
39
|
-
count = options[:count] == true
|
40
|
-
# grab dataset_attribute
|
41
|
-
@dataset_attribute = DatasetAttribute.where( count: count ).find(id)
|
42
|
-
end
|
43
|
-
|
44
|
-
def delete_data
|
45
|
-
Dataset.destroy_existing("#{id.to_i}/data").status
|
46
|
-
end
|
47
|
-
|
48
|
-
def delete_rows(*dates)
|
49
|
-
query = { dates: Array(dates).flatten }.to_query
|
50
|
-
Dataset.destroy_existing("#{id.to_i}/data/rows?#{query}").status
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
module Quandl
|
2
|
-
module Cassinatra
|
3
|
-
module Model
|
4
|
-
class Dataset
|
5
|
-
|
6
|
-
module Searchable
|
7
|
-
|
8
|
-
extend ActiveSupport::Concern
|
9
|
-
|
10
|
-
module ClassMethods
|
11
|
-
|
12
|
-
def search_scopes
|
13
|
-
@search_scopes ||+ search_scope.scopes.keys
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
included do
|
19
|
-
|
20
|
-
include Quandl
|
21
|
-
include ScopeComposer::Model
|
22
|
-
|
23
|
-
scope_composer_for :search
|
24
|
-
|
25
|
-
search_helper :column_ids, -> { dataset.column_ids }
|
26
|
-
search_helper :data_table, -> { dataset.data_table }
|
27
|
-
|
28
|
-
search_helper :dataset, -> { find(attributes[:id]) }
|
29
|
-
|
30
|
-
search_scope.class_eval do
|
31
|
-
delegate *Array.forwardable_methods, to: :data_table
|
32
|
-
delegate *Data::Table.forwardable_methods, to: :data_table
|
33
|
-
end
|
34
|
-
|
35
|
-
search_scope :row, ->(v) { where( row: v.to_i ) }
|
36
|
-
search_scope :limit, ->(v) { where( limit: v.to_i ) }
|
37
|
-
search_scope :offset, ->(v) { where( offset: v.to_i ) }
|
38
|
-
search_scope :accuracy, ->(v) { where( accuracy: v.to_i ) }
|
39
|
-
search_scope :column, ->(v) { where( column: v.to_i ) }
|
40
|
-
search_scope :order, ->(dir) { where( order: (dir.to_sym == :asc) ? 'asc' : 'desc' ) }
|
41
|
-
search_scope :trim_start, ->(date) { where( trim_start: format_trim_date(date, :start)) }
|
42
|
-
search_scope :trim_end, ->(date) { where( trim_end: format_trim_date(date, :end)) }
|
43
|
-
search_scope :with_id, ->(value) { where( id: value.to_i )}
|
44
|
-
search_scope :transform, ->(value) { where( transform: value.to_sym ) if Quandl::Operation::Transform.valid_transformation?( value.try(:to_sym) ) }
|
45
|
-
|
46
|
-
search_scope :collapse, ->(value){
|
47
|
-
# set collapse
|
48
|
-
where( collapse: value ) if Quandl::Operation::Collapse.valid_collapse?( value.try(:to_sym) )
|
49
|
-
# reset trims to force them to edge of frequency
|
50
|
-
trim_start(trim_start) if trim_start
|
51
|
-
trim_end(trim_end) if trim_end
|
52
|
-
}
|
53
|
-
|
54
|
-
search_helper :format_trim_date, ->( date, start_or_end ){
|
55
|
-
# parse
|
56
|
-
date = parse_date(date)
|
57
|
-
# format
|
58
|
-
if date.is_a?(Date)
|
59
|
-
date = date.send("#{start_or_end}_of_frequency", collapse) if collapse.present?
|
60
|
-
date.jd
|
61
|
-
else
|
62
|
-
nil
|
63
|
-
end
|
64
|
-
}
|
65
|
-
|
66
|
-
search_helper :parse_date, ->( date ){
|
67
|
-
begin
|
68
|
-
date = Date.jd(date.to_i) if date.kind_of?(String) && date.numeric?
|
69
|
-
date = Date.jd(date) if date.is_a?(Integer)
|
70
|
-
date = Date.parse(date) if date.is_a?(String) && date =~ /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/
|
71
|
-
date
|
72
|
-
rescue
|
73
|
-
nil
|
74
|
-
end
|
75
|
-
}
|
76
|
-
|
77
|
-
search_helper :find, ->(id){
|
78
|
-
begin
|
79
|
-
t1 = Time.now
|
80
|
-
result = self.class.parent.where(attributes).find(id)
|
81
|
-
Quandl::Logger.debug "Quandl::Cassinatra::Dataset.where(#{attributes.to_param if attributes.respond_to?(:to_param)}).find(#{id}) (#{t1.elapsed_ms})"
|
82
|
-
rescue => error
|
83
|
-
Quandl::Logger.error "Quandl::Cassinatra::Dataset.find #{error}"
|
84
|
-
end
|
85
|
-
result = self.class.parent.new(id: id) if result.nil?
|
86
|
-
result
|
87
|
-
}
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module Quandl
|
2
|
-
module Cassinatra
|
3
|
-
module Model
|
4
|
-
|
5
|
-
class Multiset
|
6
|
-
|
7
|
-
include Model::Dataset::Searchable
|
8
|
-
include Concerns::Properties
|
9
|
-
|
10
|
-
|
11
|
-
search_helper :to_dataset, -> { dataset }
|
12
|
-
search_helper :dataset, -> { find('multiset') }
|
13
|
-
|
14
|
-
search_scope :columns, ->(v){ where( columns: v ) }
|
15
|
-
|
16
|
-
attributes :id, :column_ids, :data
|
17
|
-
|
18
|
-
delegate :columns_count, :created_at, :frequency, :rows_count, :type, :updated_at, to: :dataset_attribute
|
19
|
-
|
20
|
-
def data_table
|
21
|
-
Data::Table.new( self.data || [] )
|
22
|
-
end
|
23
|
-
def dataset_attribute(*args)
|
24
|
-
return @dataset_attribute if @dataset_attribute
|
25
|
-
# options
|
26
|
-
options = args.extract_options!
|
27
|
-
count = options[:count] == true
|
28
|
-
# grab dataset_attribute
|
29
|
-
@dataset_attribute = DatasetAttribute.where( count: count ).find(id)
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
data/lib/quandl/her/patch.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'yajl'
|
2
|
-
|
3
|
-
module Her
|
4
|
-
module Model
|
5
|
-
# remove deprecated data method since cassinatra returns data: []
|
6
|
-
module DeprecatedMethods
|
7
|
-
remove_method :data
|
8
|
-
remove_method :data=
|
9
|
-
end
|
10
|
-
end
|
11
|
-
module Middleware
|
12
|
-
class ParseJSON < Faraday::Response::Middleware
|
13
|
-
# @private
|
14
|
-
def parse_json(body = nil)
|
15
|
-
body ||= '{}'
|
16
|
-
message = "Response from the API must behave like a Hash or an Array (last JSON response was #{body.inspect})"
|
17
|
-
|
18
|
-
json = begin
|
19
|
-
Yajl.load(body, :symbolize_keys => true)
|
20
|
-
rescue Yajl::ParseError
|
21
|
-
raise Her::Errors::ParseError, message
|
22
|
-
end
|
23
|
-
|
24
|
-
raise Her::Errors::ParseError, message unless json.is_a?(Hash) or json.is_a?(Array)
|
25
|
-
|
26
|
-
json
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|