flydata 0.0.4.4 → 0.0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ gem "i18n"
5
5
  gem "activesupport"
6
6
  gem "json"
7
7
  gem "highline"
8
- gem "fluentd"
8
+ gem "fluentd", "0.10.35"
9
9
 
10
10
  group :development do
11
11
  gem "bundler"
@@ -15,4 +15,7 @@ group :development do
15
15
  gem "autotest-standalone"
16
16
  gem "autotest-notification"
17
17
  gem "ZenTest"
18
+ gem "activemodel"
19
+ gem "activerecord"
20
+ gem "sqlite3"
18
21
  end
data/Gemfile.lock CHANGED
@@ -2,22 +2,32 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  ZenTest (4.8.2)
5
+ activemodel (3.2.8)
6
+ activesupport (= 3.2.8)
7
+ builder (~> 3.0.0)
8
+ activerecord (3.2.8)
9
+ activemodel (= 3.2.8)
10
+ activesupport (= 3.2.8)
11
+ arel (~> 3.0.2)
12
+ tzinfo (~> 0.3.29)
5
13
  activesupport (3.2.8)
6
14
  i18n (~> 0.6)
7
15
  multi_json (~> 1.0)
16
+ arel (3.0.2)
8
17
  autotest (4.4.6)
9
18
  ZenTest (>= 4.4.1)
10
19
  autotest-notification (2.3.4)
11
20
  autotest-standalone (~> 4.5)
12
21
  autotest-standalone (4.5.9)
13
- cool.io (1.1.0)
22
+ builder (3.0.4)
23
+ cool.io (1.1.1)
14
24
  iobuffer (>= 1.0.0)
15
25
  diff-lcs (1.1.3)
16
- fluentd (0.10.25)
26
+ fluentd (0.10.35)
17
27
  cool.io (~> 1.1.0)
18
28
  http_parser.rb (~> 0.5.1)
19
29
  json (>= 1.4.3)
20
- msgpack (~> 0.4.4)
30
+ msgpack (>= 0.4.4, < 0.6.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
21
31
  yajl-ruby (~> 1.0)
22
32
  git (1.2.5)
23
33
  highline (1.6.15)
@@ -31,7 +41,7 @@ GEM
31
41
  rdoc
32
42
  json (1.7.5)
33
43
  mime-types (1.19)
34
- msgpack (0.4.7)
44
+ msgpack (0.5.5)
35
45
  multi_json (1.3.6)
36
46
  rake (0.9.2.2)
37
47
  rdoc (3.12)
@@ -46,6 +56,8 @@ GEM
46
56
  rspec-expectations (2.11.3)
47
57
  diff-lcs (~> 1.1.3)
48
58
  rspec-mocks (2.11.3)
59
+ sqlite3 (1.3.7)
60
+ tzinfo (0.3.37)
49
61
  yajl-ruby (1.1.0)
50
62
 
51
63
  PLATFORMS
@@ -53,15 +65,18 @@ PLATFORMS
53
65
 
54
66
  DEPENDENCIES
55
67
  ZenTest
68
+ activemodel
69
+ activerecord
56
70
  activesupport
57
71
  autotest
58
72
  autotest-notification
59
73
  autotest-standalone
60
74
  bundler
61
- fluentd
75
+ fluentd (= 0.10.35)
62
76
  highline
63
77
  i18n
64
78
  jeweler
65
79
  json
66
80
  rest-client
67
81
  rspec
82
+ sqlite3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4.4
1
+ 0.0.5.0
data/flydata.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "flydata"
8
- s.version = "0.0.4.4"
8
+ s.version = "0.0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Koichi Fujikawa"]
12
- s.date = "2013-07-09"
12
+ s.date = "2013-08-14"
13
13
  s.description = "FlyData Command Line Interface"
14
14
  s.email = "sysadmin@flydata.co"
15
15
  s.executables = ["flydata"]
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  "VERSION",
23
23
  "bin/flydata",
24
24
  "flydata.gemspec",
25
+ "lib/fly_data_model.rb",
25
26
  "lib/flydata.rb",
26
27
  "lib/flydata/api/base.rb",
27
28
  "lib/flydata/api/data_entry.rb",
@@ -42,17 +43,22 @@ Gem::Specification.new do |s|
42
43
  "lib/flydata/cron.rb",
43
44
  "lib/flydata/flydata_crontab.sh",
44
45
  "lib/flydata/helpers.rb",
