zoho-sdk 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85e89249820cbabe7bc43696d07a2348c3e7cd668008998926ec75693d7e96f8
4
- data.tar.gz: 92f8fbdd810ee95460be4373b40b7f15ec9d06335f43543294114be8aa8ec0f3
3
+ metadata.gz: f5bfe9a0df77523a51afe859e60c155efc81d9d2ae0cc07d27fd1c2b3a50c0ef
4
+ data.tar.gz: e6808c7cb78263263a3db89b22a8ef7cac77f1a6c1a27fef95ed8c1c48c5c056
5
5
  SHA512:
6
- metadata.gz: 8df3d8ff1363dbcf72f9ed1a0d9a15e9d3cf1d35932333e38b517f8508a7d7544128ef4e84a5803ebf1fe081ebd3b59a6cb198156a0dff67039df0a61ecb47ba
7
- data.tar.gz: de35dc2a2ce57f9bd0837ffddb77e2818a1a613e068796cfef3161afb1c4ae942237873badc57a655f03336c5d470f3951072f188eb3d5e4f49a957bd83993cf
6
+ metadata.gz: 585d362f0b1625eee9aa7f597212a51defcf57f8baa7023745885cd42e9a6d8885706e9ece975b803e65eba45f8c3dcaf0b98add3914519bad8db59b2f96fdac
7
+ data.tar.gz: aa5ede9e43b6ef3695354bb35222a50d08c22534988ad87d2e7af14d82f11526c0094222c951a085298b4078c96ea703e2e9a4f4dde73d8180d2b9cb6d4adf43
@@ -8,25 +8,64 @@ module ZohoSdk::Analytics
8
8
  API_PATH = "api".freeze
9
9
  API_BASE_URL = "#{API_HOSTNAME}/#{API_PATH}".freeze
10
10
 
11
+ # URL to retrieve access token
12
+ API_AUTH_HOSTNAME = "https://accounts.zoho.com".freeze
13
+ API_AUTH_PATH = "oauth/v2/token".freeze
14
+ API_AUTH_BASE_URL = "#{API_AUTH_HOSTNAME}/#{API_AUTH_PATH}".freeze
15
+
16
+ # Allows retrieving workspaces, metadata, and other general data not tied
17
+ # to a specific resource.
11
18
  class Client
12
- def initialize(email, auth_token)
19
+ def initialize(email, client_id, client_secret, refresh_token)
13
20
  @email = email
14
- @auth_token = auth_token
21
+ @client_id = client_id
22
+ @client_secret = client_secret
23
+ @refresh_token = refresh_token
24
+
25
+ # Retrieves access token to authenticate all API requests
26
+ conn =
27
+ Faraday.new(url: API_AUTH_BASE_URL) { |conn| conn.adapter :net_http }
28
+ res =
29
+ conn.post do |req|
30
+ payload = {
31
+ "client_id" => @client_id,
32
+ "client_secret" => @client_secret,
33
+ "refresh_token" => @refresh_token,
34
+ "grant_type" => "refresh_token"
35
+ }
36
+ payload.each { |key, value| req.params[key] = value }
37
+ end
38
+ if res.success?
39
+ data = JSON.parse(res.body)
40
+ if data["access_token"]
41
+ @access_token = data["access_token"]
42
+ else
43
+ nil
44
+ end
45
+ else
46
+ nil
47
+ end
15
48
  end
16
49
 
17
50
  def workspace_metadata
18
51
  get params: {
19
- "ZOHO_ACTION" => "DATABASEMETADATA",
20
- "ZOHO_METADATA" => "ZOHO_CATALOG_LIST"
21
- }
52
+ "ZOHO_ACTION" => "DATABASEMETADATA",
53
+ "ZOHO_METADATA" => "ZOHO_CATALOG_LIST"
54
+ }
22
55
  end
23
56
 
57
+ # Create a new Zoho Analytics workspace
58
+ # @param name [String] Workspace name
59
+ # @param opts [Hash] Optional arguments
60
+ # @option opts [String] :description Workspace description
61
+ # @return [Workspace] Newly created Workspace
24
62
  def create_workspace(name, **opts)
25
- res = get params: {
26
- "ZOHO_ACTION" => "CREATEBLANKDB",
27
- "ZOHO_DATABASE_NAME" => name,
28
- "ZOHO_DATABASE_DESC" => opts[:description] || ""
29
- }
63
+ res =
64
+ get params: {
65
+ "ZOHO_ACTION" => "CREATEBLANKDB",
66
+ "ZOHO_DATABASE_NAME" => name,
67
+ "ZOHO_DATABASE_DESC" => opts[:description] || ""
68
+ }
30
69
  if res.success?
31
70
  data = JSON.parse(res.body)
32
71
  Workspace.new(name, self)
