oraora 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/LICENSE +21 -0
- data/README.md +141 -0
- data/bin/oraora +48 -0
- data/lib/oraora.rb +9 -0
- data/lib/oraora/app.rb +298 -0
- data/lib/oraora/awareness.rb +78 -0
- data/lib/oraora/completion.rb +56 -0
- data/lib/oraora/context.rb +90 -0
- data/lib/oraora/credentials.rb +64 -0
- data/lib/oraora/logger.rb +19 -0
- data/lib/oraora/meta.rb +39 -0
- data/lib/oraora/meta/column.rb +45 -0
- data/lib/oraora/meta/database.rb +27 -0
- data/lib/oraora/meta/materialized_view.rb +48 -0
- data/lib/oraora/meta/object.rb +46 -0
- data/lib/oraora/meta/schema.rb +40 -0
- data/lib/oraora/meta/sequence.rb +33 -0
- data/lib/oraora/meta/subprogram.rb +36 -0
- data/lib/oraora/meta/table.rb +42 -0
- data/lib/oraora/meta/view.rb +41 -0
- data/lib/oraora/oci.rb +56 -0
- data/lib/oraora/terminal.rb +55 -0
- data/oraora.gemspec +22 -0
- data/spec/context_spec.rb +132 -0
- data/spec/credentials_spec.rb +83 -0
- metadata +154 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
module Oraora
|
2
|
+
class Meta
|
3
|
+
class Object
|
4
|
+
attr_reader :type
|
5
|
+
|
6
|
+
def initialize(schema, name, type = nil)
|
7
|
+
@schema = schema
|
8
|
+
@name = name
|
9
|
+
@type = type
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_from_oci(oci)
|
13
|
+
if !@type
|
14
|
+
@id, @type = oci.select_one("SELECT object_id, object_type FROM all_objects
|
15
|
+
WHERE owner = :schema AND object_name = :name
|
16
|
+
ORDER BY decode(namespace, 19, 0, 99)", @schema, @name) if !@type
|
17
|
+
raise NotExists if !@id
|
18
|
+
@id = @id.to_i
|
19
|
+
end
|
20
|
+
case @type
|
21
|
+
when 'TABLE' then Table.from_oci(oci, @schema, @name)
|
22
|
+
when 'VIEW' then View.from_oci(oci, @schema, @name)
|
23
|
+
when 'MATERIALIZED VIEW' then MaterializedView.from_oci(oci, @schema, @name)
|
24
|
+
when 'SEQUENCE' then Sequence.from_oci(oci, @schema, @name)
|
25
|
+
else self
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.from_oci(oci, schema, name, type = nil)
|
30
|
+
new(schema, name, type).load_from_oci(oci)
|
31
|
+
end
|
32
|
+
|
33
|
+
def describe(options = {})
|
34
|
+
<<-HERE.reset_indentation
|
35
|
+
Object #{@schema}.#{@name}
|
36
|
+
Id: #{@id}
|
37
|
+
Type: #{@type}
|
38
|
+
HERE
|
39
|
+
end
|
40
|
+
|
41
|
+
def list(options = {}, filter = nil)
|
42
|
+
raise NotApplicable, "Cannot list for this object"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Oraora
|
2
|
+
class Meta
|
3
|
+
class Schema
|
4
|
+
def initialize(name)
|
5
|
+
@name = name
|
6
|
+
end
|
7
|
+
|
8
|
+
def load_from_oci(oci)
|
9
|
+
@id, @created = oci.select_one("SELECT user_id, created FROM all_users WHERE username = :name", @name)
|
10
|
+
raise NotExists if !@id
|
11
|
+
@id = @id.to_i
|
12
|
+
@objects = oci.pluck("SELECT object_name, min(object_type) object_type FROM all_objects
|
13
|
+
WHERE owner = :name
|
14
|
+
AND object_type IN ('TABLE', 'VIEW', 'MATERIALIZED VIEW', 'SEQUENCE')
|
15
|
+
GROUP BY object_name
|
16
|
+
ORDER BY object_name", @name)
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.from_oci(oci, name)
|
21
|
+
new(name).load_from_oci(oci)
|
22
|
+
end
|
23
|
+
|
24
|
+
def describe(options = {})
|
25
|
+
<<-HERE.reset_indentation
|
26
|
+
Schema #{@name}
|
27
|
+
Id: #{@id}
|
28
|
+
Created: #{@created}
|
29
|
+
HERE
|
30
|
+
end
|
31
|
+
|
32
|
+
def list(options = {}, filter = nil)
|
33
|
+
objects = @objects.collect(&:first)
|
34
|
+
objects.reject! { |o| o =~ /^ISEQ\$\$/ || o =~ /^SYS_/ || o =~ /^ORA_/ } unless options['a']
|
35
|
+
objects.select! { |o| o =~ /^#{Regexp.escape(filter).gsub('\*', '.*').gsub('\?', '.')}$/ } if filter
|
36
|
+
objects
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative './object.rb'
|
2
|
+
|
3
|
+
module Oraora
|
4
|
+
class Meta
|
5
|
+
class Sequence < Object
|
6
|
+
def type
|
7
|
+
'SEQUENCE'
|
8
|
+
end
|
9
|
+
|
10
|
+
def load_from_oci(oci)
|
11
|
+
@min, @max, @inc, @last = oci.select_one("SELECT min_value, max_value, increment_by, last_number
|
12
|
+
FROM all_sequences
|
13
|
+
WHERE sequence_owner = :schema AND sequence_name = :name", @schema, @name)
|
14
|
+
raise NotExists if !@min
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def describe(options = {})
|
19
|
+
<<-HERE.reset_indentation
|
20
|
+
Sequence #{@schema}.#{@name}
|
21
|
+
Min value: #{@min.to_i}
|
22
|
+
Max value: #{@max.to_i}
|
23
|
+
Increment by: #{@inc.to_i}
|
24
|
+
Last value: #{@last.to_i}
|
25
|
+
HERE
|
26
|
+
end
|
27
|
+
|
28
|
+
def list(options = {}, filter = nil)
|
29
|
+
raise NotApplicable, "Nothing to list for sequence"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Oraora
|
2
|
+
class Meta
|
3
|
+
class Subprogram
|
4
|
+
attr_reader :id, :schema, :package, :name
|
5
|
+
|
6
|
+
def initialize(schema, package, name)
|
7
|
+
@schema = schema
|
8
|
+
@package = package
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_from_oci(oci)
|
13
|
+
@id =
|
14
|
+
oci.select_one("SELECT subprogram_id FROM all_procedues WHERE owner = :schema AND object_name = :package AND procedure_name = :name", @schema, @package, @name)
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.from_oci(oci, schema, package, name)
|
19
|
+
new(schema, package, name).load_from_oci(oci)
|
20
|
+
end
|
21
|
+
|
22
|
+
def describe(options = {})
|
23
|
+
<<-HERE.reset_indentation
|
24
|
+
Schema: #{@schema}
|
25
|
+
Package: #{@package}
|
26
|
+
Name: #{@name}
|
27
|
+
Id: #{@id}
|
28
|
+
HERE
|
29
|
+
end
|
30
|
+
|
31
|
+
def list(options = {}, filter = nil)
|
32
|
+
raise NotApplicable, "Nothing to list for subprogram"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative './object.rb'
|
2
|
+
|
3
|
+
module Oraora
|
4
|
+
class Meta
|
5
|
+
class Table < Object
|
6
|
+
def type
|
7
|
+
'TABLE'
|
8
|
+
end
|
9
|
+
|
10
|
+
def load_from_oci(oci)
|
11
|
+
@partitioned = oci.select_one("SELECT partitioned FROM all_tables WHERE owner = :schema AND table_name = :name", @schema, @name).first
|
12
|
+
raise NotExists if !@partitioned
|
13
|
+
@columns = oci.pluck("SELECT column_name, column_id, data_type, data_length, data_precision, data_scale, char_used, char_length " +
|
14
|
+
"FROM all_tab_columns WHERE owner = :schema AND table_name = :name ORDER BY column_id", @schema, @name).collect do |col|
|
15
|
+
Column.new(@schema, @name, col[0], id: col[1].to_i, type: col[2], length: col[3] && col[3].to_i,
|
16
|
+
precision: col[4] && col[4].to_i, scale: col[5] && col[5].to_i, char_used: col[6],
|
17
|
+
char_length: col[7] && col[7].to_i)
|
18
|
+
end
|
19
|
+
@columns_hash = Hash[@columns.collect { |col| [col.name, col] }]
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def describe(options = {})
|
24
|
+
<<-HERE.reset_indentation
|
25
|
+
Table #{@schema}.#{@name}
|
26
|
+
Partitioned: #{@partitioned}
|
27
|
+
HERE
|
28
|
+
end
|
29
|
+
|
30
|
+
def list(options = {}, filter = nil)
|
31
|
+
columns = @columns_hash.keys
|
32
|
+
columns.select! { |c| c =~ /^#{Regexp.escape(filter).gsub('\*', '.*').gsub('\?', '.')}$/ } if filter
|
33
|
+
columns
|
34
|
+
end
|
35
|
+
|
36
|
+
def columns(column)
|
37
|
+
raise NotExists if !@columns_hash[column]
|
38
|
+
@columns_hash[column]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative './object.rb'
|
2
|
+
|
3
|
+
module Oraora
|
4
|
+
class Meta
|
5
|
+
class View < Object
|
6
|
+
def type
|
7
|
+
'VIEW'
|
8
|
+
end
|
9
|
+
|
10
|
+
def load_from_oci(oci)
|
11
|
+
x = oci.select_one("SELECT 1 FROM all_views WHERE owner = :schema AND view_name = :name", @schema, @name).first
|
12
|
+
raise NotExists if !x
|
13
|
+
@columns = oci.pluck("SELECT column_name, column_id, data_type, data_length, data_precision, data_scale, char_used, char_length " +
|
14
|
+
"FROM all_tab_columns WHERE owner = :schema AND table_name = :name ORDER BY column_id", @schema, @name).collect do |col|
|
15
|
+
Column.new(@schema, @name, col[0], id: col[1].to_i, type: col[2], length: col[3] && col[3].to_i,
|
16
|
+
precision: col[4] && col[4].to_i, scale: col[5] && col[5].to_i, char_used: col[6],
|
17
|
+
char_length: col[7] && col[7].to_i)
|
18
|
+
end
|
19
|
+
@columns_hash = Hash[@columns.collect { |col| [col.name, col] }]
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def describe(options = {})
|
24
|
+
<<-HERE.reset_indentation
|
25
|
+
View #{@schema}.#{@name}
|
26
|
+
HERE
|
27
|
+
end
|
28
|
+
|
29
|
+
def list(options = {}, filter = nil)
|
30
|
+
columns = @columns_hash.keys
|
31
|
+
columns.select! { |c| c =~ /^#{Regexp.escape(filter).gsub('\*', '.*').gsub('\?', '.')}$/ } if filter
|
32
|
+
columns
|
33
|
+
end
|
34
|
+
|
35
|
+
def columns(column)
|
36
|
+
raise NotExists if !@columns_hash[column]
|
37
|
+
@columns_hash[column]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/oraora/oci.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
module Oraora
|
2
|
+
# Wrapper around OCI8 to add some extra stuff
|
3
|
+
class OCI < OCI8
|
4
|
+
# Wrapped in a separate thread as OCI8 seems to ignore interrupts
|
5
|
+
def initialize(*args)
|
6
|
+
ret = nil
|
7
|
+
thread = Thread.new { ret = super }
|
8
|
+
thread.join
|
9
|
+
ret
|
10
|
+
end
|
11
|
+
|
12
|
+
# Wrapped in a separate thread as OCI8 seems to ignore interrupts
|
13
|
+
def logoff
|
14
|
+
ret = nil
|
15
|
+
thread = Thread.new { ret = super }
|
16
|
+
thread.join
|
17
|
+
ret
|
18
|
+
end
|
19
|
+
|
20
|
+
# Wrapped in a separate thread with Interrupt handling
|
21
|
+
def exec(sql, *bindvars, &block)
|
22
|
+
ret = nil
|
23
|
+
thread = Thread.new { ret = super }
|
24
|
+
thread.join
|
25
|
+
ret
|
26
|
+
rescue Interrupt
|
27
|
+
self.break
|
28
|
+
raise
|
29
|
+
end
|
30
|
+
|
31
|
+
# Wrapped in a separate thread with Interrupt handling
|
32
|
+
def select_one(sql, *bindvars)
|
33
|
+
ret = nil
|
34
|
+
thread = Thread.new { ret = super }
|
35
|
+
thread.join
|
36
|
+
ret
|
37
|
+
rescue Interrupt
|
38
|
+
self.break
|
39
|
+
raise
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the query result as an array of arrays
|
43
|
+
def pluck(sql, *bindvars)
|
44
|
+
result = []
|
45
|
+
exec(sql, *bindvars) { |row| result << row }
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns first column of a query as an array
|
50
|
+
def pluck_one(sql, *bindvars)
|
51
|
+
result = []
|
52
|
+
exec(sql, *bindvars) { |row| result << row.first }
|
53
|
+
result
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Oraora
|
2
|
+
module Terminal
|
3
|
+
def self.width
|
4
|
+
HighLine::SystemExtensions.terminal_size[0]
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.height
|
8
|
+
HighLine::SystemExtensions.terminal_size[1]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.puts_grid(items)
|
12
|
+
# TODO: Disable terminal size check when not reading from terminal
|
13
|
+
terminal_cols = [width || 0, 32].max
|
14
|
+
object_cols = terminal_cols / 32
|
15
|
+
# TODO: Determine optimal object_cols
|
16
|
+
num_rows = (items.length + object_cols - 1) / object_cols
|
17
|
+
#@logger.debug "Determined #{num_rows} rows of #{object_cols} objects for #{items.count} objects and #{terminal_cols} terminal width"
|
18
|
+
(0...num_rows).each do |row|
|
19
|
+
line = ''
|
20
|
+
(0...object_cols).each do |col|
|
21
|
+
index = num_rows * col + row
|
22
|
+
line += items[index].ljust(32) if items[index]
|
23
|
+
end
|
24
|
+
puts line
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.puts_cursor(cursor)
|
29
|
+
# Column metadata
|
30
|
+
column_names = cursor.get_col_names
|
31
|
+
|
32
|
+
cursor.prefetch_rows = 1000
|
33
|
+
begin
|
34
|
+
# Fetch 1000 rows
|
35
|
+
output = []
|
36
|
+
column_lengths = Array.new(column_names.length, 1)
|
37
|
+
while output.length < 1000 && record = cursor.fetch
|
38
|
+
record.collect! { |val| val.is_a?(BigDecimal) ? val.to_s('F').gsub(/\.0+$/, '') : val.to_s }
|
39
|
+
output << record
|
40
|
+
column_lengths = column_lengths.zip(record.collect { |v| v.length}).collect(&:max)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Output
|
44
|
+
if !output.empty?
|
45
|
+
puts "%-*.*s " * column_names.length % column_lengths.zip(column_lengths, column_names).flatten
|
46
|
+
puts "%-*s " * column_names.length % column_lengths.zip(column_lengths.collect { |c| '-' * c }).flatten
|
47
|
+
output.each do |row|
|
48
|
+
puts "%-*s " * row.length % column_lengths.zip(row).flatten
|
49
|
+
end
|
50
|
+
puts
|
51
|
+
end
|
52
|
+
end while record
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/oraora.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'oraora'
|
3
|
+
s.version = '0.1.0'
|
4
|
+
s.summary = "Interactive command-line utility for Oracle"
|
5
|
+
s.description = "Interactive command-line utility for Oracle"
|
6
|
+
|
7
|
+
s.author = "kmehkeri"
|
8
|
+
s.email = 'kmehkeri@gmail.com'
|
9
|
+
s.homepage = 'http://rubygems.org/gems/oraora'
|
10
|
+
s.license = 'MIT'
|
11
|
+
|
12
|
+
s.files = `git ls-files`.split($/)
|
13
|
+
s.executables = `git ls-files -- bin`.split($/).map { |f| File.basename(f) }
|
14
|
+
|
15
|
+
s.add_runtime_dependency 'highline'
|
16
|
+
s.add_runtime_dependency 'ruby-oci8'
|
17
|
+
s.add_runtime_dependency 'indentation'
|
18
|
+
s.add_runtime_dependency 'colorize'
|
19
|
+
s.add_runtime_dependency 'bigdecimal'
|
20
|
+
|
21
|
+
s.add_development_dependency 'rspec'
|
22
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'oraora/context'
|
2
|
+
|
3
|
+
describe Oraora::Context do
|
4
|
+
|
5
|
+
describe '.initialize' do
|
6
|
+
it "should initialize from hash" do
|
7
|
+
context = Oraora::Context.new('V', schema: 'X', object: 'Y', object_type: 'TABLE')
|
8
|
+
expect( context.level ).to eql :object
|
9
|
+
expect( context.user ).to eql 'V'
|
10
|
+
expect( context.schema ).to eql 'X'
|
11
|
+
expect( context.object ).to eql 'Y'
|
12
|
+
expect( context.object_type ).to eql 'TABLE'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.su' do
|
17
|
+
it "should return a different context object" do
|
18
|
+
context = Oraora::Context.new('V', schema: 'X', object: 'Y', object_type: 'TABLE')
|
19
|
+
expect( context.su('Z') ).not_to eql context
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should store specified user" do
|
23
|
+
context = Oraora::Context.new('V', schema: 'X', object: 'Y', object_type: 'TABLE').su('Z')
|
24
|
+
expect( context.user ).to eql 'Z'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should store original context's data" do
|
28
|
+
context = Oraora::Context.new('V', schema: 'X', object: 'Y', object_type: 'TABLE').su('Z')
|
29
|
+
expect( context.schema ).to eql 'X'
|
30
|
+
expect( context.object ).to eql 'Y'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.dup' do
|
35
|
+
it "should return equal context" do
|
36
|
+
context = Oraora::Context.new('V', schema: 'X', object: 'Y', object_type: 'TABLE').dup
|
37
|
+
expect( context.user ).to eql 'V'
|
38
|
+
expect( context.schema ).to eql 'X'
|
39
|
+
expect( context.object ).to eql 'Y'
|
40
|
+
expect( context.object_type ).to eql 'TABLE'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#set & #traverse' do
|
45
|
+
it "should set root context correctly" do
|
46
|
+
context = Oraora::Context.new.set({})
|
47
|
+
expect( context.level ).to be_nil
|
48
|
+
expect( context.schema ).to be_nil
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set schema context correctly" do
|
52
|
+
context = Oraora::Context.new.set(schema: 'A')
|
53
|
+
expect( context.level ).to eql :schema
|
54
|
+
expect( context.schema ).to eql 'A'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should set column context correctly" do
|
58
|
+
context = Oraora::Context.new.set(schema: 'A', object: 'B', object_type: 'TABLE', column: 'C')
|
59
|
+
expect( context.level ).to eql :column
|
60
|
+
expect( context.schema ).to eql 'A'
|
61
|
+
expect( context.object ).to eql 'B'
|
62
|
+
expect( context.column ).to eql 'C'
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should set user correctly on the context" do
|
66
|
+
context = Oraora::Context.new('AA').set(schema: 'A')
|
67
|
+
expect( context.level ).to eql :schema
|
68
|
+
expect( context.user ).to eql 'AA'
|
69
|
+
expect( context.schema ).to eql 'A'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should save user when switching context" do
|
73
|
+
context = Oraora::Context.new('AA').set(schema: 'A')
|
74
|
+
context.set(schema: 'B')
|
75
|
+
expect( context.level ).to eql :schema
|
76
|
+
expect( context.user ).to eql 'AA'
|
77
|
+
expect( context.schema ).to eql 'B'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should raise error on invalid key" do
|
81
|
+
expect { Oraora::Context.new.set(foo: 'A') }.to raise_exception(Oraora::Context::InvalidKey)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should raise error on missing object_type when object is present" do
|
85
|
+
expect { Oraora::Context.new.set(schema: 'A', object: 'B') }.to raise_exception(Oraora::Context::InvalidKey)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should raise error on invalid combination of keys" do
|
89
|
+
expect { Oraora::Context.new.set(schema: 'A', column: 'B', subprogram: 'C') }.to raise_exception(Oraora::Context::InvalidKey)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#up" do
|
94
|
+
it "should do nothing when already at root" do
|
95
|
+
context = Oraora::Context.new.up
|
96
|
+
expect( context.level ).to be_nil
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should go up from object to schema level" do
|
100
|
+
context = Oraora::Context.new(nil, schema: 'A', object: 'B', object_type: 'TABLE').up
|
101
|
+
expect( context.level ).to eql :schema
|
102
|
+
expect( context.schema ).to eql 'A'
|
103
|
+
expect( context.object ).to be_nil
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should go up from column to object level" do
|
107
|
+
context = Oraora::Context.new(nil, schema: 'X', object: 'Y', object_type: 'TABLE', column: 'Z').up
|
108
|
+
expect( context.level ).to eql :object
|
109
|
+
expect( context.schema ).to eql 'X'
|
110
|
+
expect( context.object ).to be_eql 'Y'
|
111
|
+
expect( context.column ).to be_nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#prompt' do
|
116
|
+
it "should display correct prompt for context" do
|
117
|
+
{
|
118
|
+
{} => '/',
|
119
|
+
{ schema: 'Q' } => 'Q',
|
120
|
+
{ schema: 'U' } => '~',
|
121
|
+
{ schema: 'A', object: 'B', object_type: 'TABLE' } => 'A.B',
|
122
|
+
{ schema: 'U', object: 'B', object_type: 'PACKAGE' } => '~.B',
|
123
|
+
{ schema: 'U', object: 'Y', object_type: 'TABLE', column: 'Z' } => '~.Y.Z',
|
124
|
+
{ schema: 'MMM', object: 'NNN', object_type: 'VIEW', column: 'TEST' } => 'MMM.NNN.TEST'
|
125
|
+
}.each do |hash, prompt|
|
126
|
+
expect( Oraora::Context.new('U', hash).prompt ).to eql prompt
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|