mode 0.0.17 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -134
  3. data/lib/connect.rb +5 -5
  4. data/lib/mode.rb +12 -8
  5. data/lib/mode/api/form.rb +30 -8
  6. data/lib/mode/api/request.rb +34 -16
  7. data/lib/mode/commands/connect.rb +0 -8
  8. data/lib/mode/commands/import.rb +1 -1
  9. data/lib/mode/config.rb +9 -1
  10. data/lib/mode/connector/commands/select_report_run_dataset.rb +84 -0
  11. data/lib/mode/connector/commands/select_table_metadata.rb +113 -0
  12. data/lib/mode/connector/daemon.rb +3 -3
  13. data/lib/mode/connector/data_sources/base.rb +191 -0
  14. data/lib/mode/connector/databases/rdbms.rb +69 -0
  15. data/lib/mode/connector/dataset.rb +0 -1
  16. data/lib/mode/connector/dispatcher.rb +27 -0
  17. data/lib/mode/connector/poller.rb +2 -3
  18. data/lib/mode/connector/registrar.rb +74 -16
  19. data/lib/mode/connector/scheduler.rb +24 -15
  20. data/lib/mode/connector/selector.rb +1 -0
  21. data/lib/mode/connector/tables/rdbms.rb +130 -0
  22. data/lib/mode/version.rb +2 -2
  23. data/mode.gemspec +2 -0
  24. data/script/console.rb +11 -0
  25. data/spec/api/form_spec.rb +17 -8
  26. data/spec/api/request_spec.rb +3 -3
  27. data/spec/commands/connect_spec.rb +1 -10
  28. data/spec/config_spec.rb +1 -1
  29. data/spec/connector/commands/select_report_run_dataset_spec.rb +96 -0
  30. data/spec/connector/commands/select_table_metadata_spec.rb +115 -0
  31. data/spec/connector/{data_source_spec.rb → data_sources/base_spec.rb} +8 -8
  32. data/spec/connector/databases/rdbms_spec.rb +43 -0
  33. data/spec/connector/dispatcher_spec.rb +47 -0
  34. data/spec/connector/poller_spec.rb +2 -1
  35. data/spec/connector/registrar_spec.rb +111 -26
  36. data/spec/connector/scheduler_spec.rb +12 -31
  37. data/spec/connector/selector_spec.rb +1 -1
  38. data/spec/connector/tables/rdbms_spec.rb +85 -0
  39. metadata +49 -15
  40. data/lib/mode/connector/connect.rb +0 -11
  41. data/lib/mode/connector/data_source.rb +0 -171
  42. data/lib/mode/connector/message.rb +0 -31
  43. data/lib/mode/connector/processor.rb +0 -58
  44. data/lib/mode/connector/uploader.rb +0 -54
  45. data/spec/connector/message_spec.rb +0 -22
  46. data/spec/connector/processor_spec.rb +0 -93
  47. data/spec/connector/uploader_spec.rb +0 -57
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 74f1b2ce9baad12179eacc6a688af0cc4c1a63ea
4
- data.tar.gz: 3d8f7f5cab8366b0eb3bf454c62e4374ce9fccf3
3
+ metadata.gz: ba4667740570363fcc09c91a5ab6306678f54731
4
+ data.tar.gz: 9d1e27811b305bd7f81da09fdb0794583852744e
5
5
  SHA512:
6
- metadata.gz: 1e288584297b41d8e45ce8886b987531dc5aa77650a9dc188426e25c1b1f47727fd7b6c92a378bad2c3df863c6ddf4671eddb5f48e2b3cea55635cd2da158061
7
- data.tar.gz: b091fee08b2215bb46ead6ec37c207db6641f53fa4b71b8a59e012f930d998dfb22d438211ded8f4b7997d0c090f98854914a7d25bdc463283ab5cbdc1895cca
6
+ metadata.gz: 6a820c70b52f95e12f71c7a50a37975038986ebe83cdd7769c778f6ee6d60159187d6d42ad78005ef01f045133217203540e63f99edcb7e4fcc28c913b854f76
7
+ data.tar.gz: dfd181018bf5f35d3b5c5f1f41dc8713daa8b1291f4fcd75fc2609e41796b38fa4dfd2e8c208dbaea1c731e9430fa106595816e629a4116170058a0b9408ca14
data/README.md CHANGED
@@ -2,139 +2,7 @@
2
2
 
3
3
  This gem provides command line tools for interacting with the Mode Analytics APIs.
4
4
 