@@ -35,11 +74,11 @@ module ZohoSdk::Analytics
35
74
  end
36
75
  end
37
76
 
77
+ # Retrieve a workspace by name
78
+ # @param name [String] The workspace name
79
+ # @return [Workspace]
38
80
  def workspace(name)
39
- res = get params: {
40
- "ZOHO_ACTION" => "ISDBEXIST",
41
- "ZOHO_DB_NAME" => name
42
- }
81
+ res = get params: { "ZOHO_ACTION" => "ISDBEXIST", "ZOHO_DB_NAME" => name }
43
82
  if res.success?
44
83
  data = JSON.parse(res.body)
45
84
  if data.dig("response", "result", "isdbexist") == "true"
@@ -52,49 +91,63 @@ module ZohoSdk::Analytics
52
91
  end
53
92
  end
54
93
 
94
+ # Wrapper for an HTTP GET request via Faraday
95
+ # @param path [String] URL path component
96
+ # @param params [Hash] Query parameters for the request
97
+ # @return [Faraday::Response]
55
98
  def get(path: nil, params: {})
56
- conn = Faraday.new(url: url_for(path))
57
- res = conn.get do |req|
58
- req.params["ZOHO_OUTPUT_FORMAT"] = "JSON"
59
- req.params["ZOHO_ERROR_FORMAT"] = "JSON"
60
- req.params["ZOHO_API_VERSION"] = "1.0"
61
- req.params["authtoken"] = @auth_token
62
- params.each { |key, value|
63
- req.params[key] = value
64
- }
65
- end
99
+ conn =
100
+ Faraday.new(url: url_for(path)) do |conn|
101
+ conn.adapter :net_http
102
+ conn.headers = {
103
+ "Authorization" => "Zoho-oauthtoken #{@access_token}"
104
+ }
105
+ end
106
+ res =
107
+ conn.get do |req|
108
+ req.params["ZOHO_OUTPUT_FORMAT"] = "JSON"
109
+ req.params["ZOHO_ERROR_FORMAT"] = "JSON"
110
+ req.params["ZOHO_API_VERSION"] = "1.0"
111
+ params.each { |key, value| req.params[key] = value }
112
+ end
66
113
  end
67
114
 
115
+ # Wrapper for posting JSON via Faraday. Used primarily for IMPORT tasks.
116
+ # @param path [String] URL path component
117
+ # @param io [IO] A readable IO object
118
+ # @param params [Hash] Query parameters for the request
119
+ # @return [Faraday::Response]
68
120
  def post_json(path: nil, io:, params: {})
69
- conn = Faraday.new(url: url_for(path)) do |conn|
70
- conn.request :multipart
71
- conn.adapter :net_http
72
- conn.headers = {
73
- 'Content-Type' => 'multipart/form-data'
74
- }
75
- end
76
- res = conn.post do |req|
77
- payload = {
78
- "ZOHO_OUTPUT_FORMAT" => "JSON",
79
- "ZOHO_ERROR_FORMAT" => "JSON",
80
- "ZOHO_API_VERSION" => "1.0",
81
- "authtoken" => @auth_token
82
- }
83
- params.merge(payload).each { |key, value|
84
- req.params[key] = value
85
- }
86
- req.body = {
87
- "ZOHO_FILE" => Faraday::FilePart.new(io, "application/json", "ZOHO_FILE.json")
88
- }
89
- end
121
+ conn =
122
+ Faraday.new(url: url_for(path)) do |conn|
123
+ conn.request :multipart
124
+ conn.adapter :net_http
125
+ conn.headers = {
126
+ "Authorization" => "Zoho-oauthtoken #{@access_token}",
127
+ "Content-Type" => "multipart/form-data"
128
+ }
129
+ end
130
+ res =
131
+ conn.post do |req|
132
+ payload = {
133
+ "ZOHO_OUTPUT_FORMAT" => "JSON",
134
+ "ZOHO_ERROR_FORMAT" => "JSON",
135
+ "ZOHO_API_VERSION" => "1.0"
136
+ }
137
+ params.merge(payload).each { |key, value| req.params[key] = value }
138
+ req.body = {
139
+ "ZOHO_FILE" =>
140
+ Faraday::FilePart.new(io, "application/json", "ZOHO_FILE.json")
141
+ }
142
+ end
90
143
  end
91
144
 
145
+ # Helper function to build a complete URL path that includes email ID
146
+ # and encodes path elements.
92
147
  def url_for(path = nil)
93
148
  parts = [API_BASE_URL, @email]
94
149
  if !path.nil?
95
- if path[0] == "/"
96
- path = path[1..-1]
97
- end
150
+ path = path[1..-1] if path[0] == "/"
98
151
  parts << path
99
152
  end
