flydata 0.0.4.4 → 0.0.5.0

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