46
+ "lib/flydata/heroku.rb",
47
+ "lib/flydata/heroku/configuration_methods.rb",
48
+ "lib/flydata/heroku/instance_methods.rb",
45
49
  "lib/flydata/log_monitor.rb",
46
50
  "lib/flydata/proxy.rb",
51
+ "spec/fly_data_model_spec.rb",
47
52
  "spec/flydata/api/data_entry_spec.rb",
48
53
  "spec/flydata/command/sender_spec.rb",
54
+ "spec/flydata/heroku_spec.rb",
49
55
  "spec/flydata_spec.rb",
50
56
  "spec/spec_helper.rb"
51
57
  ]
52
58
  s.homepage = "http://flydata.co/"
53
59
  s.licenses = ["All right reserved."]
54
60
  s.require_paths = ["lib"]
55
- s.rubygems_version = "1.8.23"
61
+ s.rubygems_version = "1.8.25"
56
62
  s.summary = "FlyData CLI"
57
63
 
58
64
  if s.respond_to? :specification_version then
@@ -64,7 +70,7 @@ Gem::Specification.new do |s|
64
70
  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
65
71
  s.add_runtime_dependency(%q<json>, [">= 0"])
66
72
  s.add_runtime_dependency(%q<highline>, [">= 0"])
67
- s.add_runtime_dependency(%q<fluentd>, [">= 0"])
73
+ s.add_runtime_dependency(%q<fluentd>, ["= 0.10.35"])
68
74
  s.add_development_dependency(%q<bundler>, [">= 0"])
69
75
  s.add_development_dependency(%q<jeweler>, [">= 0"])
70
76
  s.add_development_dependency(%q<rspec>, [">= 0"])
@@ -72,13 +78,16 @@ Gem::Specification.new do |s|
72
78
  s.add_development_dependency(%q<autotest-standalone>, [">= 0"])
73
79
  s.add_development_dependency(%q<autotest-notification>, [">= 0"])
74
80
  s.add_development_dependency(%q<ZenTest>, [">= 0"])
81
+ s.add_development_dependency(%q<activemodel>, [">= 0"])
82
+ s.add_development_dependency(%q<activerecord>, [">= 0"])
83
+ s.add_development_dependency(%q<sqlite3>, [">= 0"])
75
84
  else
76
85
  s.add_dependency(%q<rest-client>, [">= 0"])
77
86
  s.add_dependency(%q<i18n>, [">= 0"])
78
87
  s.add_dependency(%q<activesupport>, [">= 0"])
79
88
  s.add_dependency(%q<json>, [">= 0"])
80
89
  s.add_dependency(%q<highline>, [">= 0"])
81
- s.add_dependency(%q<fluentd>, [">= 0"])
90
+ s.add_dependency(%q<fluentd>, ["= 0.10.35"])
82
91
  s.add_dependency(%q<bundler>, [">= 0"])
83
92
  s.add_dependency(%q<jeweler>, [">= 0"])
84
93
  s.add_dependency(%q<rspec>, [">= 0"])
@@ -86,6 +95,9 @@ Gem::Specification.new do |s|
86
95
  s.add_dependency(%q<autotest-standalone>, [">= 0"])
87
96
  s.add_dependency(%q<autotest-notification>, [">= 0"])
88
97
  s.add_dependency(%q<ZenTest>, [">= 0"])
98
+ s.add_dependency(%q<activemodel>, [">= 0"])
99
+ s.add_dependency(%q<activerecord>, [">= 0"])
100
+ s.add_dependency(%q<sqlite3>, [">= 0"])
89
101
  end
90
102
  else
91
103
  s.add_dependency(%q<rest-client>, [">= 0"])
@@ -93,7 +105,7 @@ Gem::Specification.new do |s|
93
105
  s.add_dependency(%q<activesupport>, [">= 0"])
94
106
  s.add_dependency(%q<json>, [">= 0"])
95
107
  s.add_dependency(%q<highline>, [">= 0"])
96
- s.add_dependency(%q<fluentd>, [">= 0"])
108
+ s.add_dependency(%q<fluentd>, ["= 0.10.35"])
97
109
  s.add_dependency(%q<bundler>, [">= 0"])
98
110
  s.add_dependency(%q<jeweler>, [">= 0"])
99
111
  s.add_dependency(%q<rspec>, [">= 0"])
@@ -101,6 +113,9 @@ Gem::Specification.new do |s|
101
113
  s.add_dependency(%q<autotest-standalone>, [">= 0"])
102
114
  s.add_dependency(%q<autotest-notification>, [">= 0"])
