Class: Oraora::App

Inherits:
Object
  • Object
show all
Defined in:
lib/oraora/app.rb

Defined Under Namespace

Classes: InvalidCommand

Constant Summary collapse

SQL_INITIAL_KEYWORDS =
%w(
  SELECT COUNT FROM PARTITION WHERE CONNECT GROUP MODEL UNION INTERSECT MINUS ORDER
  INSERT UPDATE SET DELETE MERGE
  TRUNCATE ADD DROP CREATE RENAME ALTER PURGE GRANT REVOKE
  COMPILE ANALYZE COMMIT ROLLBACK
  IDENTIFIED PROFILE ACCOUNT QUOTA DEFAULT TEMPORARY
)
SQL_KEYWORDS =
SQL_INITIAL_KEYWORDS + %w(
  TABLE VIEW MATERIALIZED COLUMN PROCEDURE FUNCTION PACKAGE TYPE BODY
  USER SESSION SCHEMA SYSTEM DATABASE
  REPLACE AND OR
)
ORAORA_KEYWORDS =
%w(c cd l ls d desc describe x exit su sudo - -- --- . ! ? /)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(credentials, role, logger, context = nil) ⇒ App

Returns a new instance of App.



22
23
24
25
26
27
# File 'lib/oraora/app.rb', line 22

def initialize(credentials, role, logger, context = nil)
  @credentials = credentials
  @user, @database, @role = (credentials.user ? credentials.user.upcase : nil), credentials.database, (role ? role.upcase.to_sym : nil)
  @logger = logger
  @context = context
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



20
21
22
# File 'lib/oraora/app.rb', line 20

def context
  @context
end

#metaObject (readonly)

Returns the value of attribute meta.



20
21
22
# File 'lib/oraora/app.rb', line 20

def meta
  @meta
end

Instance Method Details

#run(command = nil) ⇒ Object

Run the application with given credentials



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/oraora/app.rb', line 30

def run(command = nil)
  last_interrupt = Time.now - 2

  # Connect to Oracle
  @logger.debug "Connecting: #{@credentials}" + (@role ? " as #{@role}" : '')
  logon
  @logger.info "Oraora v#{VERSION}. Type '?' for quick help"
  @user ||= @oci.username
  @context ||= Context.new(@user, schema: @user)

  # Readline tab completion
  Readline.completion_append_character = ''
  Readline.completion_proc = Completion.new(self).comp_proc

  if command
    process(command)
  else
    # Main loop
    buffer = ''
    prompt = @context.prompt + ' ' + (@role== :SYSDBA ? '#' : '$') + ' '

    while !@terminate do
      begin
        line = Readline.readline(prompt.green.bold)
        break if !line

        line.strip!
        Readline::HISTORY << line if line != '' # Manually add to history to avoid empty lines
        buffer += (buffer == '' ? '' : "\n") + line

        # Process buffer on one of these conditions:
        # * This is first line of the buffer and is empty
        # * This is first line of the buffer and is a Oraora command
        # * Entire buffer is a comment
        # * Line is '/' or ends with ';'
        if (buffer == line && (line =~ /^(#{ORAORA_KEYWORDS.collect { |k| Regexp.escape(k) }.join('|')})($|\s+)/i || line =~ /^\s*$/)) || line == '/' || line =~ /;$/ || buffer =~ /\A\s*--/ || buffer =~ /\A\s*\/\*.*\*\/\s*\Z/m
          process(buffer)
          buffer = ''
        end

        if buffer == ''
          prompt = @context.prompt + ' ' + (@role == :SYSDBA ? '#' : '$') + ' '
        else
          prompt = @context.prompt.gsub(/./, ' ') + ' % '
        end

      rescue Interrupt
        if Time.now - last_interrupt < 2
          @logger.warn "Exit on CTRL+C"
          terminate
        else
          @logger.warn "CTRL+C, hit again within 2 seconds to quit"
          buffer = ''
          prompt = @context.prompt + ' ' + (@role == :SYSDBA ? '#' : '$') + ' '
          last_interrupt = Time.now
        end
      end
    end

  end

  if !@terminate
    @logger.debug "Exiting on end of input"
    terminate
  end
end