Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,22 @@ plsql.activerecord_class = ActiveRecord::Base
and then you do not need to specify plsql.connection (this is also safer when ActiveRecord reestablishes connection to database).


### JRuby JDBC connection:

When using JRuby, the `connect!` method with `:host` and `:database` options uses the thin-style service name syntax by default:

```ruby
# Connects using service name syntax: jdbc:oracle:thin:@//localhost:1521/MYSERVICENAME
plsql.connect! username: "hr", password: "hr", host: "localhost", database: "MYSERVICENAME"
```

If you need to connect using the legacy SID syntax (for Oracle databases older than 12c), prefix the database name with a colon:

```ruby
# Connects using SID syntax: jdbc:oracle:thin:@localhost:1521:MYSID
plsql.connect! username: "hr", password: "hr", host: "localhost", database: ":MYSID"
```

### Cheat Sheet:

You may have a look at this [Cheat Sheet](http://cheatography.com/jgebal/cheat-sheets/ruby-plsql-cheat-sheet/) for instructions on how to use ruby-plsql
Expand Down
25 changes: 21 additions & 4 deletions lib/plsql/jdbc_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,31 @@
module PLSQL
class JDBCConnection < Connection # :nodoc:
def self.create_raw(params)
url = jdbc_connection_url(params)
new(java.sql.DriverManager.getConnection(url, params[:username], params[:password]))
end

def self.jdbc_connection_url(params)
database = params[:database]
url = if ENV["TNS_ADMIN"] && database && !params[:host] && !params[:url]
if ENV["TNS_ADMIN"] && database && database !~ %r{\A[:/]} && !params[:host] && !params[:url]
"jdbc:oracle:thin:@#{database}"
else
database = ":#{database}" unless database.match(/^(\:|\/)/)
params[:url] || "jdbc:oracle:thin:@#{params[:host] || 'localhost'}:#{params[:port] || 1521}#{database}"
return params[:url] if params[:url]

raise ArgumentError, "database or url option is required" if database.nil? || database.empty?

host = params[:host] || "localhost"
port = params[:port] || 1521

if database =~ /^:/
# SID syntax: jdbc:oracle:thin:@host:port:SID
"jdbc:oracle:thin:@#{host}:#{port}#{database}"
else
# service name syntax: jdbc:oracle:thin:@//host:port/service_name
database = "/#{database}" unless database =~ /^\//
"jdbc:oracle:thin:@//#{host}:#{port}#{database}"
end
end
new(java.sql.DriverManager.getConnection(url, params[:username], params[:password]))
end

def set_time_zone(time_zone = nil)
Expand Down
2 changes: 1 addition & 1 deletion lib/plsql/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def raw_connection=(raw_conn) # :nodoc:
# or
#
# plsql.connection = java.sql.DriverManager.getConnection(
# "jdbc:oracle:thin:@#{database_host}:#{database_port}/#{database_service_name}",
# "jdbc:oracle:thin:@//#{database_host}:#{database_port}/#{database_service_name}",
# database_user, database_password)
#
def connection=(conn)
Expand Down
72 changes: 72 additions & 0 deletions spec/plsql/connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,78 @@

end

describe "JDBC connection URL" do
it "should use service name syntax by default" do
url = PLSQL::JDBCConnection.jdbc_connection_url(host: "myhost", port: 1521, database: "MYSERVICENAME")
expect(url).to eq "jdbc:oracle:thin:@//myhost:1521/MYSERVICENAME"
end

it "should use default host and port when not specified" do
original_tns_admin = ENV.delete("TNS_ADMIN")
begin
url = PLSQL::JDBCConnection.jdbc_connection_url(database: "/MYSERVICENAME")
expect(url).to eq "jdbc:oracle:thin:@//localhost:1521/MYSERVICENAME"
ensure
ENV["TNS_ADMIN"] = original_tns_admin
end
end

it "should use SID syntax when database starts with colon" do
url = PLSQL::JDBCConnection.jdbc_connection_url(host: "myhost", port: 1521, database: ":MYSID")
expect(url).to eq "jdbc:oracle:thin:@myhost:1521:MYSID"
end

it "should use service name syntax when database starts with slash" do
url = PLSQL::JDBCConnection.jdbc_connection_url(host: "myhost", port: 1521, database: "/MYSERVICENAME")
expect(url).to eq "jdbc:oracle:thin:@//myhost:1521/MYSERVICENAME"
end

it "should use TNS alias when TNS_ADMIN is set and no host specified" do
original_tns_admin = ENV["TNS_ADMIN"]
ENV["TNS_ADMIN"] = "/path/to/tns"
begin
url = PLSQL::JDBCConnection.jdbc_connection_url(database: "MYALIAS")
expect(url).to eq "jdbc:oracle:thin:@MYALIAS"
ensure
ENV["TNS_ADMIN"] = original_tns_admin
end
end

it "should use service name syntax when TNS_ADMIN is set and database starts with slash" do
original_tns_admin = ENV["TNS_ADMIN"]
ENV["TNS_ADMIN"] = "/path/to/tns"
begin
url = PLSQL::JDBCConnection.jdbc_connection_url(database: "/MYSERVICENAME")
expect(url).to eq "jdbc:oracle:thin:@//localhost:1521/MYSERVICENAME"
ensure
ENV["TNS_ADMIN"] = original_tns_admin
end
end

it "should use SID syntax when TNS_ADMIN is set and database starts with colon" do
original_tns_admin = ENV["TNS_ADMIN"]
ENV["TNS_ADMIN"] = "/path/to/tns"
begin
url = PLSQL::JDBCConnection.jdbc_connection_url(database: ":MYSID")
expect(url).to eq "jdbc:oracle:thin:@localhost:1521:MYSID"
ensure
ENV["TNS_ADMIN"] = original_tns_admin
end
end

it "should raise ArgumentError when database and url are not provided" do
expect {
PLSQL::JDBCConnection.jdbc_connection_url(host: "myhost")
}.to raise_error(ArgumentError, /database or url option is required/)
end

it "should use custom URL when provided" do
custom_url = "jdbc:oracle:thin:@//custom:1522/MYSERVICENAME"
url = PLSQL::JDBCConnection.jdbc_connection_url(host: "myhost", database: "MYSERVICENAME", url: custom_url)
expect(url).to eq custom_url
end
end if defined?(JRuby)

describe "logoff" do
before(:each) do
# restore connection before each test
Expand Down
5 changes: 2 additions & 3 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@
DATABASE_NAME = ENV["DATABASE_NAME"] || "orcl"
end

DATABASE_SERVICE_NAME = (defined?(JRUBY_VERSION) ? "/" : "") +
(ENV["DATABASE_SERVICE_NAME"] || DATABASE_NAME)
DATABASE_SERVICE_NAME = ENV["DATABASE_SERVICE_NAME"] || DATABASE_NAME
DATABASE_HOST = ENV["DATABASE_HOST"] || "localhost"
DATABASE_PORT = (ENV["DATABASE_PORT"] || 1521).to_i
DATABASE_USERS_AND_PASSWORDS = [
Expand Down Expand Up @@ -77,7 +76,7 @@ def get_connection_url
unless defined?(JRUBY_VERSION)
(ENV["DATABASE_USE_TNS"] == "NO") ? get_eazy_connect_url("/") : DATABASE_NAME
else
"jdbc:oracle:thin:@#{get_eazy_connect_url}"
"jdbc:oracle:thin:@//#{get_eazy_connect_url("/")}"
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/support/test_db.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def connection
Timeout::timeout(5) {
if defined?(JRUBY_VERSION)
@connection = java.sql.DriverManager.get_connection(
"jdbc:oracle:thin:@127.0.0.1:1521/XE",
"jdbc:oracle:thin:@//127.0.0.1:1521/XE",
"system",
"oracle"
)
Expand Down