oci8_simple 0.4.2 → 0.5.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.
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/lib/oci8_simple/cli.rb +0 -1
- data/lib/oci8_simple/client.rb +32 -37
- data/lib/oci8_simple/describe.rb +117 -45
- data/lib/oci8_simple.rb +1 -0
- data/oci8_simple.gemspec +5 -5
- data/test/describe_test.rb +12 -5
- metadata +7 -7
data/Rakefile
CHANGED
@@ -15,9 +15,9 @@ Jeweler::Tasks.new do |gem|
|
|
15
15
|
gem.name = "oci8_simple"
|
16
16
|
gem.homepage = "http://github.com/unclebilly/oci8_simple"
|
17
17
|
gem.license = "MIT"
|
18
|
-
gem.summary = %Q{
|
19
|
-
gem.description = %Q{
|
20
|
-
|
18
|
+
gem.summary = %Q{Command-line tools for interacting with an Oracle database.}
|
19
|
+
gem.description = %Q{Command-line tools for interacting with an Oracle database. This client is intended to be used
|
20
|
+
to aid development and automation. This is *not* meant to replace an ORM such as ActiveRecord + OracleEnhancedAdapter.
|
21
21
|
The only prerequisite to running this code is that you have installed the ruby-oci8 gem on your machine.}
|
22
22
|
gem.email = "billy.reisinger@gmail.com"
|
23
23
|
gem.authors = ["Billy Reisinger"]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/oci8_simple/cli.rb
CHANGED
data/lib/oci8_simple/client.rb
CHANGED
@@ -1,44 +1,39 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
|
4
|
-
# Run single statements against an arbitrary Oracle schema. This client is intended to be used by simple
|
5
|
-
# command-line scripts to aid automation. This is *not* meant to replace an ORM such as ActiveRecord + OracleEnhancedAdapter.
|
6
|
-
# The only prerequisite to running this code is that you have installed the ruby-oci8 gem on your machine.
|
7
|
-
#
|
8
|
-
# == Logging
|
9
|
-
# All logging is done to ~/.oci8_simple/oci8_simple.log
|
10
|
-
#
|
11
|
-
# == Examples
|
12
|
-
# * Initialize a client against the development schema
|
13
|
-
# client = Oci8Simple::Client.new
|
14
|
-
# * Run a simple select query against development schema
|
15
|
-
# client.run('select id, name from foos') => [[2, "lol"], [3, "hey"], ...]
|
16
|
-
# * Run a simple select query against stage schema
|
17
|
-
# Oci8Simple:Client.new("stage").run('select id, name from foos') => [[2, "lol"], [3, "hey"], ...]
|
18
|
-
# * Update something
|
19
|
-
# client.run <<-SQL
|
20
|
-
# UPDATE foos SET bar='baz' WHERE id=1233
|
21
|
-
# SQL
|
22
|
-
# * Run some DDL
|
23
|
-
# client.run <<-SQL
|
24
|
-
# CREATE TABLE foos (
|
25
|
-
# ID NUMBER(38) NOT NULL
|
26
|
-
# )
|
27
|
-
# SQL
|
28
|
-
# * Run some PL/SQL
|
29
|
-
# client.run <<-SQL
|
30
|
-
# DECLARE
|
31
|
-
# a NUMBER;
|
32
|
-
# b NUMBER;
|
33
|
-
# BEGIN
|
34
|
-
# SELECT e,f INTO a,b FROM T1 WHERE e>1;
|
35
|
-
# INSERT INTO T1 VALUES(b,a);
|
36
|
-
# END;
|
37
|
-
# SQL
|
38
1
|
module Oci8Simple
|
39
2
|
class ConfigError < Exception; end
|
40
3
|
class LogError < Exception; end
|
41
4
|
|
5
|
+
# Run SQL and PL/SQL statements against an Oracle schema.
|
6
|
+
#
|
7
|
+
# == Logging
|
8
|
+
# All logging is done to ~/.oci8_simple/oci8_simple.log
|
9
|
+
#
|
10
|
+
# == Examples
|
11
|
+
# * Initialize a client against the development schema
|
12
|
+
# client = Oci8Simple::Client.new
|
13
|
+
# * Run a simple select query against development schema
|
14
|
+
# client.run('select id, name from foos') => [[2, "lol"], [3, "hey"], ...]
|
15
|
+
# * Run a simple select query against stage schema
|
16
|
+
# Oci8Simple:Client.new("stage").run('select id, name from foos') => [[2, "lol"], [3, "hey"], ...]
|
17
|
+
# * Update something
|
18
|
+
# client.run <<-SQL
|
19
|
+
# UPDATE foos SET bar='baz' WHERE id=1233
|
20
|
+
# SQL
|
21
|
+
# * Run some DDL
|
22
|
+
# client.run <<-SQL
|
23
|
+
# CREATE TABLE foos (
|
24
|
+
# ID NUMBER(38) NOT NULL
|
25
|
+
# )
|
26
|
+
# SQL
|
27
|
+
# * Run some PL/SQL
|
28
|
+
# client.run <<-SQL
|
29
|
+
# DECLARE
|
30
|
+
# a NUMBER;
|
31
|
+
# b NUMBER;
|
32
|
+
# BEGIN
|
33
|
+
# SELECT e,f INTO a,b FROM T1 WHERE e>1;
|
34
|
+
# INSERT INTO T1 VALUES(b,a);
|
35
|
+
# END;
|
36
|
+
# SQL
|
42
37
|
class Client
|
43
38
|
USER_DIR = File.join(ENV["HOME"], ".oci8_simple")
|
44
39
|
CONFIG_FILE = File.join(USER_DIR, "database.yml")
|
data/lib/oci8_simple/describe.rb
CHANGED
@@ -1,59 +1,131 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Oci8Simple
|
2
|
+
# == Description
|
3
|
+
# This class creates a string describing a table's columns, intended to be
|
4
|
+
# displayed in a fixed-width font.
|
5
|
+
# == Usage
|
6
|
+
# Oci8Simple::Describe.new("development").run("users")
|
7
|
+
class Describe
|
8
|
+
SPACE_BETWEEN=2
|
9
|
+
FIELDS=[
|
10
|
+
{:select => "NULLABLE", :header => "Required", :content => :format_nullable, :right => true},
|
11
|
+
{:select => "lower(COLUMN_NAME)", :header=> "Name"},
|
12
|
+
{:select => "lower(DATA_TYPE)", :header => "Type"},
|
13
|
+
{:select => "DATA_LENGTH", :header => "Size", :content => :format_size},
|
14
|
+
{:select => "CHAR_USED", :header => "Char?", :content => :format_char_used},
|
15
|
+
{:select => "CHAR_LENGTH", :header => "Char_size", :content => :format_char_length},
|
16
|
+
{:select => "DATA_PRECISION", :header => "Precision"},
|
17
|
+
{:select => "DATA_SCALE", :header => "Scale"},
|
18
|
+
{:select => "DATA_DEFAULT", :header => "Default", :content => :format_default, :max => 10}
|
19
|
+
]
|
5
20
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
21
|
+
def run(table)
|
22
|
+
sql = <<-SQL
|
23
|
+
select #{select_fields}
|
24
|
+
from user_tab_columns
|
25
|
+
where table_name='#{table.upcase}'
|
26
|
+
order by column_name asc
|
27
|
+
SQL
|
28
|
+
results = client.run(sql)
|
29
|
+
calculate_widths(results)
|
30
|
+
format_results(results)
|
31
|
+
end
|
15
32
|
|
16
|
-
|
17
|
-
|
18
|
-
|
33
|
+
def initialize(env=nil)
|
34
|
+
@env = env || "development"
|
35
|
+
end
|
19
36
|
|
20
|
-
|
21
|
-
|
22
|
-
if(col.data_type.to_s =~ /varchar/i)
|
23
|
-
str << "(#{col.char_size} CHAR)"
|
24
|
-
elsif(col.data_type == :number)
|
25
|
-
str << "(#{col.precision})"
|
37
|
+
def self.usage
|
38
|
+
"Usage: #{0} TABLE_NAME [ENVIRONMENT]"
|
26
39
|
end
|
27
|
-
str
|
28
|
-
end
|
29
40
|
|
30
|
-
|
31
|
-
|
32
|
-
|
41
|
+
def self.run_from_argv
|
42
|
+
o = OptionParser.new do |opt|
|
43
|
+
opt.banner = usage
|
44
|
+
opt.on("-v", "--version", "Show version") do
|
45
|
+
puts "version #{File.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION'))}"
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
end
|
49
|
+
o.parse!
|
50
|
+
if(ARGV[0].nil?)
|
51
|
+
puts o
|
52
|
+
else
|
53
|
+
puts self.new(ARGV[1]).run(ARGV[0])
|
54
|
+
end
|
55
|
+
end
|
33
56
|
|
34
|
-
|
35
|
-
"Usage: #{0} TABLE_NAME [ENVIRONMENT]"
|
36
|
-
end
|
57
|
+
private
|
37
58
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
59
|
+
def format_nullable(value, row)
|
60
|
+
value == 'N' ? '*' : ' '
|
61
|
+
end
|
62
|
+
|
63
|
+
def format_char_used(value, row)
|
64
|
+
value == 'C' ? "*" : ' '
|
65
|
+
end
|
66
|
+
|
67
|
+
def format_char_length(value, row)
|
68
|
+
row[FIELDS.index{|f| f[:select] == "CHAR_USED"}] == "C" ? value.to_s : ""
|
69
|
+
end
|
70
|
+
|
71
|
+
def format_size(value, row)
|
72
|
+
row[FIELDS.index{|f| f[:select] == "lower(DATA_TYPE)"}] =~ /lob/i ? "" : value.to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
def format_default(value, row)
|
76
|
+
value = value.to_s.strip.gsub(/^'(.+)'$/,'\1')
|
77
|
+
|
78
|
+
if(value.length > 10)
|
79
|
+
value = value[0..9] + "..."
|
44
80
|
end
|
81
|
+
value
|
45
82
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
83
|
+
|
84
|
+
def select_fields
|
85
|
+
FIELDS.map{|f| f[:select]}.join(",")
|
86
|
+
end
|
87
|
+
|
88
|
+
def max(column, header)
|
89
|
+
max = header.length
|
90
|
+
column.each {|s| max = s.length if s.length > max}
|
91
|
+
max + SPACE_BETWEEN
|
92
|
+
end
|
93
|
+
|
94
|
+
def header
|
95
|
+
FIELDS.map{|f| f[:header].ljust(f[:max], ' ')}.join("")
|
51
96
|
end
|
52
|
-
end
|
53
97
|
|
54
|
-
|
98
|
+
def calculate_widths(results)
|
99
|
+
FIELDS.each_with_index do |hsh,i|
|
100
|
+
if(hsh[:max].nil?)
|
101
|
+
hsh[:max] = max(results.map{|row| row[i].to_s}, hsh[:header])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
55
105
|
|
56
|
-
|
57
|
-
|
106
|
+
def format_results(results)
|
107
|
+
arr = []
|
108
|
+
arr << header
|
109
|
+
arr << "-" * arr[0].length
|
110
|
+
results.each do |result|
|
111
|
+
str = ""
|
112
|
+
result.each_with_index do |col, i|
|
113
|
+
field = FIELDS[i]
|
114
|
+
value = field[:content].nil? ? col.to_s : send(field[:content], col, result)
|
115
|
+
if(field[:right])
|
116
|
+
str << value.rjust(field[:max] - SPACE_BETWEEN, ' ')
|
117
|
+
str << ' ' * SPACE_BETWEEN
|
118
|
+
else
|
119
|
+
str << value.ljust(field[:max], ' ')
|
120
|
+
end
|
121
|
+
end
|
122
|
+
arr << str
|
123
|
+
end
|
124
|
+
arr.join("\n")
|
125
|
+
end
|
126
|
+
|
127
|
+
def client
|
128
|
+
@client ||= Oci8Simple::Client.new(@env)
|
129
|
+
end
|
58
130
|
end
|
59
131
|
end
|
data/lib/oci8_simple.rb
CHANGED
data/oci8_simple.gemspec
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{oci8_simple}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.5.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Billy Reisinger"]
|
12
|
-
s.date = %q{2011-06-
|
13
|
-
s.description = %q{
|
14
|
-
|
12
|
+
s.date = %q{2011-06-30}
|
13
|
+
s.description = %q{Command-line tools for interacting with an Oracle database. This client is intended to be used
|
14
|
+
to aid development and automation. This is *not* meant to replace an ORM such as ActiveRecord + OracleEnhancedAdapter.
|
15
15
|
The only prerequisite to running this code is that you have installed the ruby-oci8 gem on your machine.}
|
16
16
|
s.email = %q{billy.reisinger@gmail.com}
|
17
17
|
s.executables = ["oci8_simple", "describe"]
|
@@ -42,7 +42,7 @@ Gem::Specification.new do |s|
|
|
42
42
|
s.licenses = ["MIT"]
|
43
43
|
s.require_paths = ["lib"]
|
44
44
|
s.rubygems_version = %q{1.5.2}
|
45
|
-
s.summary = %q{
|
45
|
+
s.summary = %q{Command-line tools for interacting with an Oracle database.}
|
46
46
|
s.test_files = [
|
47
47
|
"test/cli_test.rb",
|
48
48
|
"test/client_test.rb",
|
data/test/describe_test.rb
CHANGED
@@ -7,8 +7,9 @@ class DescribeTest < Test::Unit::TestCase
|
|
7
7
|
@client.run <<-SQL
|
8
8
|
CREATE TABLE "OCI8_SIMPLE_TEST"
|
9
9
|
(
|
10
|
-
"NAME" VARCHAR2(400 CHAR) NOT NULL ENABLE,
|
11
|
-
"ID" NUMBER(38,0) NOT NULL ENABLE,
|
10
|
+
"NAME" VARCHAR2(400 CHAR) DEFAULT 'FOO' NOT NULL ENABLE,
|
11
|
+
"ID" NUMBER(38,0) DEFAULT 7 NOT NULL ENABLE,
|
12
|
+
"LONG_THING" VARCHAR(2000 CHAR) DEFAULT '#{"a " * 50}' NOT NULL ENABLE,
|
12
13
|
"TEXTS" CLOB
|
13
14
|
)
|
14
15
|
SQL
|
@@ -19,10 +20,16 @@ class DescribeTest < Test::Unit::TestCase
|
|
19
20
|
end
|
20
21
|
should "format results for the command line" do
|
21
22
|
expected=<<-STR
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
Required Name Type Size Char? Char_size Precision Scale Default
|
24
|
+
------------------------------------------------------------------------------------
|
25
|
+
* id number 22 38 0 7
|
26
|
+
* long_thing varchar2 4000 * 2000 a a a a a ...
|
27
|
+
* name varchar2 1600 * 400 FOO
|
28
|
+
texts clob
|
25
29
|
STR
|
30
|
+
# puts
|
31
|
+
# puts expected.chop
|
32
|
+
# puts @describe.run("oci8_simple_test")
|
26
33
|
assert_equal(expected.chop, @describe.run("oci8_simple_test"))
|
27
34
|
end
|
28
35
|
end
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 5
|
9
|
+
- 0
|
10
|
+
version: 0.5.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Billy Reisinger
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-06-
|
18
|
+
date: 2011-06-30 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -111,8 +111,8 @@ dependencies:
|
|
111
111
|
type: :runtime
|
112
112
|
requirement: *id006
|
113
113
|
description: |-
|
114
|
-
|
115
|
-
|
114
|
+
Command-line tools for interacting with an Oracle database. This client is intended to be used
|
115
|
+
to aid development and automation. This is *not* meant to replace an ORM such as ActiveRecord + OracleEnhancedAdapter.
|
116
116
|
The only prerequisite to running this code is that you have installed the ruby-oci8 gem on your machine.
|
117
117
|
email: billy.reisinger@gmail.com
|
118
118
|
executables:
|
@@ -174,7 +174,7 @@ rubyforge_project:
|
|
174
174
|
rubygems_version: 1.5.2
|
175
175
|
signing_key:
|
176
176
|
specification_version: 3
|
177
|
-
summary:
|
177
|
+
summary: Command-line tools for interacting with an Oracle database.
|
178
178
|
test_files:
|
179
179
|
- test/cli_test.rb
|
180
180
|
- test/client_test.rb
|