100
153
  URI.encode(parts.join("/"))
@@ -4,13 +4,16 @@ require "uri"
4
4
  module ZohoSdk::Analytics
5
5
  class Table
6
6
  IMPORT_TYPES = {
7
- :append => "APPEND",
8
- :truncate_add => "TRUNCATEADD",
9
- :update_add => "UPDATEADD"
7
+ append: "APPEND",
8
+ truncate_add: "TRUNCATEADD",
9
+ update_add: "UPDATEADD"
10
10
  }.freeze
11
11
 
12
+ # @return [Workspace] The table's workspace
12
13
  attr_reader :workspace
13
14
  attr_reader :columns
15
+
16
+ # @return [Client] Client object
14
17
  attr_reader :client
15
18
 
16
19
  def initialize(table_name, workspace, client, columns: [])
@@ -25,18 +28,28 @@ module ZohoSdk::Analytics
25
28
  @table_name
26
29
  end
27
30
 
31
+ # Create a new column in the table
32
+ # @param column_name [String] The new column's name
33
+ # @param type [Symbol] Column data type. See {Column::DATA_TYPES}
34
+ # @param opts [Hash] Optional arguments
35
+ # @option opts [Boolean] :required Should the column be mandatory. Defaults to false.
36
+ # @option opts [String] :description The column's description
28
37
  def create_column(column_name, type, **opts)
29
38
  if !Column::DATA_TYPES.values.include?(type)
30
- raise ArgumentError.new("Column type must be one of: #{Column::DATA_TYPES.values.join(', ')}")
39
+ raise ArgumentError.new(
40
+ "Column type must be one of: #{Column::DATA_TYPES.values.join(", ")}"
41
+ )
31
42
  end
32
43
  @type = type
33
44
  @required = opts[:required] || false
34
45
  @description = opts[:description] || ""
35
- res = client.get path: "#{workspace.name}/#{name}", params: {
36
- "ZOHO_ACTION" => "ADDCOLUMN",
37
- "ZOHO_COLUMNNAME" => column_name,
38
- "ZOHO_DATATYPE" => type.to_s.upcase
39
- }
46
+ res =
47
+ client.get path: "#{workspace.name}/#{name}",
48
+ params: {
49
+ "ZOHO_ACTION" => "ADDCOLUMN",
50
+ "ZOHO_COLUMNNAME" => column_name,
51
+ "ZOHO_DATATYPE" => type.to_s.upcase
52
+ }
40
53
  if res.success?
41
54
  data = JSON.parse(res.body)
42
55
  Column.new(column_name, self, client)
@@ -45,11 +58,16 @@ module ZohoSdk::Analytics
45
58
  end
46
59
  end
47
60
 
61
+ # Retrieve a table column by name
62
+ # @param name [String] The column name
63
+ # @return [Column]
48
64
  def column(name)
49
- res = client.get path: "#{workspace.name}/#{name}", params: {
50
- "ZOHO_ACTION" => "ISCOLUMNEXIST",
51
- "ZOHO_COLUMN_NAME" => name
52
- }
65
+ res =
66
+ client.get path: "#{workspace.name}/#{name}",
67
+ params: {
68
+ "ZOHO_ACTION" => "ISCOLUMNEXIST",
69
+ "ZOHO_COLUMN_NAME" => name
70
+ }
53
71
  if res.success?
54
72
  data = JSON.parse(res.body)
55
73
  if data.dig("response", "result", "iscolumnexist") == "true"
@@ -65,14 +83,29 @@ module ZohoSdk::Analytics
65
83
  end
66
84
 
67
85
  def rows
68
- res = client.get path: "#{workspace.name}/#{name}", params: {
69
- "ZOHO_ACTION" => "EXPORT"
70
- }
86
+ res =
87
+ client.get path: "#{workspace.name}/#{name}",
88
+ params: {
89
+ "ZOHO_ACTION" => "EXPORT"
90
+ }
71
91
  end
72
92
 
93
+ # Import data into the table using one of three methods: :append,
94
+ # :truncate_add, or :update_add. The :append option simply adds rows to
95
+ # the end of the table. When using :truncate_add, all rows are first
96
+ # removed and replaced by the new rows. If :update_add is selected,
97
+ # the :matching option must be provided to match rows to be updated by
98
+ # any imported row data.
99
+ # @param import_type [Symbol] Import type. Must be one of: :append, :truncate_add, :update_add
100
+ # @param data [Hash] The data to import. Must be a hash with column names as keys and cell contents as values.
101
+ # @param opts [Hash] Optional arguments
102
+ # @option opts [Array] :matching Array of column names to match when using :update_add
103
+ # @raise [ArgumentError]
73
104
  def import(import_type, data, **opts)
74
105
  if !IMPORT_TYPES.keys.include?(import_type)
