bigquery-client 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env.example +3 -0
- data/.gitignore +1 -0
- data/README.md +78 -32
- data/bigquery-client.gemspec +6 -3
- data/lib/bigquery-client/client.rb +3 -1
- data/lib/bigquery-client/datasets.rb +42 -0
- data/lib/bigquery-client/jobs.rb +64 -0
- data/lib/bigquery-client/projects.rb +6 -5
- data/lib/bigquery-client/tabledata.rb +13 -4
- data/lib/bigquery-client/tables.rb +45 -43
- data/lib/bigquery-client/version.rb +1 -1
- data/test/helper.rb +32 -3
- data/test/test_client.rb +3 -165
- data/test/test_datasets.rb +25 -0
- data/test/test_jobs.rb +22 -0
- data/test/test_projects.rb +15 -0
- data/test/test_tabledata.rb +29 -0
- data/test/test_tables.rb +41 -0
- metadata +67 -14
- data/.travis.yml +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edc1852a762f3a210c21f52f68cc4e86f1b4d63d
|
4
|
+
data.tar.gz: 8b5e41ca6514e45f48734a1ee373f486fee4a8f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 517febf8c68c0b83fa566673d7caf0492067a950133b67d03dc5ec587390b994354ba222b920332b5270479ad8016f7aa9327339132f30a50c168b0fcbd2ef65
|
7
|
+
data.tar.gz: dad3b8e445ad4f7bf2028f7f285aaaf4c1a69e610bcaff90f7b2c661c4c3dde18c0de26243d589edd325b3ee4ac693798f16deac40a66ae9e027f132d5bff04c
|
data/.env.example
ADDED
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# BigQuery Client
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/bigquery-client.svg)](http://badge.fury.io/rb/bigquery-client)
|
4
|
-
[![Build Status](https://travis-ci.org/ttanimichi/bigquery-client.svg)](https://travis-ci.org/ttanimichi/bigquery-client)
|
5
4
|
|
6
5
|
A Ruby interface to the BigQuery API.
|
7
6
|
|
@@ -25,48 +24,46 @@ client = BigQuery::Client.new(
|
|
25
24
|
auth_method: "private_key"
|
26
25
|
)
|
27
26
|
|
28
|
-
client.
|
29
|
-
|
27
|
+
client.sql "SELECT * FROM publicdata:samples.wikipedia LIMIT 10"
|
30
28
|
```
|
31
29
|
|
32
30
|
## Available API methods
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
| Resource type | Method | Function
|
37
|
-
|
38
|
-
|
|
39
|
-
|
|
40
|
-
| Tables |
|
41
|
-
| Tables |
|
42
|
-
| Tables |
|
43
|
-
| Tables | patch | `patch_table`
|
44
|
-
| Tables | update | `update_table`
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
| Datasets |
|
52
|
-
| Datasets |
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
| Projects | list | `list_projects` | :white_check_mark: |
|
32
|
+
https://cloud.google.com/bigquery/docs/reference/v2/
|
33
|
+
|
34
|
+
| Resource type | Method | Function | Support |
|
35
|
+
|---------------|-----------------|-------------------------------|:---------------------:|
|
36
|
+
| Tabledata | insertAll | `insert`, `insert_all` | :white_check_mark: |
|
37
|
+
| Tabledata | list | `list_tabledata` | :white_check_mark: |
|
38
|
+
| Tables | list | `tables`, `list_tables` | :white_check_mark: |
|
39
|
+
| Tables | get | `fetch_schema`, `fetch_table` | :white_check_mark: |
|
40
|
+
| Tables | insert | `create_table` | :white_check_mark: |
|
41
|
+
| Tables | patch | `patch_table` | :white_check_mark: |
|
42
|
+
| Tables | update | `update_table` | :white_check_mark: |
|
43
|
+
| Tables | delete | `delete_table` | :white_check_mark: |
|
44
|
+
| Jobs | query | `sql`, `jobs_query` | :white_check_mark: |
|
45
|
+
| Jobs | insert | `load` | :white_check_mark: |
|
46
|
+
| Jobs | list | `jobs` | :white_check_mark: |
|
47
|
+
| Jobs | get | `fetch_job` | :white_check_mark: |
|
48
|
+
| Jobs | getQueryResults | `query_results` | :white_check_mark: |
|
49
|
+
| Datasets | list | `datasets`, `list_datasets` | :white_check_mark: |
|
50
|
+
| Datasets | get | `fetch_dataset` | :white_medium_square: |
|
51
|
+
| Datasets | insert | `create_dataset` | :white_check_mark: |
|
52
|
+
| Datasets | patch | `patch_dataset` | :white_medium_square: |
|
53
|
+
| Datasets | update | `update_dataset` | :white_medium_square: |
|
54
|
+
| Datasets | delete | `delete_dataset` | :white_check_mark: |
|
55
|
+
| Projects | list | `projects`, `list_projects` | :white_check_mark: |
|
59
56
|
|
60
57
|
## Usage
|
61
58
|
|
62
59
|
```ruby
|
63
60
|
# insert
|
64
|
-
client.insert("your_table",
|
61
|
+
client.insert("your_table", nickname: "john", age: 42)
|
65
62
|
|
66
63
|
# insert multiple rows
|
67
64
|
rows = [
|
68
|
-
{
|
69
|
-
{
|
65
|
+
{ nickname: "foo", age: 43 },
|
66
|
+
{ nickname: "bar", age: 44 }
|
70
67
|
]
|
71
68
|
client.insert("your_table", rows)
|
72
69
|
|
@@ -77,17 +74,66 @@ schema = [
|
|
77
74
|
]
|
78
75
|
client.create_table("new_table", schema)
|
79
76
|
|
77
|
+
# SQL
|
78
|
+
client.sql "SELECT * FROM your_dataset.your_table LIMIT 100"
|
79
|
+
|
80
|
+
# SQL (public data)
|
81
|
+
client.sql "SELECT * FROM publicdata:samples.wikipedia LIMIT 10"
|
82
|
+
|
83
|
+
# tables
|
84
|
+
client.tables
|
85
|
+
#=> ["your_table", "your_table2", "your_table3"]
|
86
|
+
|
87
|
+
# datasets
|
88
|
+
client.datasets
|
89
|
+
#=> ["your_dataset", "your_dataset2"]
|
90
|
+
|
80
91
|
# fetch schema
|
81
92
|
client.fetch_schema("your_table")
|
82
|
-
#=> [{"name"=>"
|
93
|
+
#=> [{"name"=>"nickname", "type"=>"STRING"}, {"name"=>"age", "type"=>"INTEGER"}]
|
94
|
+
|
95
|
+
# delete table
|
96
|
+
client.delete_table('your_table')
|
97
|
+
|
98
|
+
# create dataset
|
99
|
+
client.create_dataset('your_dataset')
|
100
|
+
|
101
|
+
# delete dataset
|
102
|
+
client.delete_dataset('your_dataset')
|
83
103
|
```
|
84
104
|
|
85
105
|
## TODO
|
86
106
|
|
87
107
|
- [ ] Support all API methods
|
108
|
+
- [ ] Improve `load`
|
109
|
+
- Support load-from-GCS flow and POST-request flow
|
110
|
+
- ref. https://cloud.google.com/bigquery/loading-data-into-bigquery
|
88
111
|
- [ ] Support OAuth installed application credentials
|
89
112
|
- [ ] Google API discovery expiration
|
90
113
|
|
114
|
+
## How to run tests
|
115
|
+
|
116
|
+
Please create a file named `.env` on the root of this repository. You can use `.env.example` file as a template.
|
117
|
+
|
118
|
+
```
|
119
|
+
% cp .env.example .env
|
120
|
+
```
|
121
|
+
|
122
|
+
and edit `.env` file properly.
|
123
|
+
|
124
|
+
```
|
125
|
+
BIGQUERY_PROJECT=your-project-42
|
126
|
+
BIGQUERY_EMAIL=1234567890@developer.gserviceaccount.com
|
127
|
+
BIGQUERY_PRIVATE_KEY_PATH=/path/to/keyfile.p12
|
128
|
+
```
|
129
|
+
|
130
|
+
Then run tests.
|
131
|
+
|
132
|
+
```
|
133
|
+
% bundle install
|
134
|
+
% bundle exec rake
|
135
|
+
```
|
136
|
+
|
91
137
|
## Contributing
|
92
138
|
|
93
139
|
1. Fork it ( https://github.com/ttanimichi/bigquery-client/fork )
|
data/bigquery-client.gemspec
CHANGED
@@ -22,7 +22,10 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.add_development_dependency 'rake'
|
24
24
|
spec.add_development_dependency 'bundler'
|
25
|
-
spec.add_development_dependency '
|
26
|
-
spec.add_development_dependency '
|
27
|
-
spec.add_development_dependency '
|
25
|
+
spec.add_development_dependency 'test-unit', '~> 3.0.0'
|
26
|
+
spec.add_development_dependency 'dotenv', '~> 1.0.0'
|
27
|
+
spec.add_development_dependency 'awesome_print'
|
28
|
+
spec.add_development_dependency 'pry'
|
29
|
+
spec.add_development_dependency 'pry-doc'
|
30
|
+
spec.add_development_dependency 'pry-byebug'
|
28
31
|
end
|
@@ -22,7 +22,9 @@ module BigQuery
|
|
22
22
|
params[:parameters] ||= {}
|
23
23
|
params[:parameters][:projectId] ||= @project
|
24
24
|
params[:parameters][:datasetId] ||= @dataset
|
25
|
-
client.execute(params)
|
25
|
+
result = client.execute(params)
|
26
|
+
handle_error(result) if result.error?
|
27
|
+
JSON.parse(result.body) unless result.body.empty?
|
26
28
|
end
|
27
29
|
|
28
30
|
def bigquery
|
@@ -2,5 +2,47 @@
|
|
2
2
|
|
3
3
|
module BigQuery
|
4
4
|
module Datasets
|
5
|
+
def datasets
|
6
|
+
list_datasets['datasets'].map {|dataset| dataset['datasetReference']['datasetId'] }
|
7
|
+
end
|
8
|
+
|
9
|
+
def list_datasets
|
10
|
+
access_api(
|
11
|
+
api_method: bigquery.datasets.list
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch_dataset
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_dataset(name)
|
20
|
+
access_api(
|
21
|
+
api_method: bigquery.datasets.insert,
|
22
|
+
body_object: {
|
23
|
+
datasetReference: {
|
24
|
+
datasetId: name
|
25
|
+
}
|
26
|
+
}
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def patch_dataset
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
|
34
|
+
def update_dataset
|
35
|
+
raise NotImplementedError
|
36
|
+
end
|
37
|
+
|
38
|
+
def delete_dataset(name)
|
39
|
+
access_api(
|
40
|
+
api_method: bigquery.datasets.delete,
|
41
|
+
parameters: {
|
42
|
+
datasetId: name,
|
43
|
+
deleteContents: true
|
44
|
+
}
|
45
|
+
)
|
46
|
+
end
|
5
47
|
end
|
6
48
|
end
|
data/lib/bigquery-client/jobs.rb
CHANGED
@@ -2,5 +2,69 @@
|
|
2
2
|
|
3
3
|
module BigQuery
|
4
4
|
module Jobs
|
5
|
+
def sql(query, options = {})
|
6
|
+
result = jobs_query(query, options)
|
7
|
+
names = result['schema']['fields'].map {|field| field['name'] }
|
8
|
+
types = result['schema']['fields'].map {|field| field['type'] }
|
9
|
+
records = result['rows'].map {|row| row['f'].map {|record| record['v'] } }
|
10
|
+
convert(records, types).map { |values| [names, values].transpose.to_h }
|
11
|
+
end
|
12
|
+
|
13
|
+
def jobs_query(query, options = {})
|
14
|
+
default = { query: query, timeoutMs: 600_000 }
|
15
|
+
access_api(
|
16
|
+
api_method: bigquery.jobs.query,
|
17
|
+
body_object: default.merge(options)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def load(options = {})
|
22
|
+
access_api(
|
23
|
+
api_method: bigquery.jobs.insert,
|
24
|
+
body_object: {
|
25
|
+
configuration: {
|
26
|
+
load: options
|
27
|
+
}
|
28
|
+
}
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def jobs(options = {})
|
33
|
+
access_api(
|
34
|
+
api_method: bigquery.jobs.list,
|
35
|
+
parameters: options
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch_job(id, options = {})
|
40
|
+
access_api(
|
41
|
+
api_method: bigquery.jobs.get,
|
42
|
+
parameters: { jobId: id }.merge(options)
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def query_results(id, options = {})
|
47
|
+
access_api(
|
48
|
+
api_method: bigquery.jobs.get_query_results,
|
49
|
+
parameters: { jobId: id }.merge(options)
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def convert(records, types)
|
56
|
+
records.map do |values|
|
57
|
+
values.map.with_index do |value, index|
|
58
|
+
case types[index]
|
59
|
+
when 'INTEGER'
|
60
|
+
value.to_i
|
61
|
+
when 'BOOLEAN'
|
62
|
+
value == 'true'
|
63
|
+
else
|
64
|
+
value
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
5
69
|
end
|
6
70
|
end
|
@@ -2,13 +2,14 @@
|
|
2
2
|
|
3
3
|
module BigQuery
|
4
4
|
module Projects
|
5
|
+
def projects
|
6
|
+
list_projects['projects'].map {|project| project['id'] }
|
7
|
+
end
|
8
|
+
|
5
9
|
def list_projects
|
6
|
-
|
7
|
-
api_method: bigquery.projects.list
|
8
|
-
parameters: {
|
9
|
-
}
|
10
|
+
access_api(
|
11
|
+
api_method: bigquery.projects.list
|
10
12
|
)
|
11
|
-
JSON.parse(result.body)
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module BigQuery
|
4
4
|
module Tabledata
|
5
|
-
def insert(table,
|
6
|
-
rows =
|
7
|
-
|
5
|
+
def insert(table, arg)
|
6
|
+
rows = arg.is_a?(Array) ? arg : [arg]
|
7
|
+
access_api(
|
8
8
|
api_method: bigquery.tabledata.insert_all,
|
9
9
|
parameters: {
|
10
10
|
tableId: table
|
@@ -13,7 +13,16 @@ module BigQuery
|
|
13
13
|
rows: rows.map { |row| { json: row } }
|
14
14
|
}
|
15
15
|
)
|
16
|
-
|
16
|
+
end
|
17
|
+
alias_method :insert_all, :insert
|
18
|
+
|
19
|
+
def list_tabledata(table)
|
20
|
+
access_api(
|
21
|
+
api_method: bigquery.tabledata.list,
|
22
|
+
parameters: {
|
23
|
+
tableId: table
|
24
|
+
}
|
25
|
+
)
|
17
26
|
end
|
18
27
|
end
|
19
28
|
end
|
@@ -2,77 +2,79 @@
|
|
2
2
|
|
3
3
|
module BigQuery
|
4
4
|
module Tables
|
5
|
-
def
|
6
|
-
|
7
|
-
api_method: bigquery.tables.insert,
|
8
|
-
body_object: {
|
9
|
-
tableReference: {
|
10
|
-
tableId: name
|
11
|
-
},
|
12
|
-
schema: {
|
13
|
-
fields: schema
|
14
|
-
}
|
15
|
-
}
|
16
|
-
)
|
17
|
-
handle_error(result) if result.error?
|
5
|
+
def tables(options = {})
|
6
|
+
(list_tables(options)['tables'] || []).map {|t| t['tableReference']['tableId'] }
|
18
7
|
end
|
19
8
|
|
20
9
|
def list_tables(options = {})
|
21
|
-
|
10
|
+
access_api(
|
22
11
|
api_method: bigquery.tables.list,
|
23
12
|
parameters: options
|
24
13
|
)
|
25
|
-
handle_error(result) if result.error?
|
26
|
-
JSON.parse(result.body)
|
27
14
|
end
|
28
15
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
16
|
+
def fetch_schema(table)
|
17
|
+
fetch_table(table)['schema']['fields']
|
18
|
+
end
|
19
|
+
|
20
|
+
def fetch_table(table)
|
21
|
+
access_api(
|
22
|
+
api_method: bigquery.tables.get,
|
32
23
|
parameters: {
|
33
|
-
tableId:
|
34
|
-
}
|
35
|
-
body_object: options
|
24
|
+
tableId: table
|
25
|
+
}
|
36
26
|
)
|
37
|
-
handle_error(result) if result.error?
|
38
|
-
JSON.parse(result.body)
|
39
27
|
end
|
40
28
|
|
41
|
-
def
|
42
|
-
|
29
|
+
def create_table(table, schema)
|
30
|
+
access_api(
|
31
|
+
api_method: bigquery.tables.insert,
|
32
|
+
body_object: {
|
33
|
+
tableReference: {
|
34
|
+
tableId: table
|
35
|
+
},
|
36
|
+
schema: {
|
37
|
+
fields: schema
|
38
|
+
}
|
39
|
+
}
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def patch_table(table, schema)
|
44
|
+
access_api(
|
43
45
|
api_method: bigquery.tables.patch,
|
44
46
|
parameters: {
|
45
|
-
tableId:
|
47
|
+
tableId: table
|
46
48
|
},
|
47
|
-
body_object:
|
49
|
+
body_object: {
|
50
|
+
schema: {
|
51
|
+
fields: schema
|
52
|
+
}
|
53
|
+
}
|
48
54
|
)
|
49
|
-
handle_error(result) if result.error?
|
50
|
-
JSON.parse(result.body)
|
51
55
|
end
|
52
56
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
def fetch_table_info(table)
|
58
|
-
result = access_api(
|
59
|
-
api_method: bigquery.tables.get,
|
57
|
+
def update_table(table, schema)
|
58
|
+
access_api(
|
59
|
+
api_method: bigquery.tables.update,
|
60
60
|
parameters: {
|
61
61
|
tableId: table
|
62
|
+
},
|
63
|
+
body_object: {
|
64
|
+
schema: {
|
65
|
+
fields: schema
|
66
|
+
}
|
62
67
|
}
|
63
68
|
)
|
64
|
-
handle_error(result) if result.error?
|
65
|
-
JSON.parse(result.body)
|
66
69
|
end
|
67
70
|
|
68
|
-
def
|
69
|
-
|
71
|
+
def delete_table(table)
|
72
|
+
access_api(
|
70
73
|
api_method: bigquery.tables.delete,
|
71
74
|
parameters: {
|
72
|
-
tableId:
|
75
|
+
tableId: table
|
73
76
|
}
|
74
77
|
)
|
75
|
-
handle_error(result) if result.error?
|
76
78
|
end
|
77
79
|
end
|
78
80
|
end
|
data/test/helper.rb
CHANGED
@@ -1,6 +1,35 @@
|
|
1
1
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
2
|
|
3
|
-
require 'bigquery-client'
|
4
3
|
require 'test/unit'
|
5
|
-
require '
|
6
|
-
require '
|
4
|
+
require 'bigquery-client'
|
5
|
+
require 'dotenv'
|
6
|
+
require 'awesome_print'
|
7
|
+
require 'pry-byebug'
|
8
|
+
|
9
|
+
if defined?(PryByebug)
|
10
|
+
Pry.commands.alias_command 'c', 'continue'
|
11
|
+
Pry.commands.alias_command 's', 'step'
|
12
|
+
Pry.commands.alias_command 'n', 'next'
|
13
|
+
Pry.commands.alias_command 'f', 'finish'
|
14
|
+
end
|
15
|
+
|
16
|
+
Dotenv.load
|
17
|
+
|
18
|
+
$dataset = 'test_bigquery_client'
|
19
|
+
|
20
|
+
$client = BigQuery::Client.new(
|
21
|
+
project: ENV['BIGQUERY_PROJECT'],
|
22
|
+
email: ENV['BIGQUERY_EMAIL'],
|
23
|
+
private_key_path: ENV['BIGQUERY_PRIVATE_KEY_PATH'],
|
24
|
+
dataset: $dataset,
|
25
|
+
private_key_passphrase: 'notasecret',
|
26
|
+
auth_method: 'private_key'
|
27
|
+
)
|
28
|
+
|
29
|
+
$client.datasets.select { |dataset|
|
30
|
+
Regexp.new($dataset) =~ dataset
|
31
|
+
}.each { |dataset|
|
32
|
+
$client.delete_dataset(dataset)
|
33
|
+
}
|
34
|
+
|
35
|
+
$client.create_dataset($dataset)
|
data/test/test_client.rb
CHANGED
@@ -1,171 +1,9 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
class ClientTest < Test::Unit::TestCase
|
4
|
-
def setup
|
5
|
-
@client = BigQuery::Client.new(
|
6
|
-
project: '1234567890',
|
7
|
-
dataset: 'my_dataset',
|
8
|
-
email: '1234567890@developer.gserviceaccount.com',
|
9
|
-
private_key_path: '/path/to/keyfile.p12',
|
10
|
-
private_key_passphrase: 'itsasecret',
|
11
|
-
auth_method: 'private_key'
|
12
|
-
)
|
13
|
-
end
|
14
|
-
|
15
4
|
def test_initialize
|
16
|
-
actual
|
17
|
-
|
18
|
-
assert { actual
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_create_table
|
22
|
-
params = {
|
23
|
-
api_method: 'create_table',
|
24
|
-
body_object: {
|
25
|
-
tableReference: {
|
26
|
-
tableId: 'my_table'
|
27
|
-
},
|
28
|
-
schema: {
|
29
|
-
fields: [
|
30
|
-
{ name: 'foo', type: 'timestamp' },
|
31
|
-
{ name: 'bar', type: 'string' }
|
32
|
-
]
|
33
|
-
}
|
34
|
-
},
|
35
|
-
parameters: {
|
36
|
-
projectId: '1234567890',
|
37
|
-
datasetId: 'my_dataset'
|
38
|
-
}
|
39
|
-
}
|
40
|
-
auth = Object.new
|
41
|
-
mock(client = Object.new) do |client|
|
42
|
-
client.discovered_api('bigquery', 'v2') { mock!.tables.mock!.insert { 'create_table' } }
|
43
|
-
client.execute(params) { mock(Object.new).error? { false } }
|
44
|
-
client.authorization = auth
|
45
|
-
end
|
46
|
-
mock(Google::APIClient).new.with_any_args { client }
|
47
|
-
mock(Google::APIClient::JWTAsserter).new.with_any_args { mock(Object.new).authorize { auth } }
|
48
|
-
mock(Google::APIClient::PKCS12).load_key('/path/to/keyfile.p12', 'itsasecret')
|
49
|
-
schema = [{name: 'foo', type: 'timestamp'}, { name: 'bar', type: 'string'}]
|
50
|
-
assert { @client.create_table('my_table', schema).nil? }
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_insert
|
54
|
-
params = {
|
55
|
-
api_method: 'insert_all',
|
56
|
-
parameters: {
|
57
|
-
projectId: '1234567890',
|
58
|
-
datasetId: 'my_dataset',
|
59
|
-
tableId: 'my_table'
|
60
|
-
},
|
61
|
-
body_object: {
|
62
|
-
rows: [ { json: { a: 'b', c: 'd' } } ]
|
63
|
-
}
|
64
|
-
}
|
65
|
-
auth = Object.new
|
66
|
-
mock(client = Object.new) do |client|
|
67
|
-
client.discovered_api('bigquery', 'v2') { mock!.tabledata.mock!.insert_all { 'insert_all' } }
|
68
|
-
client.execute(params) { mock(Object.new).error? { false } }
|
69
|
-
client.authorization = auth
|
70
|
-
end
|
71
|
-
mock(Google::APIClient).new.with_any_args { client }
|
72
|
-
mock(Google::APIClient::JWTAsserter).new.with_any_args { mock(Object.new).authorize { auth } }
|
73
|
-
mock(Google::APIClient::PKCS12).load_key('/path/to/keyfile.p12', 'itsasecret')
|
74
|
-
assert { @client.insert('my_table', a: 'b', c: 'd').nil? }
|
75
|
-
end
|
76
|
-
|
77
|
-
def test_insert_rows
|
78
|
-
params = {
|
79
|
-
api_method: 'insert_all',
|
80
|
-
parameters: {
|
81
|
-
projectId: '1234567890',
|
82
|
-
datasetId: 'my_dataset',
|
83
|
-
tableId: 'my_table'
|
84
|
-
},
|
85
|
-
body_object: {
|
86
|
-
rows: [
|
87
|
-
{ json: { 'a' => 'b' } },
|
88
|
-
{ json: { 'b' => 'c' } }
|
89
|
-
]
|
90
|
-
}
|
91
|
-
}
|
92
|
-
auth = Object.new
|
93
|
-
mock(client = Object.new) do |client|
|
94
|
-
client.discovered_api('bigquery', 'v2') { mock!.tabledata.mock!.insert_all { 'insert_all' } }
|
95
|
-
client.execute(params) { mock(Object.new).error? { false } }
|
96
|
-
client.authorization = auth
|
97
|
-
end
|
98
|
-
mock(Google::APIClient).new.with_any_args { client }
|
99
|
-
mock(Google::APIClient::JWTAsserter).new.with_any_args { mock(Object.new).authorize { auth } }
|
100
|
-
mock(Google::APIClient::PKCS12).load_key('/path/to/keyfile.p12', 'itsasecret')
|
101
|
-
rows = [{'a' => 'b'}, {'b' => 'c'}]
|
102
|
-
assert { @client.insert('my_table', rows).nil? }
|
103
|
-
end
|
104
|
-
|
105
|
-
def test_fetch_schema
|
106
|
-
params = {
|
107
|
-
api_method: 'tables_get',
|
108
|
-
parameters: {
|
109
|
-
tableId: 'my_table',
|
110
|
-
projectId: '1234567890',
|
111
|
-
datasetId: 'my_dataset'
|
112
|
-
}
|
113
|
-
}
|
114
|
-
result_body = JSON.generate(
|
115
|
-
{
|
116
|
-
schema: {
|
117
|
-
fields: [
|
118
|
-
{ name: 'time', type: 'TIMESTAMP' },
|
119
|
-
{ name: 'tty', type: 'STRING' }
|
120
|
-
]
|
121
|
-
}
|
122
|
-
}
|
123
|
-
)
|
124
|
-
auth = Object.new
|
125
|
-
mock(result = Object.new) do |result|
|
126
|
-
result.error? { false }
|
127
|
-
result.body { result_body }
|
128
|
-
end
|
129
|
-
mock(client = Object.new) do |client|
|
130
|
-
client.discovered_api('bigquery', 'v2') { mock!.tables.mock!.get { 'tables_get' } }
|
131
|
-
client.execute(params) { result }
|
132
|
-
client.authorization = auth
|
133
|
-
end
|
134
|
-
mock(Google::APIClient).new.with_any_args { client }
|
135
|
-
mock(Google::APIClient::JWTAsserter).new.with_any_args { mock(Object.new).authorize { auth } }
|
136
|
-
mock(Google::APIClient::PKCS12).load_key('/path/to/keyfile.p12', 'itsasecret')
|
137
|
-
expected = [
|
138
|
-
{ 'name' => 'time', 'type' => 'TIMESTAMP' },
|
139
|
-
{ 'name' => 'tty', 'type' => 'STRING' }
|
140
|
-
]
|
141
|
-
assert { @client.fetch_schema('my_table') == expected }
|
142
|
-
end
|
143
|
-
|
144
|
-
def test_errors
|
145
|
-
errors = [
|
146
|
-
{ code: 404, klass: BigQuery::NotFound },
|
147
|
-
{ code: 409, klass: BigQuery::Conflict },
|
148
|
-
{ code: 403, klass: BigQuery::ClientError },
|
149
|
-
{ code: 503, klass: BigQuery::ServerError },
|
150
|
-
{ code: 301, klass: BigQuery::UnexpectedError }
|
151
|
-
]
|
152
|
-
errors.each do |error|
|
153
|
-
auth = Object.new
|
154
|
-
mock(result = Object.new) do |result|
|
155
|
-
result.error? { true }
|
156
|
-
result.status { error[:code] }
|
157
|
-
result.error_message { 'this is an error message' }
|
158
|
-
end
|
159
|
-
mock(client = Object.new) do |client|
|
160
|
-
client.execute.with_any_args { result }
|
161
|
-
client.authorization = auth
|
162
|
-
end
|
163
|
-
mock(@client).bigquery { mock!.tabledata.mock!.insert_all }
|
164
|
-
mock(Google::APIClient).new.with_any_args { client }
|
165
|
-
mock(Google::APIClient::JWTAsserter).new.with_any_args { mock(Object.new).authorize { auth } }
|
166
|
-
mock(Google::APIClient::PKCS12).load_key('/path/to/keyfile.p12', 'itsasecret')
|
167
|
-
rows = [{'a' => 'b'}, {'b' => 'c'}]
|
168
|
-
assert_raise(error[:klass]) { @client.insert('my_table', rows) }
|
169
|
-
end
|
5
|
+
actual = $client.instance_variables
|
6
|
+
minimal = [:@project, :@dataset, :@email, :@private_key_path, :@private_key_passphrase, :@auth_method]
|
7
|
+
assert { minimal - actual == [] }
|
170
8
|
end
|
171
9
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class DatasetsTest < Test::Unit::TestCase
|
4
|
+
def test_datasets
|
5
|
+
dataset_name = "#{$dataset}_test_datasets"
|
6
|
+
$client.create_dataset(dataset_name)
|
7
|
+
$client.datasets.include?(dataset_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_create_dataset
|
11
|
+
dataset_name = "#{$dataset}_create_dataset"
|
12
|
+
$client.create_dataset(dataset_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_delete_dataset
|
16
|
+
dataset_name = "#{$dataset}_delete_dataset"
|
17
|
+
$client.create_dataset(dataset_name)
|
18
|
+
before = $client.datasets
|
19
|
+
$client.delete_dataset(dataset_name)
|
20
|
+
after = $client.datasets
|
21
|
+
actual = before - after
|
22
|
+
expected = [dataset_name]
|
23
|
+
assert { actual == expected }
|
24
|
+
end
|
25
|
+
end
|
data/test/test_jobs.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class JobsTest < Test::Unit::TestCase
|
4
|
+
@@query = <<-"EOS"
|
5
|
+
SELECT
|
6
|
+
born_alive_alive, mother_residence_state, is_male
|
7
|
+
FROM
|
8
|
+
publicdata:samples.natality
|
9
|
+
ORDER BY
|
10
|
+
day
|
11
|
+
LIMIT
|
12
|
+
100
|
13
|
+
EOS
|
14
|
+
|
15
|
+
def test_sql
|
16
|
+
result = $client.sql(@@query)
|
17
|
+
assert { result.size == 100 }
|
18
|
+
assert { result.sample["born_alive_alive"].is_a? Fixnum }
|
19
|
+
assert { result.sample["mother_residence_state"].is_a? String }
|
20
|
+
assert { result.sample["is_male"] == true || result.first["is_male"] == false }
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class ProjectsTest < Test::Unit::TestCase
|
4
|
+
def test_projects
|
5
|
+
actual = $client.projects.first
|
6
|
+
expected = ENV['BIGQUERY_PROJECT']
|
7
|
+
assert { actual == expected }
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_list_projects
|
11
|
+
actual = $client.list_projects['projects'].first['id']
|
12
|
+
expected = ENV['BIGQUERY_PROJECT']
|
13
|
+
assert { actual == expected }
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TablesTest < Test::Unit::TestCase
|
4
|
+
def test_insert
|
5
|
+
table_name = __method__.to_s
|
6
|
+
schema = [{ name: 'bar', type: 'string' }]
|
7
|
+
$client.create_table(table_name, schema)
|
8
|
+
result = $client.insert(table_name, bar: "foo")
|
9
|
+
assert { result['kind'] == 'bigquery#tableDataInsertAllResponse' }
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_insert_with_array
|
13
|
+
table_name = __method__.to_s
|
14
|
+
schema = [{ name: 'bar', type: 'string' }]
|
15
|
+
$client.create_table(table_name, schema)
|
16
|
+
result = $client.list_tabledata(table_name)
|
17
|
+
rows = [{ bar: "foo" }, { bar: "foo2" }, { bar: "foo3" }]
|
18
|
+
result = $client.insert(table_name, rows)
|
19
|
+
assert { result['kind'] == 'bigquery#tableDataInsertAllResponse' }
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_list_tabledata
|
23
|
+
table_name = __method__.to_s
|
24
|
+
schema = [{ name: 'bar', type: 'string' }]
|
25
|
+
$client.create_table(table_name, schema)
|
26
|
+
result = $client.list_tabledata(table_name)
|
27
|
+
assert { result['kind'] == "bigquery#tableDataList" }
|
28
|
+
end
|
29
|
+
end
|
data/test/test_tables.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TablesTest < Test::Unit::TestCase
|
4
|
+
def test_tables
|
5
|
+
table_name = __method__.to_s
|
6
|
+
schema = [{ name: 'bar', type: 'string' }]
|
7
|
+
$client.create_table(table_name, schema)
|
8
|
+
assert { $client.tables.include?(table_name) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_fetch_schema
|
12
|
+
table_name = __method__.to_s
|
13
|
+
schema = [{ name: 'bar', type: 'string' }]
|
14
|
+
$client.create_table(table_name, schema)
|
15
|
+
result = $client.fetch_schema(table_name)
|
16
|
+
assert { result == [{"name"=>"bar", "type"=>"STRING"}] }
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_create_table
|
20
|
+
table_name = __method__.to_s
|
21
|
+
schema = [{ name: 'bar', type: 'string' }]
|
22
|
+
before = $client.tables
|
23
|
+
$client.create_table(table_name, schema)
|
24
|
+
after = $client.tables
|
25
|
+
actual = after - before
|
26
|
+
expected = [table_name]
|
27
|
+
assert { expected == actual }
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_delete_table
|
31
|
+
table_name = __method__.to_s
|
32
|
+
schema = [{ name: 'bar', type: 'string' }]
|
33
|
+
$client.create_table(table_name, schema)
|
34
|
+
before = $client.tables
|
35
|
+
$client.delete_table(table_name)
|
36
|
+
after = $client.tables
|
37
|
+
actual = before - after
|
38
|
+
expected = [table_name]
|
39
|
+
assert { actual == expected }
|
40
|
+
end
|
41
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bigquery-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tsukuru Tanimichi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-api-client
|
@@ -53,7 +53,35 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: test-unit
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.0.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.0.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: dotenv
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.0.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.0.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: awesome_print
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
87
|
- - ">="
|
@@ -67,33 +95,47 @@ dependencies:
|
|
67
95
|
- !ruby/object:Gem::Version
|
68
96
|
version: '0'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
98
|
+
name: pry
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
72
100
|
requirements:
|
73
|
-
- - "
|
101
|
+
- - ">="
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
103
|
+
version: '0'
|
76
104
|
type: :development
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
|
-
- - "
|
108
|
+
- - ">="
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
110
|
+
version: '0'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
112
|
+
name: pry-doc
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
86
114
|
requirements:
|
87
|
-
- - "
|
115
|
+
- - ">="
|
88
116
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
117
|
+
version: '0'
|
90
118
|
type: :development
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
93
121
|
requirements:
|
94
|
-
- - "
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry-byebug
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
95
137
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
138
|
+
version: '0'
|
97
139
|
description:
|
98
140
|
email:
|
99
141
|
- ttanimichi@hotmail.com
|
@@ -101,8 +143,8 @@ executables: []
|
|
101
143
|
extensions: []
|
102
144
|
extra_rdoc_files: []
|
103
145
|
files:
|
146
|
+
- ".env.example"
|
104
147
|
- ".gitignore"
|
105
|
-
- ".travis.yml"
|
106
148
|
- Gemfile
|
107
149
|
- LICENSE.txt
|
108
150
|
- README.md
|
@@ -119,6 +161,11 @@ files:
|
|
119
161
|
- lib/bigquery-client/version.rb
|
120
162
|
- test/helper.rb
|
121
163
|
- test/test_client.rb
|
164
|
+
- test/test_datasets.rb
|
165
|
+
- test/test_jobs.rb
|
166
|
+
- test/test_projects.rb
|
167
|
+
- test/test_tabledata.rb
|
168
|
+
- test/test_tables.rb
|
122
169
|
homepage: https://github.com/ttanimichi/bigquery-client
|
123
170
|
licenses:
|
124
171
|
- MIT
|
@@ -146,3 +193,9 @@ summary: A Ruby interface to the BigQuery API.
|
|
146
193
|
test_files:
|
147
194
|
- test/helper.rb
|
148
195
|
- test/test_client.rb
|
196
|
+
- test/test_datasets.rb
|
197
|
+
- test/test_jobs.rb
|
198
|
+
- test/test_projects.rb
|
199
|
+
- test/test_tabledata.rb
|
200
|
+
- test/test_tables.rb
|
201
|
+
has_rdoc:
|