103
115
  s.add_dependency(%q<ZenTest>, [">= 0"])
116
+ s.add_dependency(%q<activemodel>, [">= 0"])
117
+ s.add_dependency(%q<activerecord>, [">= 0"])
118
+ s.add_dependency(%q<sqlite3>, [">= 0"])
104
119
  end
105
120
  end
106
121
 
@@ -0,0 +1,4 @@
1
+ module FlyDataModel
2
+ extend ActiveSupport::Concern
3
+ include ActiveModel::Serialization
4
+ end
data/lib/flydata.rb CHANGED
@@ -13,4 +13,6 @@ ActiveSupport::Dependencies.autoload_paths << lib_dir
13
13
 
14
14
  module Flydata
15
15
  HOME_DIR="#{ENV['HOME']}/.flydata"
16
+
17
+ include Flydata::Heroku
16
18
  end
@@ -0,0 +1,150 @@
1
+ module Flydata
2
+ module Heroku
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ if defined? ActiveModel
7
+ # Reopen ActiveModel::Serialization to add flydata support
8
+ module ActiveModel::Serialization
9
+ extend ActiveSupport::Concern
10
+ include Flydata::Heroku::InstanceMethods
11
+ include Flydata::Heroku::ConfigurationMethods
12
+ end
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ # Puts a JSON string that represents args to $stdout
18
+ #
19
+ # @example
20
+ # send_to('table_name', { key: 'value' })
21
+ # send_to('table_name', [{ key: 'value' }, { key: 'value' ])
22
+ #
23
+ # @example
24
+ # send_to(:table_name, { key: 'value' })
25
+ # send_to(:table_name', [{ key: 'value' }, { key: 'value' ])
26
+ #
27
+ # @example
28
+ # send_to(active_record)
29
+ # send_to(active_record, active_record)
30
+ #
31
+ # @example
32
+ # send_to([user, user])
33
+ #
34
+ # @param [String, Symbol] table name
35
+ # @param [Hash] values
36
+ # @param [Array<Hash>] array of value
37
+ # @param [ActiveRecord::Base] record
38
+ # @param [ActiveModel::Serialization] model
39
+ # @param [Array<ActiveRecord::Base>] array of record
40
+ # @param [Array<ActiveModel::Serialization>] array of model
41
+ def send_to(*args)
42
+ if args[0].nil?
43
+ raise ArgumentError, 'The argument of send_to must be non-nil'
44
+ end
45
+
46
+ if args[0].respond_to?(:empty?) && args[0].empty?
47
+ raise ArgumentError, 'The 1st argument of send_to must not be empty'
48
+ end
49
+
50
+ if (args[0].kind_of?(String) || args[0].kind_of?(Symbol))
51
+ unless structured_data?(args[1])
52
+ raise ArgumentError, 'The 2nd argument of send_to must be an Array or Hash'
53
+ end
54
+ end
55
+
56
+ obj = case args[0]
57
+ when String
58
+ structured_data_as_flydata(args[0], args[1])
59
+ when Symbol
60
+ structured_data_as_flydata(args[0].to_s, args[1])
61
+ when Array
62
+ ancestors = args[0][0].class.ancestors
63
+ if defined?(ActiveModel) && ancestors.include?(ActiveModel::Serialization)
64
+ active_models_as_flydata(args[0])
65
+ end
66
+ else
67
+ ancestors = args[0].class.ancestors
68
+ if defined?(ActiveModel) && ancestors.include?(ActiveModel::Serialization)
69
+ multiple_active_models_as_flydata(args)
70
+ end
71
+ end
72
+ $stdout.puts(obj.to_json) if obj
73
+ end
74
+
75
+ # Formats a Time object for Redshift
76
+ #
77
+ # @param [#strftime]
78
+ # @return [String, Objct]
79
+ def format_time_for_redshift(time)
80
+ time.respond_to?(:strftime) ? time.strftime('%Y-%m-%d %H:%M:%S') : time
81
+ end
82
+
83
+ # Formats a Time object for Redshift
84
+ #
85
+ # @param [#strftime]
86
+ # @return [String, Objct]
87
+ def format_date_for_redshift(time)
88
+ time.respond_to?(:strftime) ? time.strftime('%Y-%m-%d') : time
89
+ end
90
+
91
+ private
92
+
93
+ # @param [String]
94
+ # @param [Hash, Array]
95
+ # @return [Hash]
96
+ def structured_data_as_flydata(table_name, values)
97
+ { table_name => format_for_flydata(values) }
98
+ end
99
+
100
+ # @param [Object]
101
+ # @return [Object]
102
+ def format_for_flydata(obj)
103
+ case obj
104
+ when Hash
105
+ obj.each { |k, v| obj[k] = format_for_flydata(v) }
106
+ when Array
107
+ obj.map { |item| item.kind_of?(Hash) ? format_for_flydata(item) : item }
108
+ when Time
109
+ format_time_for_redshift(obj)
110
+ when DateTime
111
+ format_time_for_redshift(obj)
112
+ when Date
113
+ format_date_for_redshift(obj)
114
+ else
115
+ obj
116
+ end
117
+ end
118
+
119
+ # @param [Object]
120
+ # @return [Boolean]
121
+ def structured_data?(value)
122
+ value.kind_of?(Array) || value.kind_of?(Hash)
123
+ end
124
+
125
+ if defined?(ActiveModel)
126
+ # @param [Array<ActiveModel::Serialization>]
127
+ # @return [Hash]
128
+ def active_models_as_flydata(models)
129
+ table_name = models[0].class.flydata_table_name
130
+ { table_name => models.map(&:as_flydata) }
131
+ end
132
+
133
+ # @param [Array<ActiveModel::Serialization>]
134
+ # @return [Hash]
135
+ def multiple_active_models_as_flydata(models)
136
+ hash = {}
137
+ models.group_by { |record| record.class.flydata_table_name }.each do |table_name, models|
138
+ hash[table_name] = if models.size == 1
139
+ models[0].as_flydata
140
+ else
141
+ models.map(&:as_flydata)
142
+ end
143
+ end
144
+ hash
145
+ end
146
+ end
147
+ end
148
+
149
+ end
150
+ end
@@ -0,0 +1,47 @@
1
+ module Flydata
2
+ module Heroku
3
+ module ConfigurationMethods
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ if respond_to?(:class_attribute)
8
+ class_attribute :_flydata_table_name
9
+ class_attribute :_flydata_attributes
10
+ else
11
+ class_inheritable_accessor :_flydata_table_name
12
+ class_inheritable_accessor :_flydata_attributes
13
+ end
14
+ self._flydata_table_name = nil
15
+ self._flydata_attributes = nil
16
+ end
17
+
18
+ module ClassMethods
19
+ # @example
20
+ # class User < ActiveRecord::Base
21
+ # flydata_attr :id, :name
22
+ # end
23
+ def flydata_attr(*attributes)
24
+ raise "flydata_attr attributes cannot be blank" if attributes.empty?
25
+ self._flydata_attributes = attributes.map(&:to_sym)
26
+ end
27
+
28
+ # @example
29
+ # class User < ActiveRecord::Base
30
+ # flydata_table :other_table
31
+ # end
32
+ def flydata_table(table_name)
33
+ self._flydata_table_name = table_name
34
+ end
35
+
36
+ # @return [String]
37
+ def flydata_table_name
38
+ self._flydata_table_name ||= if self.ancestors.include?(ActiveRecord::Base)
39
+ self.table_name
40
+ else
41
+ self.name.tableize
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,42 @@
1
+ module Flydata
2
+ module Heroku
3
+ module InstanceMethods
4
+ # @return [Hash]
5
+ def as_flydata
6
+ # Logic borrowed from activemodel/lib/active_model/serialization.rb
7
+ options = { :root => nil }
8
+ attribute_names = self.class._flydata_attributes || attributes.keys.sort
9
+ hash = {}
10
+ attribute_names.each do |n|
11
+ value = read_attribute_for_serialization(n)
12
+ hash[n] = case value
13
+ when Time
14
+ Flydata.format_time_for_redshift(value)
15
+ when DateTime
16
+ Flydata.format_time_for_redshift(value)
17
+ when Date
18
+ Flydata.format_date_for_redshift(value)
19
+ else
20
+ value
21
+ end
22
+ end
23
+ method_names = Array.wrap(options[:methods]).select { |n| respond_to?(n) }
24
+ method_names.each { |n| hash[n] = send(n) }
25
+
26
+ serializable_add_includes(options) do |association, records, opts|
27
+ hash[association] = if records.is_a?(Enumerable)
28
+ records.map { |a| a.serializable_hash(opts) }
29
+ else
30
+ records.serializable_hash(opts)
31
+ end
32
+ end
33
+
34
+ hash
35
+ end
36
+
37
+ def send_to_flydata
38
+ $stdout.puts({ self.class.flydata_table_name => as_flydata }.to_json)
39
+ end
40
+ end
41
+ end
42
+ end