zoho-sdk 0.1.2 → 1.0.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.
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