embulk-output-postgres-json 0.2.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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YWFmMWQ2YjM0ZTRiMzRmY2IxMjdlYmU5ZWQyOTFlOGZkNjEwNDY5Mg==
5
+ data.tar.gz: !binary |-
6
+ MzliNjcwNjk5NTZkM2UyYzgzMzZlOTc1ZjY4ZWIwYmQ4NjQzOTM1NQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZjU2MjE4YmE4ZmQ4Mzg0ZTc0YzY5ZGNlYTc4MTI2NTBiMDIwMzZhNTkyMzBh
10
+ OTkzMjUwMGJkOTQ3ZDlhZDQ2NmY0MmNiYTcyYjNlNjgyMWU4ZWI1Y2I5ZDE0
11
+ MWZkOWViMDdkZmIzYTgzMmFhZmUwOTE0OTBjNzM0ZDdmMGExYWQ=
12
+ data.tar.gz: !binary |-
13
+ ODU2ZmExMTIwODYyMmE2OGZmYWM2MjRiYjI3M2Q2YzNmNTY5MGM1M2Q5YmNl
14
+ ZDRlNzIzOWMyYTcwOGI2YzY2YzcxOTI0MzQwYmIxMjQ3ZmEzM2Q0YzZiODg4
15
+ ZGE4MjA3NjI5MDY5ZDE2Y2E0NjgwZDU5YzJmN2Y0NjU5ZmFjZmE=
@@ -0,0 +1,5 @@
1
+
2
+ 2015-01-26 version 0.1.0:
3
+
4
+ * The first release
5
+
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
@@ -0,0 +1,19 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ embulk-plugin-postgres-json (0.1.0)
5
+ jdbc-postgres (>= 3.2.0)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ jdbc-postgres (9.3.1102)
11
+ rake (10.4.2)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ bundler (~> 1.0)
18
+ embulk-plugin-postgres-json!
19
+ rake (>= 0.9.2)
@@ -0,0 +1,33 @@
1
+ # Embulk output plugin for PostgreSQL json column
2
+
3
+ This [Embulk](https://github.com/embulk/embulk) output plugin writes records to a json column of a table.
4
+
5
+ This works as following:
6
+
7
+ 1. transaction begin: creates a temporary table
8
+ 2. run: insert records to the temporary table
9
+ 3. transaction commit: copy the records to the actual table and drop the temporary table
10
+
11
+ ## Configuration
12
+
13
+ - **host** host name of the PostgreSQL server (string, required)
14
+ - **port** port of the PostgreSQL server (integer, default: 5432)
15
+ - **username** login user name (string, required)
16
+ - **password** login password (string, default: "")
17
+ - **database** destination database name (string, required)
18
+ - **table** destination table name (string, required)
19
+ - **column** destination column name (string, default: "json")
20
+ - **column_type** json or jsonb (string, default: 'json')
21
+
22
+ ### Example
23
+
24
+ ```yaml
25
+ out:
26
+ type: postgres_json
27
+ host: localhost
28
+ port: 5432
29
+ username: pg
30
+ database: embulk_test
31
+ table: load01
32
+ ```
33
+
@@ -0,0 +1,4 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ task :default => [:build]
@@ -0,0 +1,21 @@
1
+
2
+ Gem::Specification.new do |gem|
3
+ gem.name = "embulk-output-postgres-json"
4
+ gem.version = "0.2.0"
5
+
6
+ gem.summary = %q{Embulk output for PostgreSQL json and jsonb column}
7
+ gem.description = gem.summary
8
+ gem.authors = ["Sadayuki Furuhashi"]
9
+ gem.email = ["frsyuki@gmail.com"]
10
+ gem.license = "Apache 2.0"
11
+ gem.homepage = "https://github.com/frsyuki/embulk-output-postgres-json"
12
+
13
+ gem.files = `git ls-files`.split("\n") + Dir["classpath/*.jar"]
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.require_paths = ["lib"]
16
+ gem.has_rdoc = false
17
+
18
+ gem.add_dependency 'jdbc-postgres', ['>= 3.2.0']
19
+ gem.add_development_dependency 'bundler', ['~> 1.0']
20
+ gem.add_development_dependency 'rake', ['>= 0.9.2']
21
+ end
@@ -0,0 +1,109 @@
1
+ module Embulk
2
+ require 'jdbc/postgres'
3
+ Jdbc::Postgres.load_driver
4
+
5
+ class PostgresJsonOutputPlugin < OutputPlugin
6
+ Plugin.register_output('postgres_json', self)
7
+
8
+ def self.transaction(config, schema, processor_count, &control)
9
+ task = {
10
+ 'host' => config.param('host', :string),
11
+ 'port' => config.param('port', :integer, default: 5432),
12
+ 'username' => config.param('username', :string),
13
+ 'password' => config.param('password', :string, default: ''),
14
+ 'database' => config.param('database', :string),
15
+ 'table' => config.param('table', :string),
16
+ 'column' => config.param('column', :string, default: 'json'),
17
+ 'column_type' => config.param('column_type', :string, default: 'json'),
18
+ }
19
+
20
+ now = Time.now
21
+ unique_name = "%08x%08x" % [now.tv_sec, now.tv_nsec] # TODO add org.embulk.spi.ExecSession.getTransactionUniqueName() method
22
+ task['temp_table'] = "#{task['table']}_LOAD_TEMP_#{unique_name}"
23
+
24
+ connect(task) do |pg|
25
+ # drop table if exists "DEST"
26
+ # create table if exists "TEMP" ("COL" json)
27
+ execute_sql(pg, %[drop table if exists "#{task['temp_table']}"])
28
+ execute_sql(pg, %[create table "#{task['temp_table']}" ("#{task['column']}" #{task['column_type']})])
29
+ end
30
+
31
+ begin
32
+ yield(task)
33
+
34
+ connect(task) do |pg|
35
+ # create table if not exists "DEST" ("COL" json)
36
+ # insert into "DEST" ("COL") select "COL" from "TEMP"
37
+ execute_sql(pg, %[create table if not exists "#{task['table']}" ("#{task['column']}" #{task['column_type']})])
38
+ execute_sql(pg, %[insert into "#{task['table']}" ("#{task['column']}") select "#{task['column']}" from "#{task['temp_table']}"])
39
+ end
40
+
41
+ ensure
42
+ connect(task) do |pg|
43
+ # drop table if exists TEMP
44
+ execute_sql(pg, %[drop table if exists "#{task['temp_table']}"])
45
+ end
46
+ end
47
+
48
+ return {}
49
+ end
50
+
51
+ def self.connect(task)
52
+ url = "jdbc:postgresql://#{task['host']}:#{task['port']}/#{task['database']}"
53
+ props = java.util.Properties.new
54
+ props.put("user", task['username'])
55
+ props.put("password", task['password'])
56
+
57
+ pg = org.postgresql.Driver.new.connect(url, props)
58
+ if block_given?
59
+ begin
60
+ yield pg
61
+ ensure
62
+ pg.close
63
+ end
64
+ end
65
+ pg
66
+ end
67
+
68
+ def self.execute_sql(pg, sql, *args)
69
+ stmt = pg.createStatement
70
+ begin
71
+ stmt.execute(sql)
72
+ ensure
73
+ stmt.close
74
+ end
75
+ end
76
+
77
+ def initialize(task, schema, index)
78
+ super
79
+ @pg = self.class.connect(task)
80
+ end
81
+
82
+ def close
83
+ @pg.close
84
+ end
85
+
86
+ def add(page)
87
+ prep = @pg.prepareStatement(%[insert into "#{@task['temp_table']}" (#{@task['column']}) values (?::#{@task['column_type']})])
88
+ begin
89
+ page.each do |record|
90
+ prep.setString(1, record.to_json)
91
+ prep.execute
92
+ end
93
+ ensure
94
+ prep.close
95
+ end
96
+ end
97
+
98
+ def finish
99
+ end
100
+
101
+ def abort
102
+ end
103
+
104
+ def commit
105
+ {}
106
+ end
107
+ end
108
+
109
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: embulk-output-postgres-json
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Sadayuki Furuhashi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jdbc-postgres
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.9.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.2
55
+ description: Embulk output for PostgreSQL json and jsonb column
56
+ email:
57
+ - frsyuki@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ChangeLog
63
+ - Gemfile
64
+ - Gemfile.lock
65
+ - README.md
66
+ - Rakefile
67
+ - embulk-plugin-postgres-json.gemspec
68
+ - lib/embulk/output/postgres_json.rb
69
+ homepage: https://github.com/frsyuki/embulk-output-postgres-json
70
+ licenses:
71
+ - Apache 2.0
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.2.2
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Embulk output for PostgreSQL json and jsonb column
93
+ test_files: []