5
- [![Build Status](https://magnum.travis-ci.com/mode/mode-ruby.png?token=i2TyUW8sMD41B46pRCpz&branch=master)](https://magnum.travis-ci.com/mode/mode-ruby)
5
+ [![Build Status](https://travis-ci.org/mode/mode-ruby.png?branch=v0.0.17)](https://travis-ci.org/mode/mode-ruby)
6
6
  [![Code Climate](https://codeclimate.com/repos/52a90897f3ea0044b10034de/badges/68f57393128c9c3fe2c5/gpa.png)](https://codeclimate.com/repos/52a90897f3ea0044b10034de/feed)
7
7
 
8
-
9
- ## Install Mode
10
-
11
- **Mode requires Ruby 1.9 or JRuby 1.7 or newer**
12
-
13
- For the best performance and compatibility we recommend JRuby.
14
-
15
- If you don't currently have a suitable ruby or aren't sure then follow [these directions](doc/install_ruby.md) to install it before continuing.
16
-
17
- ```
18
- gem install mode
19
- ```
20
-
21
- ## Logging In
22
-
23
- Before you use the mode gem you'll need to login.
24
-
25
- The login process allows you to authorize the machine to connect via
26
- the API with the use of an API access token. The first time you use this
27
- command the it will look as follows:
28
-
29
- ```
30
- $ mode login
31
- Enter your Mode credentials:
32
- Username: besquared
33
- Password:
34
-
35
- No API tokens found, would you like to create a new token? [y/n] y
36
-
37
- Choose a token name: Connector
38
- Updated configuration at /Users/josh/.mode/config.yml
39
- ```
40
-
41
- The token name is just a descriptive name that will help you remember what the token is used for.
42
-
43
- Tokens can be renamed or deleted at any time from your account settings page in Mode.
44
-
45
- ## Adding Data Sources
46
-
47
- Open the Mode configuration file in your favorite text editor (I'm using sublime text)
48
-
49
- ```
50
- $ subl ~/.mode/config.yml
51
- ```
52
-
53
- A sample data sources configuration is listed which you can copy to the bottom of your config file and modify:
54
-
55
- ```
56
- data_sources:
57
- development:
58
- adapter: jdbc:postgresql
59
- host: localhost
60
- database: development
61
- username: postgres
62
- password:
63
-
64
- warehouse:
65
- adapter: jdbc:redshift
66
- host: hostname.redshift.amazonaws.com
67
- port: 5439
68
- database: dev
69
- username:
70
- password:
71
- ```
72
-
73
- ## Database Drivers
74
-
75
- If you're using JRuby then you can load JDBC drivers by copying the driver's jar files into Mode's drivers directory
76
-
77
- Example for teradata:
78
-
79
- ```
80
- cp terajdbc4.jar ~/mode/drivers
81
- cp tdgssconfig.jar ~/mode/drivers
82
- ```
83
-
84
- For ruby1.9+ you need to install the correct driver gem and libraries
85
-
86
- ```
87
- # PostgreSQL
88
- gem install pg
89
-
90
- # Redshift
91
- gem install sequel_redshift
92
-
93
- # MySQL
94
- gem install mysql2
95
-
96
- # Oracle 9i+
97
- gem install oci8
98
-
99
- # SQL Server & Azure
100
- gem install tiny_tds
101
-
102
- # DB2
103
- gem install ibm_db
104
- ```
105
-
106
- ## Verifying your API and driver configuration
107
-
108
- You can verify that your data sources are correct by using the verify command:
109
-
110
- ```
111
- $ mode connect verify
112
- ```
113
-
114
- ## Controlling the connector
115
-
116
- Starting
117
-
118
- ```
119
- $ mode connect start
120
- ```
121
-
122
- Restarting
123
-
124
- ```
125
- $ mode connect restart
126
- ```
127
-
128
- Stopping
129
-
130
- ```
131
- $ mode connect stop
132
- ```
133
-
134
- ## Connector logging
135
-
136
- The connect logs all its activity and errors to a log file that rotates weekly by default.
137
-
138
- ```
139
- tail -f ~/.mode/log/mode.log
140
- ```
8
+ To learn how to install and use this gem please visit [Mode Analytics Help](http://help.modeanalytics.com)
@@ -4,21 +4,21 @@ $LOAD_PATH.unshift File.dirname(__FILE__)
4
4
 
5
5
  require 'mode'
6
6
 
7
- runner = Mode::Connector::Daemon.new(:max_jobs => ARGV[0] || 4)
7
+ daemon = Mode::Connector::Daemon.new(:max_jobs => ARGV[0] || 4)
8
8
 
9
9
  trap("INT") do
10
10
  Mode::Logger.instance.info("connect.rb", "Received INT signal, shutting down.")
11
- runner.stop
11
+ daemon.stop
12
12
  end
13
13
 
14
14
  trap("HUP") do
15
15
  Mode::Logger.instance.info("connect.rb", "Received HUP signal, shutting down.")
16
- runner.stop
16
+ daemon.stop
17
17
  end
18
18
 
19
19
  trap("TERM") do
20
20
  Mode::Logger.instance.info("connect.rb", "Received TERM signal, shutting down.")
21
- runner.stop
21
+ daemon.stop
22
22
  end
23
23
 
24
- runner.start
24
+ daemon.start
@@ -30,19 +30,23 @@ require 'mode/api/request'
30
30
 
31
31
  # Core
32
32
  require 'mode/connector/type_map'
33
- require 'mode/connector/data_source'
33
+ require 'mode/connector/tables/rdbms'
34
+ require 'mode/connector/databases/rdbms'
35
+ require 'mode/connector/data_sources/base'
34
36
 
35
- # Operations
37
+ # Models
38
+ require 'mode/connector/dataset'
39
+
40
+ # Commands
41
+ require 'mode/connector/commands/select_table_metadata'
42
+ require 'mode/connector/commands/select_report_run_dataset'
43
+
44
+ # Core Operations
36
45
  require 'mode/connector/registrar'
37
46
  require 'mode/connector/scheduler'
38
47
  require 'mode/connector/poller'
39
- require 'mode/connector/processor'
40
48
  require 'mode/connector/selector'
41
- require 'mode/connector/uploader'
42
-
43
- # Models
44
- require 'mode/connector/dataset'
45
- require 'mode/connector/message'
49
+ require 'mode/connector/dispatcher'
46
50
 
47
51
  # Daemon
48
52
  require 'mode/connector/daemon'
@@ -22,32 +22,54 @@ module Mode
22
22
  def submit!(params = {})
23
23
  inputs = content['input']
24
24
  params = input_values(inputs, params)
25
- Mode::API::Request.send(method.to_sym, action, params)
25
+ Mode::API::Request.send(method.to_sym, action, params, request_opts)
26
26
  end
27
27
 
28
28
  private
29
29
 
30
+ def request_opts
31
+ {
32
+ :content_type => content_type
33
+ }.delete_if{|k, v| v.nil? }
34
+ end
35
+
36
+ def content_type
37
+ content['content_type']
38
+ end
39
+
30
40
  def input_values(inputs, params = {})
31
41
  merged = {}
32
42
  return merged if inputs.nil?
33
43
 
34
44
  inputs.each do |name, value|
35
- if value.instance_of?(Hash)
36
- if value.has_key?('value')
37
- # we reached a leaf
38
- merged[name] = params[name] || value['value']
45
+ if name =~ /\[\]$/
46
+ clean_name = name.gsub(/\[\]$/, '')
47
+ param_value = params[clean_name.to_sym]
48
+
49
+ merged[clean_name] = param_value.map do |item|
50
+ input_values(value, item)
51
+ end unless param_value.nil?
52
+
53
+ elsif value.instance_of?(Hash)
54
+ param_value = params[name.to_sym]
55
+
56
+ if is_leaf?(value)
57
+ merged[name] = param_value.nil? ? value['value'] : param_value
39
58
  else
40
- # we're at an intermediate node
41
- merged[name] = input_values(value, params[name])
59
+ merged[name] = input_values(value, param_value) unless param_value.nil?
42
60
  end
43
61
  else
44
- # non-field node
62
+ # non-field node (WHAT DO?)
45
63
  # merged[name] = params[name]
46
64
  end
47
65
  end
48
66
 
49
67
  merged
50
68
  end
69
+
70
+ def is_leaf?(value)
71
+ value.find{ |k, v| v.instance_of?(Hash) }.nil?
72
+ end
51
73
  end
52
74
  end
53
75
  end
@@ -1,6 +1,7 @@
1
1
  require 'uri'
2
2
  require 'json'
3
3
  require 'faraday'
4
+ require 'faraday_middleware'
4
5
 
5
6
  module Mode
6
7
  module API
@@ -13,11 +14,16 @@ module Mode
13
14
  @params = params
14
15
  end
15
16
 
16
- def perform(request_opts = {})
17
+ def perform(opts = {})
17
18
  response = http.send(method.to_sym) do |request|
18
19
  request.url path
19
20
  request.body = params unless params.empty?
20
- request.options[:timeout] = request_opts.fetch(:timeout, 30)
21
+
22
+ if opts[:content_type]
23
+ request.headers['Content-Type'] = opts[:content_type]
24
+ end
25
+
26
+ request.options[:timeout] = opts.fetch(:timeout, 30)
21
27
  end
22
28
 
23
29
  response.success? ? success(response) : error(response)
@@ -56,7 +62,7 @@ module Mode
56
62
  response_lines = response.body.split("\n")
57
63
 
58
64
  Mode::Logger.instance.send(level,
59
- "API::Request", "#{response.status}",
65
+ self.class.name, "#{response.status}",
60
66
  ["HOST #{self.class.base_url}", "#{method.upcase} #{path}", *response_lines])
61
67
  end
62
68
 
@@ -104,24 +110,28 @@ module Mode
104
110
  # Request Methods
105
111
  #
106
112
 
107
- def head(path)
108
- new(:head, resolve_path(path)).perform
113
+ def head(path, opts = {})
114
+ new(:head, resolve_path(path)).perform(opts)
115
+ end
116
+
117
+ def get(path, params = {}, opts = {})
118
+ new(:get, resolve_path(path), params).perform(opts)
109
119
  end
110
120
 
111
- def get(path, params = {})
112
- new(:get, resolve_path(path), params).perform
121
+ def post(path, params = {}, opts = {})
122
+ new(:post, resolve_path(path), params).perform(opts)
113
123
  end
114
124
 
115
- def post(path, params = {})
116
- new(:post, resolve_path(path), params).perform
125
+ def put(path, params = {}, opts = {})
126
+ new(:put, resolve_path(path), params).perform(opts)
117
127
  end
118
128
 
119
- def put(path, params = {})
120
- new(:put, resolve_path(path), params).perform
129
+ def patch(path, params = {}, opts = {})
130
+ new(:patch, resolve_path(path), params).perform(opts)
121
131
  end
122
132
 
123
- def delete(path, params = {})
124
- new(:delete, resolve_path(path), params).perform
133
+ def delete(path, params = {}, opts = {})
134
+ new(:delete, resolve_path(path), params).perform(opts)
125
135
  end
126
136
 
127
137
  def resolve_path(path)
@@ -140,10 +150,12 @@ module Mode
140
150
  "#{base_path}/packages"
141
151
  end
142
152
 
153
+ # user.access_tokens
143
154
  def access_tokens_path
144
155
  "#{base_path}/access_tokens"
145
156
  end
146
157
 
158
+ # access_token.data_source_connections
147
159
  def data_source_connections_path
148
160
  "#{base_path}/data_source_connections"
149
161
  end
@@ -153,6 +165,7 @@ module Mode
153
165
  [data_source_connections_path, token].join('/').strip
154
166
  end
155
167
 
168
+ # connection.links('messages').follow()
156
169
  def data_source_connection_messages_path
157
170
  [data_source_connection_path, 'messages'].join('/').strip
158
171
  end
@@ -162,10 +175,15 @@ module Mode
162
175
  #
163
176
  def http(options = {})
164
177
  @_http ||= Faraday.new(:url => base_url) do |builder|
165
- builder.request :multipart # adds small overhead to each request
178
+ builder.request :multipart # adds small overhead to each request
166
179
  builder.request :url_encoded
167
- builder.adapter Faraday.default_adapter
180
+ builder.request :json
181
+
168
182
  builder.basic_auth(username, password)
183
+
184
+ builder.use FaradayMiddleware::FollowRedirects, limit: 5
185
+
186
+ builder.adapter Faraday.default_adapter
169
187
  end
170
188
  end
171
189
 
@@ -197,7 +215,7 @@ module Mode
197
215
  when :staging
198
216
  "staging.modeanalytics.com"
199
217
  else
200
- "stealth.modeanalytics.com"
218
+ "modeanalytics.com"
201
219
  end
202
220
  end
203
221
 
@@ -14,8 +14,6 @@ module Mode
14
14
 
15
15
  def execute(options = {})
16
16
  validate_config!
17
-
18
- register!
19
17
  run_command!
20
18
  end
21
19
 
@@ -30,12 +28,6 @@ module Mode
30
28
 
31
29
  private
32
30
 
33
- def register!
34
- if ['start', 'restart'].include?(command)
35
- Mode::Connector::Registrar.new(configuration).perform!
36
- end
37
- end
38
-
39
31
  def run_command!
40
32
  if command == 'status'
41
33
  daemon.alive?
@@ -64,7 +64,7 @@ module Mode
64
64
  end
65
65
 
66
66
  def submit_import_form(resource, params)
67
- resource.forms('import').submit!('import' => params)
67
+ resource.forms('import').submit!(:import => params)
68
68
  end
69
69
 
70
70
  def parse_uploaded_response(content)
@@ -56,6 +56,14 @@ module Mode
56
56
  new(path, filename)
57
57
  end
58
58
 
59
+ def load_drivers!
60
+ if RUBY_PLATFORM == 'java'
61
+ Dir[File.join(drivers_dir, '*.jar')].each do |driver|
62
+ load driver
63
+ end
64
+ end
65
+ end
66
+
59
67
  def default_dir
60
68
  File.expand_path("~/.mode")
61
69
  end
@@ -82,7 +90,7 @@ module Mode
82
90
 
83
91
  @data_sources ||= []
84
92
  (config['data_sources'] || []).each do |name, props|
85
- @data_sources << Mode::Connector::DataSource.new(name, props)
93
+ @data_sources << Mode::Connector::DataSources::Base.build(name, props)
86
94
  end
87
95
  end
88
96