75
- raise ArgumentError.new("import_type must be one of: #{IMPORT_TYPES.keys.join(', ')}")
106
+ raise ArgumentError.new(
107
+ "import_type must be one of: #{IMPORT_TYPES.keys.join(", ")}"
108
+ )
76
109
  end
77
110
 
78
111
  params = {
@@ -87,13 +120,18 @@ module ZohoSdk::Analytics
87
120
  if import_type == :update_add
88
121
  matching = opts[:matching] || []
89
122
  if !matching.is_a?(Array) || matching.size < 1
90
- raise ArgumentError.new("Must pass at least one column in `matching` option for UPDATEADD")
123
+ raise ArgumentError.new(
124
+ "Must pass at least one column in `matching` option for UPDATEADD"
125
+ )
91
126
  end
92
127
 
93
- params["ZOHO_MATCHING_COLUMNS"] = matching.join(',')
128
+ params["ZOHO_MATCHING_COLUMNS"] = matching.join(",")
94
129
  end
95
130
 
96
- res = client.post_json path: "#{workspace.name}/#{name}", io: StringIO.new(data.to_json), params: params
131
+ res =
132
+ client.post_json path: "#{workspace.name}/#{name}",
133
+ io: StringIO.new(data.to_json),
134
+ params: params
97
135
  if res.success?
98
136
  data = JSON.parse(res.body)
99
137
  data.dig("response", "result", "importSummary", "successRowCount")
@@ -102,6 +140,9 @@ module ZohoSdk::Analytics
102
140
  end
103
141
  end
104
142
 
143
+ # Safer delete option. Deletes rows from the table based on the given
144
+ # criteria.
145
+ # @param criteria [String] The row criteria to match when deleting rows.
105
146
  def delete(criteria)
106
147
  if criteria.nil?
107
148
  raise ArgumentError.new("Delete criteria must be specified")
@@ -110,10 +151,11 @@ module ZohoSdk::Analytics
110
151
  delete!(criteria)
111
152
  end
112
153
 
154
+ # Unsafe delete. Deletes rows based on the given criteria. If not
155
+ # provided, all rows are deleted.
156
+ # @param criteria [String] The row criteria to match when deleting rows.
113
157
  def delete!(criteria = nil)
114
- params = {
115
- "ZOHO_ACTION" => "DELETE"
116
- }
158
+ params = { "ZOHO_ACTION" => "DELETE" }
117
159
 
118
160
  params["ZOHO_CRITERIA"] = criteria if !criteria.nil?
119
161
 
@@ -126,19 +168,21 @@ module ZohoSdk::Analytics
126
168
  end
127
169
  end
128
170
 
171
+ # Insert a single row into the table
172
+ # @param row [Hash] Hash of row data. Column names are keys, and cell contents are values.
129
173
  def <<(row)
130
174
  params = { "ZOHO_ACTION" => "ADDROW" }
131
- restricted = %w(
175
+ restricted = %w[
132
176
  ZOHO_ACTION
133
177
  ZOHO_API_VERSION
134
178
  ZOHO_OUTPUT_FORMAT
135
179
  ZOHO_ERROR_FORMAT
136
- authtoken
137
- )
180
+ ]
138
181
 
139
- params = row.reject { |key|
140
- !key.is_a?(String) || restricted.include?(key)
141
- }.merge(params)
182
+ params =
183
+ row.reject do |key|
184
+ !key.is_a?(String) || restricted.include?(key)
185
+ end.merge(params)
142
186
 
143
187
  res = client.get path: "#{workspace.name}/#{name}", params: params
144
188
  if res.success?
@@ -33,6 +33,12 @@ module ZohoSdk::Analytics
33
33
  end
34
34
  end
35
35
 
36
+ # Create a new table in the workspace.
37
+ # @param table_name [String] The new table's name
38
+ # @param folder [String] Folder name to create the table under.
39
+ # @param opts [Hash] Optional arguments
40
+ # @option opts [String] :description The table's description
41
+ # @return [Table] Newly created table
36
42
  def create_table(table_name, folder = nil, **opts)
37
43
  table_design = {
38
44
  "TABLENAME" => table_name,
@@ -52,6 +58,9 @@ module ZohoSdk::Analytics
52
58
  end
53
59
  end
54
60
 
61
+ # Retrieve a table by name from the workspace
62
+ # @param table_name [String] The table name
63
+ # @return [Table]
55
64
  def table(table_name)
56
65
  res = client.get path: name, params: {
57
66
  "ZOHO_ACTION" => "ISVIEWEXIST",
@@ -1,3 +1,3 @@
1
1
  module ZohoSdk
2
- VERSION = "0.1.2"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zoho-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Holden
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-30 00:00:00.000000000 Z
11
+ date: 2021-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday