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 +4 -4
- data/lib/zoho-sdk/analytics/client.rb +101 -48
- data/lib/zoho-sdk/analytics/table.rb +73 -29
- data/lib/zoho-sdk/analytics/workspace.rb +9 -0
- data/lib/zoho-sdk/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5bfe9a0df77523a51afe859e60c155efc81d9d2ae0cc07d27fd1c2b3a50c0ef
|
4
|
+
data.tar.gz: e6808c7cb78263263a3db89b22a8ef7cac77f1a6c1a27fef95ed8c1c48c5c056
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
19
|
+
def initialize(email, client_id, client_secret, refresh_token)
|
13
20
|
@email = email
|
14
|
-
@
|
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
|
-
|
20
|
-
|
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 =
|
26
|
-
|
27
|
-
|
28
|
-
|
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 =
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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 =
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
:
|
8
|
-
:
|
9
|
-
:
|
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(
|
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 =
|
36
|
-
|
37
|
-
|
38
|
-
|
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 =
|
50
|
-
|
51
|
-
|
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 =
|
69
|
-
|
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(
|
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(
|
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 =
|
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
|
-
|
137
|
-
)
|
180
|
+
]
|
138
181
|
|
139
|
-
params =
|
140
|
-
|
141
|
-
|
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",
|
data/lib/zoho-sdk/version.rb
CHANGED
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.
|
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:
|
11
|
+
date: 2021-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|