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