oci8_simple 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|