<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>ray_apps_blog &#187; oracle</title>
	<atom:link href="http://blog.rayapps.com/category/oracle/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.rayapps.com</link>
	<description>About Ruby, Oracle, Mac and others</description>
	<lastBuildDate>Mon, 21 Jun 2010 14:02:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.rayapps.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/0dbc428d172e04af3f6bb51ac225001b?s=96&#038;d=http://s2.wp.com/i/buttonw-com.png</url>
		<title>ray_apps_blog &#187; oracle</title>
		<link>http://blog.rayapps.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.rayapps.com/osd.xml" title="ray_apps_blog" />
	<atom:link rel='hub' href='http://blog.rayapps.com/?pushpress=hub'/>
		<item>
		<title>Oracle enhanced adapter 1.3.0 is Rails 3 compatible</title>
		<link>http://blog.rayapps.com/2010/06/21/oracle-enhanced-adapter-1-3-0-is-rails-3-compatible/</link>
		<comments>http://blog.rayapps.com/2010/06/21/oracle-enhanced-adapter-1-3-0-is-rails-3-compatible/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 14:02:00 +0000</pubDate>
		<dc:creator>Raimonds Simanovskis</dc:creator>
				<category><![CDATA[oracle]]></category>
		<category><![CDATA[oracle-enhanced]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">https://rayapps.wordpress.com/?p=174</guid>
		<description><![CDATA[Rails 3 is in final finishing stage (currently in beta4) and therefore I released new Oracle enhanced adapter version 1.3.0 which I was working on during last months. Rails 3 compatibility The major enhancement is that Oracle enhanced adapter is now compatible with Rails 3. To achieve that I also developed Oracle SQL compiler for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=174&subd=rayapps&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>Rails 3 is in final finishing stage (currently in beta4) and therefore I released new <a href="http://github.com/rsim/oracle-enhanced">Oracle enhanced adapter</a> version 1.3.0 which I was working on during last months.</p>
<h3>Rails 3 compatibility</h3>
<p><img src="http://rayapps.files.wordpress.com/2010/06/rails3.gif?w=150&#038;h=112" alt="rails3.gif" border="0" width="150" height="112" style="float:right;padding-left:20px;" /><br />
The major enhancement is that Oracle enhanced adapter is now compatible with Rails 3. To achieve that I also developed Oracle SQL compiler for <a href="http://github.com/rails/arel">Arel</a> gem which is used now by ActiveRecord to generate SQL statements. When using Oracle enhanced adapter with Rails 3 you will notice several major changes:</p>
<ul>
<li>Table and column names are always quoted and in uppercase to avoid the need for checking Oracle reserved words.<br />
E.g. now Post.all will generate query <br />SELECT &#8220;POSTS&#8221;.* FROM &#8220;POSTS&#8221;</li>
<li>Better support for limit and offset options (when possible just ROWNUM condition in WHERE clause is used without using subqueries).<br />
E.g. Post.first (or Post.limit(1)) will generate query <br />SELECT &#8220;POSTS&#8221;.* FROM &#8220;POSTS&#8221; WHERE ROWNUM &lt;= 1<br />
but Post.limit(1).offset(1) will generate <br />select * from (select raw_sql_.*, rownum raw_rnum_ from (SELECT &#8220;EMPLOYEES&#8221;.* FROM &#8220;EMPLOYEES&#8221;) raw_sql_ where rownum &lt;= 2) where raw_rnum_ &gt; 1
</li>
</ul>
<p>When using Oracle enhanced adapter with current version of Rails 3 and Arel it is necessary to turn on table and column caching option in all environments as otherwise Arel gem will cause very many SQL queries on data dictionary tables on each request. To achieve that you need to include in some initializer file:</p>
<pre class="brush: ruby; light: true;">
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = true
</pre>
<p>I have published simple <a href="http://github.com/rsim/rails3_oracle_sample">Rails 3 demo application</a> using Rails 3 and Oracle enhanced adapter. You can take a look at <a href="http://github.com/rsim/rails3_oracle_sample/blob/master/Gemfile">Gemfile</a> and <a href="http://github.com/rsim/rails3_oracle_sample/blob/master/config/initializers/oracle.rb">Oracle initializer file</a> to see examples how to configure Oracle enhanced adapter with Rails 3.</p>
<h3>Rails 2.3 compatibility</h3>
<p>Oracle enhanced adapter version 1.3.0 is still compatible with Rails 2.3 (I am testing it against Rails 2.3.5 and 2.3.8) and it is recommended to upgrade if you are on Rails 2.3 and plan to upgrade to Rails 3.0 later. But if you are still on Rails 2.2 or earlier then there might be issues with Oracle enhanced adapter 1.3.0 as I am using some Rails methods which appeared just in Rails 2.3 &#8211; so in this case it might be safer to stay on previous Oracle enhanced adapter version 1.2.4 until you upgrade to latest Rails version.</p>
<h3>Oracle CONTEXT index support</h3>
<p>Every edition of Oracle database includes <a href="http://www.oracle.com/technology/products/text/index.html">Oracle Text</a> option for free which provides different full text indexing capabilities. Therefore in Oracle database case you don&#8217;t need external full text indexing and searching engines which can simplify your application deployment architecture.</p>
<p>The most commonly used index type is CONTEXT index which can be used for efficient full text search. Most of CONTEXT index creation examples show how to create simple full text index on one table and one column. But if you want to create more complex full text indexes on multiple columns or even on multiple tables and columns then you need to write your custom procedures and custom index refreshing logic.</p>
<p>Therefore to make creation of more complex full text indexes easier I have created additional add_context_index and remove_context_index methods that can be used in migrations and which creates additional stored procedures and triggers when needed in standardized way.</p>
<p>This is how you can create simple single column index:</p>
<pre class="brush: ruby; light: true;">
add_context_index :posts, :title
</pre>
<p>And you can perform search using this index with</p>
<pre class="brush: ruby; light: true;">
Post.contains(:title, 'word')
</pre>
<p>This is how you create index on several columns (which will generate additional stored procedure for providing XML document with specified columns to indexer):</p>
<pre class="brush: ruby; light: true;">
add_context_index :posts, [:title, :body]
</pre>
<p>And you can search either in all columns or specify in which column you want to search (as first argument you need to specify first column name as this is the column which is referenced during index creation):</p>
<pre class="brush: ruby; light: true;">
Post.contains(:title, 'word')
Post.contains(:title, 'word within title')
Post.contains(:title, 'word within body')
</pre>
<p>See Oracle Text documentation for syntax that you can use in CONTAINS function in SELECT WHERE clause.</p>
<p>You can also specify some dummy main column name when creating multiple column index as well as specify to update index automatically after each commit (as otherwise you need to synchronize index manually or schedule periodic update):</p>
<pre class="brush: ruby; light: true;">
add_context_index :posts, [:title, :body], :index_column =&gt; :all_text,
  :sync =&gt; 'ON COMMIT'
Post.contains(:all_text, 'word')
</pre>
<p>Or you can specify that index should be updated when specified columns are updated (e.g. in ActiveRecord you can specify to trigger index update when created_at or updated_at columns are updated). Otherwise index is updated only when main index column is updated.</p>
<pre class="brush: ruby; light: true;">
add_context_index :posts, [:title, :body], :index_column =&gt; :all_text,
  :sync =&gt; 'ON COMMIT', :index_column_trigger_on =&gt; [:created_at, :updated_at]
</pre>
<p>And you can even create index on multiple tables by providing SELECT statements which should be used to fetch necessary columns from related tables:</p>
<pre class="brush: ruby; light: true;">
add_context_index :posts,
  [:title, :body,
  # specify aliases always with AS keyword
  &quot;SELECT comments.author AS comment_author, comments.body AS comment_body FROM comments WHERE comments.post_id = :id&quot;
  ],
  :name =&gt; 'post_and_comments_index',
  :index_column =&gt; :all_text,
  :index_column_trigger_on =&gt; [:updated_at, :comments_count],
  :sync =&gt; 'ON COMMIT'
# search in any table columns
Post.contains(:all_text, 'word')
# search in specified column
Post.contains(:all_text, &quot;aaa within title&quot;)
Post.contains(:all_text, &quot;bbb within comment_author&quot;)
</pre>
<p>In terms of Oracle Text performance in most cases it is good enough (typical response in not more that hundreds of milliseconds). But from my experience it is still slower compared to dedicated full text search engines like Sphinx. So in case if Oracle Text performance is not good enough (if you need all search operations return in tens of milliseconds) then you probably need to evaluate dedicated search engines like Sphinx or Lucene.</p>
<h3>Other changes</h3>
<p>Please see <a href="http://github.com/rsim/oracle-enhanced/blob/master/History.txt">change history file</a> or <a href="http://github.com/rsim/oracle-enhanced/commits/master">commit list</a> to see more detailed list of changes in this version.</p>
<h3>Install</h3>
<p>As always you can install Oracle enhanced adapter on any Ruby platform (Ruby 1.8.7 or Ruby 1.9.1/1.9.2 or JRuby) with</p>
<p>gem install activerecord-oracle_enhanced-adapter</p>
<p>If you have any questions please use <a href="http://groups.google.com/group/oracle-enhanced">discussion group</a> or <a href="http://github.com/rsim/oracle-enhanced/issues">report issues at GitHub</a> or post comments here.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rayapps.wordpress.com/174/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rayapps.wordpress.com/174/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rayapps.wordpress.com/174/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rayapps.wordpress.com/174/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rayapps.wordpress.com/174/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rayapps.wordpress.com/174/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rayapps.wordpress.com/174/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rayapps.wordpress.com/174/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rayapps.wordpress.com/174/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rayapps.wordpress.com/174/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=174&subd=rayapps&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.rayapps.com/2010/06/21/oracle-enhanced-adapter-1-3-0-is-rails-3-compatible/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a94fbe334eb75d80da9dd0d3d352df1b?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">elietas</media:title>
		</media:content>

		<media:content url="http://rayapps.files.wordpress.com/2010/06/rails3.gif" medium="image">
			<media:title type="html">rails3.gif</media:title>
		</media:content>
	</item>
		<item>
		<title>Please vote for my Ruby session proposals at Oracle OpenWorld</title>
		<link>http://blog.rayapps.com/2010/06/17/please-vote-for-my-ruby-session-proposals-at-oracle-openworld/</link>
		<comments>http://blog.rayapps.com/2010/06/17/please-vote-for-my-ruby-session-proposals-at-oracle-openworld/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 08:32:40 +0000</pubDate>
		<dc:creator>Raimonds Simanovskis</dc:creator>
				<category><![CDATA[oracle]]></category>
		<category><![CDATA[oracle-enhanced]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">https://rayapps.wordpress.com/?p=169</guid>
		<description><![CDATA[I am trying to tell more people at Oracle OpenWorld about Ruby and Rails and how it can be used with Oracle database. Unfortunately my session proposals were rejected by organizers but now there is a second chance to propose sessions at mix.oracle.com and top voted sessions will be accepted for conference. But currently my [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=169&subd=rayapps&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.oracle.com/us/openworld/index.htm"><img src="http://rayapps.files.wordpress.com/2010/06/oow2010.png?w=344&#038;h=106" alt="oow2010.png" border="0" width="344" height="106" align="right" style="padding:0 0 10px 20px;"></a>I am trying to tell more people at <a href="http://www.oracle.com/us/openworld/index.htm">Oracle OpenWorld</a> about Ruby and Rails and how it can be used with Oracle database. Unfortunately my session proposals were rejected by organizers but now there is a second chance to propose sessions at <a href="http://mix.oracle.com">mix.oracle.com</a>  and top voted sessions will be accepted for conference. But currently my proposed sessions do not have enough votes :(</p>
<p>I would be grateful if my blog readers and Ruby on Oracle supporters would vote for my sessions <a href="https://mix.oracle.com/oow10/proposals/10704-fast-web-applications-development-with-ruby-on-rails-on-oracle">Fast Web Applications Development with Ruby on Rails on Oracle</a> and <a href="https://mix.oracle.com/oow10/proposals/10703-pl-sql-unit-testing-can-be-fun">PL/SQL Unit Testing Can Be Fun!</a>.</p>
<p>You need to log in to <a href="http://mix.oracle.com">mix.oracle.com</a> with your oracle.com login (or you should create new one if you don&#8217;t have it). And also you need to vote for at least one more session as well (as votes are counted if you have voted for at least 3 sessions). Voting should be done until end of this week (June 20). </p>
<p>And if you have other oracle_enhanced or ruby-plsql users in your<br />
organization then please ask their support as well :) </p>
<p>Thanks in advance!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rayapps.wordpress.com/169/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rayapps.wordpress.com/169/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rayapps.wordpress.com/169/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rayapps.wordpress.com/169/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rayapps.wordpress.com/169/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rayapps.wordpress.com/169/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rayapps.wordpress.com/169/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rayapps.wordpress.com/169/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rayapps.wordpress.com/169/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rayapps.wordpress.com/169/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=169&subd=rayapps&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.rayapps.com/2010/06/17/please-vote-for-my-ruby-session-proposals-at-oracle-openworld/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a94fbe334eb75d80da9dd0d3d352df1b?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">elietas</media:title>
		</media:content>

		<media:content url="http://rayapps.files.wordpress.com/2010/06/oow2010.png" medium="image">
			<media:title type="html">oow2010.png</media:title>
		</media:content>
	</item>
		<item>
		<title>ruby-plsql 0.4.2 &#8211; better support for object types and types in packages</title>
		<link>http://blog.rayapps.com/2010/02/26/ruby-plsql-0-4-2-better-support-for-object-types-and-types-in-packages/</link>
		<comments>http://blog.rayapps.com/2010/02/26/ruby-plsql-0-4-2-better-support-for-object-types-and-types-in-packages/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 16:43:04 +0000</pubDate>
		<dc:creator>Raimonds Simanovskis</dc:creator>
				<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://rayapps.wordpress.com/?p=164</guid>
		<description><![CDATA[I just released ruby-plsql version 0.4.2 which mainly adds support for more PL/SQL procedure parameter types. See change history file for more detailed list of changes. Object types and object methods Now you can use ruby-plsql to construct PL/SQL objects and call methods on these object. For example, if you have the following type defined: [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=164&subd=rayapps&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>I just released <a href="http://github.com/rsim/ruby-plsql">ruby-plsql</a> version 0.4.2 which mainly adds support for more PL/SQL procedure parameter types. See <a href="http://github.com/rsim/ruby-plsql/blob/master/History.txt">change history</a> file for more detailed list of changes.</p>
<h3>Object types and object methods</h3>
<p>Now you can use ruby-plsql to construct PL/SQL objects and call methods on these object. For example, if you have the following type defined:</p>
<pre class="brush: sql; light: true;">
CREATE OR REPLACE TYPE t_address AS OBJECT (
  street    VARCHAR2(50),
  city      VARCHAR2(50),
  country   VARCHAR2(50),
  CONSTRUCTOR FUNCTION t_address(p_full_address VARCHAR2)
    RETURN SELF AS RESULT,
  MEMBER FUNCTION display_address(p_separator VARCHAR2 DEFAULT ',') RETURN VARCHAR2,
  MEMBER PROCEDURE set_country(p_country VARCHAR2),
  STATIC FUNCTION create_address(p_full_address VARCHAR2) RETURN t_address
);
</pre>
<p>Then you can construct PL/SQL objects and call methods on them:</p>
<pre class="brush: ruby; light: true;">
# call default constructor with named parameters
address = plsql.t_address(:street =&gt; 'Street', :city =&gt; 'City', :country =&gt; 'Country')
# call default constructor with sequential parameters
address = plsql.t_address('Street', 'City', 'Country')
# call custom constructor
address = plsql.t_address('Street, City, Country')
address = plsql.t_address(:p_full_address =&gt; 'Street, City, Country')

# returned PL/SQL object is Hash object in Ruby
address == {:street =&gt; 'Street', :city =&gt; 'City', :country =&gt; 'Country'}

# but in addition you can call PL/SQL methods on it
address.display_address == 'Street, City, Country'
address.set_country('Other') == {:street =&gt; 'Street', :city =&gt; 'City', :country =&gt; 'Other'}

# or you can call object member methods also with explicit self parameter
plsql.t_address.display_address(:self =&gt; {:street =&gt; 'Street', :city =&gt; 'City', :country =&gt; 'Other'}, :p_separator =&gt; ',') == 'Street, City, Country'

# or you can call static methods of type
plsql.t_address.create_address('Street, City, Country') == {:street =&gt; 'Street', :city =&gt; 'City', :country =&gt; 'Country'}
</pre>
<h3>Record types and table of record types inside packages</h3>
<p>Now you can call Pl/SQL procedures with parameters which have record or table of record type that is defined inside PL/SQL package. For example if you have the following package:</p>
<pre class="brush: sql; light: true;">
CREATE OR REPLACE PACKAGE test_records IS
  TYPE t_employee IS RECORD(
    employee_id   NUMBER(15),
    first_name    VARCHAR2(50),
    last_name     VARCHAR2(50),
    hire_date     DATE
  );
  TYPE t_employees IS TABLE OF t_employee;
  TYPE t_employees2 IS TABLE OF t_employee
    INDEX BY BINARY_INTEGER;
  FUNCTION test_employee (p_employee IN t_employee)
    RETURN t_employee;
  FUNCTION test_employees (p_employees IN t_employees)
    RETURN t_employees;
  FUNCTION test_employees2 (p_employees IN t_employees2)
    RETURN t_employees2;
END;
</pre>
<p>Then you can call these package functions from Ruby:</p>
<pre class="brush: ruby; light: true;">
employee = {
  :employee_id =&gt; 1,
  :first_name =&gt; 'First',
  :last_name =&gt; 'Last',
  :hire_date =&gt; Time.local(2010,2,26)
}
# PL/SQL record corresponds to Ruby Hash
plsql.test_records.test_employee(employee) == employee
# PL/SQL table corresponds to Ruby Array
plsql.test_records.test_employees([employee, employee]) == [employee, employee]
# PL/SQL index-by table corresponds to Ruby Hash
plsql.test_records.test_employees({1 =&gt; employee, 2 =&gt; employee}) == {1 =&gt; employee, 2 =&gt; employee}
</pre>
<p>If you will use table types defined inside PL/SQL packages then ruby-plsql will dynamically create session specific temporary tables which will be used to pass and get table parameter values. To ensure that these session specific temporary tables will be dropped you need to explicitly call plsql.logoff to close connection. For example, if you use <a href="http://github.com/rsim/ruby-plsql-spec">ruby-plsql-spec</a> for PL/SQL unit testing then in spec_helper.rb include</p>
<pre class="brush: ruby; light: true;">
at_exit do
  plsql.logoff
end
</pre>
<p>to ensure that connection will be closed with plsql.logoff before Ruby script will exit. But in case of some script failure if this was not executed and you notice that there are temporary tables with RUBY_ prefix in your schema then you can call plsql.connection.drop_all_ruby_temporary_tables to drop all temporary tables.</p>
<h3>Establish new connection</h3>
<p>Now there is simpler <strong>connect!</strong> method how to establish new ruby-plsql connection when you need a new connection just for ruby-plsql needs. You can do it in several ways:</p>
<pre class="brush: ruby; light: true;">
plsql.connect! username, password, database_tns_alias
plsql.connect! username, password, :host =&gt; host, :port =&gt; port, :database =&gt; database
plsql.connect! :username =&gt; username, :password =&gt; password, :database =&gt; database_tns_alias
plsql.connect! :username =&gt; username, :password =&gt; password, :host =&gt; host, :port =&gt; port, :database =&gt; database
</pre>
<p>And the good thing is that this method will work both with MRI 1.8 or 1.9 or with JRuby &#8211; you do not need to change the way how you are establishing connection to database.</p>
<h3>Savepoints</h3>
<p>Now there is simpler way how to define savepoints and how to rollback to savepoint:</p>
<pre class="brush: ruby; light: true;">
plsql.savepoint &quot;before_something&quot;
plsql.rollback_to &quot;before_something&quot;
</pre>
<h3>Check validity of database objects</h3>
<p>Now ruby-plsql will check if referenced database object is valid before trying to call it. And if it will not be valid then corresponding compilation error will be displayed. For example, if you have invalid database object:</p>
<pre class="brush: sql; light: true;">
CREATE OR REPLACE FUNCTION test_invalid_function(p_dummy VARCHAR2) RETURN VARCHAR2 IS
  l_dummy invalid_table.invalid_column%TYPE;
BEGIN
  RETURN p_dummy;
END;
</pre>
<p>then when trying to call it</p>
<pre class="brush: ruby; light: true;">
plsql.test_invalid_function('dummy')
</pre>
<p>you will get the following error message:</p>
<pre class="brush: plain; light: true;">
ArgumentError: Database object 'HR.TEST_INVALID_FUNCTION' is not in valid status
Error on line    2:   l_dummy invalid_table.invalid_column%TYPE;
     position   11: PLS-00201: identifier 'INVALID_TABLE.INVALID_COLUMN' must be declared
     position   11: PL/SQL: Item ignored
</pre>
<h3>Other improvements</h3>
<p>See <a href="http://github.com/rsim/ruby-plsql/blob/master/History.txt">History.txt</a> file for other new features and improvements and see RSpec tests in <a href="http://github.com/rsim/ruby-plsql/tree/master/spec/plsql/">spec directory</a> for more usage examples.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rayapps.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rayapps.wordpress.com/164/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rayapps.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rayapps.wordpress.com/164/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rayapps.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rayapps.wordpress.com/164/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rayapps.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rayapps.wordpress.com/164/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rayapps.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rayapps.wordpress.com/164/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=164&subd=rayapps&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.rayapps.com/2010/02/26/ruby-plsql-0-4-2-better-support-for-object-types-and-types-in-packages/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a94fbe334eb75d80da9dd0d3d352df1b?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">elietas</media:title>
		</media:content>
	</item>
		<item>
		<title>ActiveRecord Oracle enhanced adapter version 1.2.4</title>
		<link>http://blog.rayapps.com/2010/02/24/activerecord-oracle-enhanced-adapter-version-1-2-4/</link>
		<comments>http://blog.rayapps.com/2010/02/24/activerecord-oracle-enhanced-adapter-version-1-2-4/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 13:23:08 +0000</pubDate>
		<dc:creator>Raimonds Simanovskis</dc:creator>
				<category><![CDATA[oracle]]></category>
		<category><![CDATA[oracle-enhanced]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://rayapps.wordpress.com/?p=160</guid>
		<description><![CDATA[I have released maintenance version of ActiveRecrod Oracle enhanced adapter with some bug fixes and some new features. This is the last maintenance version for Rails 2, I have already done majority of work to support also Rails 3 in next adapter versions, but that deserves another post when it will be ready :). Detailed [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=160&subd=rayapps&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>I have released maintenance version of ActiveRecrod <a href="http://github.com/rsim/oracle-enhanced">Oracle enhanced adapter</a> with some bug fixes and some new features. This is the last maintenance version for Rails 2, I have already done majority of work to support also Rails 3 in next adapter versions, but that deserves another post when it will be ready :).</p>
<p>Detailed changes can be found in <a href="http://github.com/rsim/oracle-enhanced/blob/master/History.txt">change history file</a> and commit log, here I will point out the main changes.</p>
<h3>Schema and structure dump</h3>
<p>There are several improvements in schema (<strong>rake db:schema:dump</strong>) and structure dump (<strong>rake db:structure:dump</strong>) tasks. Now structure dump is improved to contain all schema objects in SQL statements format.</p>
<p>Also <strong>db:test:purge</strong> rake task (which is run before recreating test schema when running rake test or rake spec) is changed that it will delete all schema objects from test schema &#8211; including also views, packages, procedures and functions which are not recreated from schema.rb. So if you need to have additional database objects in your schema besides tables, indexes, sequences and synonyms (which are dumped in schema.rb) then you need to recreate them after standard rake task db:schema:load is run. Here is example how to execute any additional tasks after db:schema:load (include this in some .rake file in lib/tasks directory):</p>
<pre class="brush: ruby; light: true;">
namespace :db do
  namespace :schema do
    task :load do
      Rake::Task[&quot;db:schema:create_other_objects&quot;].invoke
    end
    task :create_other_objects do
      # include code here which creates necessary views, packages etc.
    end
  end
end
</pre>
<h3>Additional options for schema definition methods</h3>
<p>You can pass <strong>:temporary =&gt; true</strong> option for <strong>create_table</strong> method to create temporary tables.</p>
<p>You can use <strong>:tablespace =&gt; &#8220;tablespace name&#8221;</strong> option for <strong>add_index</strong> method to create index in non-default Oracle tablespace that is specified for user (e.g. if it is requested by your DBA for performance reasons). You can also define function based indexes using add_index and they will be correctly dumped in schema.rb.</p>
<h3>Savepoints and nested ActiveRecord transactions</h3>
<p>oracle_enhanced adapter now supports <a href="http://weblog.rubyonrails.org/2009/1/16/this-week-in-edge-rails">ActiveRecord nested transactions</a> using database savepoints.</p>
<h3>ruby-oci8 version</h3>
<p>As I am using and testing oracle_enhanced adapter just with <strong>ruby-oci8 2.0.3</strong> then I have made this as precondition (if you use MRI 1.8 or 1.9). So if you haven&#8217;t yet upgraded to latest ruby-oci8 version then please do so before upgrading to oracle_enhanced 1.2.4.</p>
<h3>JNDI connection support</h3>
<p>If you are using oracle_enhanced with JRuby then now you can also use JNDI database connections &#8211; please see this <a href="http://github.com/rsim/oracle-enhanced/issues#issue/6">issue with comments</a> to see some examples.</p>
<h3>Install</h3>
<p>As always you can install Oracle enhanced adapter on any Ruby platform (Ruby 1.8.6 / 1.8.7 or Ruby 1.9.1 or JRuby) with</p>
<pre class="brush: bash; light: true;">
gem install activerecord-oracle_enhanced-adapter
</pre>
<p>If you have any questions please use <a href="http://groups.google.com/group/oracle-enhanced">discussion group</a> or post comments here.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rayapps.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rayapps.wordpress.com/160/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rayapps.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rayapps.wordpress.com/160/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rayapps.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rayapps.wordpress.com/160/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rayapps.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rayapps.wordpress.com/160/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rayapps.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rayapps.wordpress.com/160/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=160&subd=rayapps&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.rayapps.com/2010/02/24/activerecord-oracle-enhanced-adapter-version-1-2-4/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a94fbe334eb75d80da9dd0d3d352df1b?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">elietas</media:title>
		</media:content>
	</item>
		<item>
		<title>Screencasts of Oracle PL/SQL unit testing with Ruby</title>
		<link>http://blog.rayapps.com/2010/01/06/screencasts-of-oracle-plsql-unit-testing-with-ruby/</link>
		<comments>http://blog.rayapps.com/2010/01/06/screencasts-of-oracle-plsql-unit-testing-with-ruby/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 14:01:45 +0000</pubDate>
		<dc:creator>Raimonds Simanovskis</dc:creator>
				<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[screencast]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://rayapps.wordpress.com/?p=135</guid>
		<description><![CDATA[In my previous post I already described how to do Oracle PL/SQL unit testing with Ruby. I now have named it as ruby-plsql-spec unit testing framework. But probably you didn&#8217;t want to read such long text or maybe it seemed for you too difficult to try it out therefore I prepared two screencasts to show [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=135&subd=rayapps&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>In my previous post I already described how to do <a href="http://blog.rayapps.com/2009/11/27/oracle-plsql-unit-testing-with-ruby/">Oracle PL/SQL unit testing with Ruby</a>. I now have named it as <a href="http://github.com/rsim/ruby-plsql-spec">ruby-plsql-spec</a> unit testing framework. But probably you didn&#8217;t want to read such long text or maybe it seemed for you too difficult to try it out therefore I prepared two screencasts to show how easy and fun it is :)</p>
<h3>Testing simple function</h3>
<p>The first example is based on classic <a href="http://utplsql.sourceforge.net/Doc/fourstep.html#step2">BETWNSTR function example from utPLSQL tutorial</a>.</p>
<div style="text-align:left;"><a href="http://ruby.lv/files/betwnstr.mov" title="Click to play..."><img src="http://rayapps.files.wordpress.com/2010/01/betwnstr.png?w=400&#038;h=300" alt="betwnstr.png" border="0" width="400" height="300" /></a><br />
<a href="http://ruby.lv/files/betwnstr.mov">Load screencast in QuickTime format (4.7 MB).</a></div>
<h3>Testing procedure that changes tables</h3>
<p>Second example is based on <a href="http://www.quest.com/code-tester-for-oracle/product-demo/chap02.htm">Quest Code Tester for Oracle testing tables demo screencast</a>. So you can see both unit testing frameworks in action and can compare which you like better :)</p>
<div style="text-align:left;"><a href="http://ruby.lv/files/rooms.mov" title="Click to play..."><img src="http://rayapps.files.wordpress.com/2010/01/rooms.png?w=400&#038;h=300" alt="rooms.png" border="0" width="400" height="300" /></a><br />
<a href="http://ruby.lv/files/rooms.mov">Load screencast in QuickTime format (8.1 MB).</a></div>
<h3>Test driven development</h3>
<p>In both these screencasts I demonstrated how to do <a href="http://en.wikipedia.org/wiki/Test-driven_development">test driven development</a> of PL/SQL</p>
<ul>
<li>Write little test of indended functionality before writing code.</li>
<li>Write implementation of new functionality until this test passes and verify that all existing tests pass as well.</li>
<li>Refactor implementation when needed and verify that all tests still pass.</li>
</ul>
<p>From my experience TDD style of development can improve design and testability of code and also make you think before coding what you actually want to implement. But existing visual PL/SQL testing tools (Quest Code Tester, SQL Developer 2.1) do not quite support TDD style of development, they expect that there is already existing code that should be tested. Therefore this is one more ruby-plsql-spec advantage if you would like to do TDD style development in PL/SQL.</p>
<h3>More information</h3>
<p>Examples shown in screencasts are available in <a href="http://github.com/rsim/ruby-plsql-spec">ruby-plsql-spec</a> GitHub repository. And if you want to see more examples how to use ruby-plsql library for PL/SQL unit testing then you can take a look at <a href="http://github.com/rsim/ruby-plsql/blob/master/spec/plsql/procedure_spec.rb">ruby-plsql own RSpec tests</a> or read <a href="http://blog.rayapps.com/category/plsql/">previous posts about ruby-plsql</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rayapps.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rayapps.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rayapps.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rayapps.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rayapps.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rayapps.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rayapps.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rayapps.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rayapps.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rayapps.wordpress.com/135/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=135&subd=rayapps&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.rayapps.com/2010/01/06/screencasts-of-oracle-plsql-unit-testing-with-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://ruby.lv/files/betwnstr.mov" length="4723477" type="video/quicktime" />
<enclosure url="http://ruby.lv/files/rooms.mov" length="8070248" type="video/quicktime" />
	
		<media:content url="http://0.gravatar.com/avatar/a94fbe334eb75d80da9dd0d3d352df1b?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">elietas</media:title>
		</media:content>

		<media:content url="http://rayapps.files.wordpress.com/2010/01/betwnstr.png" medium="image">
			<media:title type="html">betwnstr.png</media:title>
		</media:content>

		<media:content url="http://rayapps.files.wordpress.com/2010/01/rooms.png" medium="image">
			<media:title type="html">rooms.png</media:title>
		</media:content>
	</item>
		<item>
		<title>ruby-plsql 0.4.1 &#8211; support for package variables, views, dbms_output and more</title>
		<link>http://blog.rayapps.com/2010/01/04/ruby-plsql-0-4-1-support-for-package-variables-views-dbms_output-and-more/</link>
		<comments>http://blog.rayapps.com/2010/01/04/ruby-plsql-0-4-1-support-for-package-variables-views-dbms_output-and-more/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 21:40:10 +0000</pubDate>
		<dc:creator>Raimonds Simanovskis</dc:creator>
				<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://rayapps.wordpress.com/?p=131</guid>
		<description><![CDATA[Based on feedback from using ruby-plsql for PL/SQL unit testing I have release new version 0.4.1 with several new features. You can read about initial versions of ruby-plsql in previous blog posts. Package variables When you call methods on &#8220;plsql&#8221; Ruby object then ruby-plsql uses all_procedures and all_arguments data dictionary views to search for procedures [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=131&subd=rayapps&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>Based on feedback from using <a href="http://github.com/rsim/ruby-plsql">ruby-plsql</a> for <a href="http://blog.rayapps.com/2009/11/27/oracle-plsql-unit-testing-with-ruby/">PL/SQL unit testing</a> I have release new version 0.4.1 with several new features. You can read about initial versions of ruby-plsql in <a href="http://blog.rayapps.com/category/plsql/">previous blog posts</a>.</p>
<h3>Package variables</h3>
<p>When you call methods on &#8220;plsql&#8221; Ruby object then ruby-plsql uses all_procedures and all_arguments data dictionary views to search for procedures and their argument metadata to construct corresponding PL/SQL block for execution. Unfortunately there are no corresponding data dictionary views for package variables (sometimes called &#8220;global variables&#8221;) that are defined in package specifications. Therefore there was no support for package variables in initial ruby-plsql versions.</p>
<p>But as there is quite frequent need in PL/SQL tests to set and get package variable values then I created the following solution for accessing package variables. I assume that typically package variables are defined in one line in package specifications and I scan PL/SQL package specification source in all_source data dictionary view for potential package variable definitions.</p>
<p>As a result if you have the following example of package specification:</p>
<pre class="brush: sql; light: true;">
CREATE OR REPLACE PACKAGE test_package IS
  varchar2_variable VARCHAR2(50);
  number_variable NUMBER(15,2);
  string_constant CONSTANT  VARCHAR2(10) := 'constant';
  integer_constant CONSTANT INTEGER := 1;
END;
</pre>
<p>then you can access these package variables in the same way as procedures:</p>
<pre class="brush: ruby; light: true;">
plsql.test_package.varchar2_variable = 'test'
plsql.test_package.number_variable = 123
plsql.test_package.varchar2_variable # =&gt; 'test'
plsql.test_package.number_variable # =&gt; 123
plsql.test_package.string_constant # =&gt; 'constant'
plsql.test_package.integer_constant # =&gt; 1
</pre>
<p>Other basic data types as well as %ROWTYPE, %TYPE and schema object types are also supported for package variables. Only custom types defined in package specification are not supported (they are not supported for procedure parameters as well). As there are no data dictionary views for types defined in package specifications I don&#8217;t feel very enthusiastic about parsing package sources from all_source to get information about types defined inside packages :)</p>
<h3>Views</h3>
<p>In <a href="http://blog.rayapps.com/2009/11/25/more-oracle-data-types-supported-by-ruby-plsql-gem">previous post</a> I described how to use ruby-plsql to perform basic table operations. Now these operations can be performed also with views:</p>
<pre class="brush: ruby; light: true;">
plsql.view_name.insert
plsql.view_name.first
plsql.view_name.all
plsql.view_name.count
plsql.view_name.update
plsql.view_name.delete
</pre>
<h3>insert_values method</h3>
<p>Additional insert_values method is added for tables and views which can be helpful in PL/SQL tests for test data preparation. You can specify with more compact syntax which data you would like to insert into table or view:</p>
<pre class="brush: ruby; light: true;">
plsql.employees.insert_values [:employee_id, :first_name, :last_name],
    [1, 'First', 'Last'],
    [2, 'Second', 'Last']

# =&gt; INSERT INTO employees (employee_id, first_name, last_name) VALUES (1, 'First', 'Last')
# =&gt; INSERT INTO employees (employee_id, first_name, last_name) VALUES (2, 'Second', 'Last')
</pre>
<h3>DBMS_OUTPUT logging</h3>
<p>If you use DBMS_OUTPUT.PUT_LINE in your PL/SQL procedures to log some debug messages then you can use plsql.dbms_output_stream= method to set where these messages should be displayed. Use the following to display DBMS_OUTPUT messages in standard output:</p>
<pre class="brush: ruby; light: true;">
plsql.dbms_output_stream = STDOUT
</pre>
<p>Or write DBMS_OUTPUT messages to file:</p>
<pre class="brush: ruby; light: true;">
plsql.dbms_output_stream = File.new('debug.log', 'w')
</pre>
<h3>STANDARD package procedures</h3>
<p>Procedures from SYS.STANDARD package can be called without sys.standard prefix, e.g.:</p>
<pre class="brush: ruby; light: true;">
plsql.sysdate
plsql.substr('abcde',2,2)
</pre>
<h3>Other improvements</h3>
<p>See <a href="http://github.com/rsim/ruby-plsql/blob/master/History.txt">History.txt</a> file for other new features and improvements and see RSpec tests in spec directory for more usage examples.</p>
<p>And also this version of ruby-plsql requires ruby-oci8 gem latest version 2.0.3 (if you use MRI / standard Ruby interpreter 1.8.6, 1.8.7 or 1.9.1) so please upgrade it as well if you do not have it. But as previously you can use ruby-plsql with JRuby and Oracle JDBC driver as well.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rayapps.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rayapps.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rayapps.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rayapps.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rayapps.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rayapps.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rayapps.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rayapps.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rayapps.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rayapps.wordpress.com/131/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=131&subd=rayapps&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.rayapps.com/2010/01/04/ruby-plsql-0-4-1-support-for-package-variables-views-dbms_output-and-more/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a94fbe334eb75d80da9dd0d3d352df1b?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">elietas</media:title>
		</media:content>
	</item>
		<item>
		<title>Oracle PL/SQL unit testing with Ruby</title>
		<link>http://blog.rayapps.com/2009/11/27/oracle-plsql-unit-testing-with-ruby/</link>
		<comments>http://blog.rayapps.com/2009/11/27/oracle-plsql-unit-testing-with-ruby/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 12:18:39 +0000</pubDate>
		<dc:creator>Raimonds Simanovskis</dc:creator>
				<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://rayapps.wordpress.com/?p=124</guid>
		<description><![CDATA[Current PL/SQL unit testing options Unit testing and TDD (test driven development) practices are nowadays one of the key software development practices. It is especially important if you are doing agile software development in small iterations where you need to automate unit testing as much as possible, as you cannot do manual regression testing of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=124&subd=rayapps&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<h3>Current PL/SQL unit testing options</h3>
<p>Unit testing and TDD (test driven development) practices are nowadays one of the key software development practices. It is especially important if you are doing agile software development in small iterations where you need to automate unit testing as much as possible, as you cannot do manual regression testing of all existing and new functionality at the end of each iteration.</p>
<p>In some languages (like Java, Ruby, Python, C# etc.) there is quite good tools and frameworks support for unit testing and as a result there is quite high testing culture among top developers in these communities. But unfortunately in PL/SQL community so far automated unit testing is not used very often. During recent Oracle OpenWorld conference in presentations about unit testing when it was asked who is doing automated unit testing then only few hands were raised.</p>
<p>Why is it so? And what are current options for doing automated PL/SQL unit testing?</p>
<p>The first unit testing framework for PL/SQL was <a href="http://utplsql.sourceforge.net/">utPLSQL</a> which was created by <a href="http://www.toadworld.com/sf">Steven Feuerstein</a> and based on API defined by many other xUnit style frameworks (like e.g. JUnit). But the issue with this approach was that PL/SQL syntax for tests was quite verbose and tests were not very readable (see <a href="http://utplsql.cvs.sourceforge.net/viewvc/utplsql/examples/ut_betwnstr.pkb?view=markup">example</a>). As a result Steven stopped developing further utPLSQL and currently there are no other active maintainers of this project. There are some other alternative frameworks which tried to simplify writing tests in PL/SQL (OUnit, pl/unit, PLUTO etc.) but none of them are very actively used and maintained by PL/SQL community.</p>
<p>Because of the issues with utPLSQL Steven Feuerstein started development of graphical interface tool for PL/SQL unit testing which is now <a href="http://unittest.inside.quest.com">Quest Code Tester for Oracle</a>. This tool is actively developed and maintained by Quest Software but there are several issues with it:</p>
<ul>
<li>It is a commercial tool and as a result it will not become widely accepted by all PL/SQL developers. There is also a freeware edition of it but the functionality of it is <a href="http://unittest.inside.quest.com/servlet/KbServlet/download/2792-102-5392/Differences%20Between%20Quest%20Code%20Tester%20for%20Oracle%20Freeware%20and%20Commercial.htm">very limited</a>.</li>
<li>It is a graphical tool &#8211; it can help you with quick creation of simple tests but when you will need more complex logic you might get stuck that you cannot do it (or you need to do it again in plain PL/SQL and have the same issues as in utPLSQL).</li>
<li>It stores tests in database repository &#8211; and it means that it might be hard to maintain unit tests in version control system like Subversion or Git.</li>
</ul>
<p>And finally also Oracle started to do something in PL/SQL unit testing area and there is unit testing support in latest <a href="http://www.oracle.com/technology/products/database/sql_developer/index.html">SQL Developer version 2.1</a> which currently still is in early adopter status. SQL Developer has very similar approach to Quest Code Tester &#8211; it is graphical tool which stores tests and test results in repository. So the benefit of SQL Developer over Quest Code Tester is that it is free :) But compared to Quest Code Tester it still has less features (e.g. currently not all complex data types are supported) and still is not released as final version and still has bugs.</p>
<h3>Ruby as testing tool for PL/SQL</h3>
<p>As you probably know I am quite big <a href="http://www.ruby-lang.org/en/">Ruby</a> fan and always exploring new ways how to use Ruby to increase my productivity. And Ruby community has very high testing culture and has many good tools for testing support (I like and use <a href="http://rspec.info/">RSpec</a> testing framework). Therefore some time ago I started to use Ruby and RSpec also for testing PL/SQL code in our projects where we use Ruby on Rails on top of Oracle databases with existing PL/SQL business logic.</p>
<p>I have created <a href="http://github.com/rsim/ruby-plsql">ruby-plsql</a> library which provides very easy API for calling PL/SQL procedures from Ruby and recent ruby-plsql version <a href="http://blog.rayapps.com/2009/11/25/more-oracle-data-types-supported-by-ruby-plsql-gem/">supports majority of PL/SQL data types</a>.</p>
<p>So let&#8217;s start with with simple example how to use Ruby, RSpec and ruby-plsql to create PL/SQL procedure unit test. I will use BETWNSTR procedure example from utPLSQL examples:</p>
<pre class="brush: sql; light: true;">
CREATE OR REPLACE FUNCTION betwnstr (
   string_in   IN   VARCHAR2,
   start_in    IN   INTEGER,
   end_in      IN   INTEGER
)
   RETURN VARCHAR2
IS
   l_start PLS_INTEGER := start_in;
BEGIN
   IF l_start = 0
   THEN
      l_start := 1;
   END IF;
   RETURN (SUBSTR (string_in, l_start, end_in - l_start + 1));
END;
</pre>
<p>I took <a href="http://utplsql.cvs.sourceforge.net/viewvc/utplsql/examples/ut_betwnstr_gen.pkg?view=markup">example tests from utPLSQL</a> and wrote them in Ruby and RSpec:</p>
<pre class="brush: ruby; light: true;">
describe &quot;Between string&quot; do
  it &quot;should be correct in normal case&quot; do
    plsql.betwnstr('abcdefg', 2, 5).should == 'bcde'
  end
  it &quot;should be correct with zero start value&quot; do
    plsql.betwnstr('abcdefg', 0, 5).should == 'abcde'
  end
  it &quot;should be correct with way big end value&quot; do
    plsql.betwnstr('abcdefg', 5, 500).should == 'efg'
  end
  it &quot;should be correct with NULL string&quot; do
    plsql.betwnstr(nil, 5, 500).should be_nil
  end
end
</pre>
<p>As you can see the tests are much shorter than in utPLSQL and are much more readable (also more readable than <a href="http://utplsql.cvs.sourceforge.net/viewvc/utplsql/examples/bewtnstr.utc?view=markup">utPLSQL template</a> which can be used to generate utPLSQL tests). And also you can create these tests faster than using GUI tools like Quest Code Tester or SQL Developer.</p>
<h3>More complex example</h3>
<p>Second more complex example I took from <a href="http://www.oracle.com/technology/obe/11gr2_db_prod/appdev/sqldev/sqldev_unit_test/sqldev_unit_test_otn.htm">SQL Developer unit testing tutorial</a>. We will create tests for PL/SQL procedure AWARD_BONUS:</p>
<pre class="brush: sql; light: true;">
CREATE OR REPLACE
 PROCEDURE award_bonus (
  emp_id NUMBER, sales_amt NUMBER) AS
  commission    REAL;
  comm_missing  EXCEPTION;
BEGIN
  SELECT commission_pct INTO commission
    FROM employees2
      WHERE employee_id = emp_id;
  IF commission IS NULL THEN
    RAISE comm_missing;
  ELSE
    UPDATE employees2
      SET salary = NVL(salary,0) + sales_amt*commission
        WHERE employee_id = emp_id;
  END IF;
END award_bonus;
</pre>
<p>I didn&#8217;t quite like the testing approach in SQL Developer unit testing tutorial &#8211; it was assuming that there is already specific data in employees2 table and was testing procedure using specific primary key values. As a result tests are not very readable as you cannot see all input data in the test case and tests could easily broke if initial data in table are different.</p>
<p>Therefore I created tests in Ruby using better approach that each test creates all necessary data that are needed for it and at the end of test there are no side effects which can influence other tests:</p>
<pre class="brush: ruby; light: true;">
describe &quot;Award bonus&quot; do
  include CustomerFactory

  [ [1000,  1234.55,  0.10,   1123.46],
    [nil,   1234.56,  0.10,   123.46],
    [1000,  1234.54,  0.10,   1123.45]
  ].each do |salary, sales_amt, commission_pct, result|
    it &quot;should calculate base salary #{salary.inspect} + sales amount #{sales_amt} * commission percentage #{commission_pct} = salary #{result.inspect}&quot; do
      employee = create_employee(
        :commission_pct =&gt; commission_pct,
        :salary =&gt; salary
      )
      plsql.award_bonus(employee[:employee_id], sales_amt)
      get_employee(employee[:employee_id])[:salary].should == result
    end
  end
end
</pre>
<p>I am generating three different tests with three different sets of input values. When you run these tests you see result:</p>
<pre class="brush: plain; light: true;">
Award bonus
- should calculate base salary 1000 + sales amount 1234.55 * commission percentage 0.1 = salary 1123.46
- should calculate base salary NULL + sales amount 1234.56 * commission percentage 0.1 = salary 123.46
- should calculate base salary 1000 + sales amount 1234.54 * commission percentage 0.1 = salary 1123.45
</pre>
<p>In addition I am using factory pattern (create_customer method) for test data creation. When using factory pattern you create test data creation method which will create valid new record with default field values. If in your test you need some specific non-default values then you can pass just these values as parameters to factory method. Factory pattern also helps in the maintenance of tests. For example, if new mandatory columns will be added to employees table then it will be necessary to add new fields with default values in factory methods and nothing should be changed in individual tests.</p>
<p>Here is example of employee factory implementation:</p>
<pre class="brush: ruby; light: true;">
module EmployeeFactory
  # Creates new employee with valid field values.
  # Pass in parameters only field values that you want to override.
  def create_employee(params)
    employee = {
      :employee_id =&gt; plsql.employees2_seq.nextval,
      :last_name =&gt; 'Last',
      :email =&gt; 'last@example.com',
      :hire_date =&gt; Date.today,
      :job_id =&gt; plsql.jobs.first[:job_id],
      :commission_pct =&gt; nil,
      :salary =&gt; nil
    }.merge(params)
    plsql.employees2.insert employee
    get_employee employee[:employee_id]
  end

  # Select employee by primary key
  def get_employee(employee_id)
    plsql.employees2.first :employee_id =&gt; employee_id
  end
end
</pre>
<p>And here is additional test for testing if procedure will raise exception if one input value is missing:</p>
<pre class="brush: ruby; light: true;">
  it &quot;should raise ORA-06510 exception if commission percentage is missing&quot; do
    salary, sales_amt, commission_pct = 1000,  1234.55,  nil
    employee = create_employee(
      :commission_pct =&gt; commission_pct,
      :salary =&gt; salary
    )
    lambda do
      plsql.award_bonus(employee[:employee_id], sales_amt)
    end.should raise_error(/ORA-06510/)
  end
</pre>
<h3>How to use it</h3>
<p>I hope that if you are looking for PL/SQL unit testing tool then you will try this out :) You can get examples from this article together with necessary setup code and installation instructions at  <a href="http://github.com/rsim/ruby-plsql-spec">http://github.com/rsim/ruby-plsql-spec</a>.</p>
<p>If you have any feedback or questions or feature suggestions then please comment.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rayapps.wordpress.com/124/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rayapps.wordpress.com/124/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rayapps.wordpress.com/124/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rayapps.wordpress.com/124/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rayapps.wordpress.com/124/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rayapps.wordpress.com/124/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rayapps.wordpress.com/124/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rayapps.wordpress.com/124/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rayapps.wordpress.com/124/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rayapps.wordpress.com/124/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=124&subd=rayapps&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.rayapps.com/2009/11/27/oracle-plsql-unit-testing-with-ruby/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a94fbe334eb75d80da9dd0d3d352df1b?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">elietas</media:title>
		</media:content>
	</item>
		<item>
		<title>More Oracle data types supported by ruby-plsql gem</title>
		<link>http://blog.rayapps.com/2009/11/25/more-oracle-data-types-supported-by-ruby-plsql-gem/</link>
		<comments>http://blog.rayapps.com/2009/11/25/more-oracle-data-types-supported-by-ruby-plsql-gem/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 14:34:33 +0000</pubDate>
		<dc:creator>Raimonds Simanovskis</dc:creator>
				<category><![CDATA[jruby]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://rayapps.wordpress.com/?p=122</guid>
		<description><![CDATA[I have just released ruby-plsql gem version 0.4.0 which provides many new features. You can read about initial versions of ruby-plsql in previous blog posts. Oracle complex data type support Initial versions of ruby-plsql supported just simple Oracle types like NUMBER, VARCHAR2, DATE, TIMESTAMP, CLOB, BLOB as PL/SQL procedure parameters. Now support for many more [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=122&subd=rayapps&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>I have just released <a href="http://github.com/rsim/ruby-plsql">ruby-plsql</a> gem version 0.4.0 which provides many new features. You can read about initial versions of ruby-plsql in <a href="http://blog.rayapps.com/category/plsql/">previous blog posts</a>.</p>
<h3>Oracle complex data type support</h3>
<p>Initial versions of ruby-plsql supported just simple Oracle types like NUMBER, VARCHAR2, DATE, TIMESTAMP, CLOB, BLOB as PL/SQL procedure parameters. Now support for many more complex data types is added. See examples below how to call PL/SQL procedures with these complex data types.</p>
<h4>PL/SQL Record</h4>
<p>Let&#8217;s assume you have PL/SQL procedure with PL/SQL record type parameter (which most typically will be in table%ROWTYPE format):</p>
<pre>
CREATE TABLE test_employees (
          employee_id   NUMBER(15),
          first_name    VARCHAR2(50),
          last_name     VARCHAR2(50),
          hire_date     DATE
        );
CREATE OR REPLACE FUNCTION test_full_name (p_employee test_employees%ROWTYPE)
RETURN VARCHAR2 IS
BEGIN
  RETURN p_employee.first_name || ' ' || p_employee.last_name;
END;
</pre>
<p>Then you can create Ruby Hash with record field values (specifying field names as Symbols), e.g.:</p>
<pre>
p_employee = {
  :employee_id =&gt; 1,
  :first_name =&gt; 'First',
  :last_name =&gt; 'Last',
  :hire_date =&gt; Time.local(2000,01,31)
}
</pre>
<p>and pass this Hash as a parameter which will be translated to PL/SQL record parameter by ruby-plsql:</p>
<pre>
plsql.test_full_name(p_employee) #=&gt; "First Last"
# or
plsql.test_full_name(:p_employee =&gt; p_employee) #=&gt; "First Last"
</pre>
<p>In the same way you can get PL/SQL function return values or output parameter values as Hash values.</p>
<h4>Object type</h4>
<p>In similar way also object type parameters can be passed as Hash values. In this case also nested objects or nested collections of objects are supported:</p>
<pre>
CREATE OR REPLACE TYPE t_address AS OBJECT (
  street    VARCHAR2(50),
  city      VARCHAR2(50),
  country   VARCHAR2(50)
);
CREATE OR REPLACE TYPE t_phone AS OBJECT (
  type            VARCHAR2(10),
  phone_number    VARCHAR2(50)
);
CREATE OR REPLACE TYPE t_phones AS TABLE OF T_PHONE;
CREATE OR REPLACE TYPE t_employee AS OBJECT (
  employee_id   NUMBER(15),
  first_name    VARCHAR2(50),
  last_name     VARCHAR2(50),
  hire_date     DATE,
  address       t_address,
  phones        t_phones
);
CREATE OR REPLACE FUNCTION test_full_name (p_employee t_employee)
  RETURN VARCHAR2
IS
BEGIN
  RETURN p_employee.first_name || ' ' || p_employee.last_name;
END;
</pre>
<p>and from Ruby side you can call this PL/SQL function as:</p>
<pre>
p_employee = {
  :employee_id =&gt; 1,
  :first_name =&gt; 'First',
  :last_name =&gt; 'Last',
  :hire_date =&gt; Time.local(2000,01,31),
  :address =&gt; {:street =&gt; 'Main street 1', :city =&gt; 'Riga', :country =&gt; 'Latvia'},
  :phones =&gt; [{:type =&gt; 'mobile', :phone_number =&gt; '123456'}, {:type =&gt; 'home', :phone_number =&gt; '654321'}]
}
plsql.test_full_name(p_employee) #=&gt; "First Last"
# or
plsql.test_full_name(:p_employee =&gt; p_employee) #=&gt; "First Last"
</pre>
<p>And also object type return values and output parameters will be returned as Ruby Hash values (with nested Hashes or Arrays if necessary).</p>
<p>There is one limitation that these object types should be defined as database types and not just inside PL/SQL package definition. Unfortunately you cannot access type definitions inside packages from OCI or JDBC drivers and as a result cannot call such procedures from outside of PL/SQL.</p>
<h4>TABLE and VARRAY collections</h4>
<p>TABLE and VARRAY collection parameters can be passed as Array values:</p>
<pre>
CREATE OR REPLACE TYPE t_numbers AS TABLE OF NUMBER(15);
CREATE OR REPLACE FUNCTION test_sum (p_numbers IN t_numbers)
  RETURN NUMBER
IS
  l_sum   NUMBER(15) := 0;
BEGIN
  IF p_numbers.COUNT &gt; 0 THEN
    FOR i IN p_numbers.FIRST..p_numbers.LAST LOOP
      IF p_numbers.EXISTS(i) THEN
        l_sum := l_sum + p_numbers(i);
      END IF;
    END LOOP;
    RETURN l_sum;
  ELSE
    RETURN NULL;
  END IF;
END;
</pre>
<p>And from Ruby side:</p>
<pre>
plsql.test_sum([1,2,3,4]) #=&gt; 10
</pre>
<h4>CURSOR</h4>
<p>You can get also cursor return values from PL/SQL procedures:</p>
<pre>
CREATE OR REPLACE FUNCTION test_cursor
  RETURN SYS_REFCURSOR
IS
  l_cursor  SYS_REFCURSOR;
BEGIN
  OPEN l_cursor FOR
  SELECT * FROM test_employees ORDER BY employee_id;
  RETURN l_cursor;
END;
</pre>
<p>can be called from Ruby in the following way:</p>
<pre>
plsql.test_cursor do |cursor|
  cursor.fetch #=&gt; first row from test_employees will be returned
end
</pre>
<p>It is important to pass block parameter in this case and do something with returned cursor within this block as after ruby-plsql finishes PL/SQL procedure call it will close all open cursors and therefore it will not be possible to do anything with returned cursor outside this block.</p>
<p>It is also possible to use returned cursor as input parameter for another PL/SQL procedure:</p>
<pre>
CREATE OR REPLACE FUNCTION test_cursor_fetch(p_cursor SYS_REFCURSOR)
  RETURN test_employees%ROWTYPE
IS
  l_record  test_employees%ROWTYPE;
BEGIN
  FETCH p_cursor INTO l_record;
  RETURN l_record;
END;
</pre>
<pre>
plsql.test_cursor do |cursor|
  plsql.test_cursor_fetch(cursor) #=&gt; first record as Hash
end
</pre>
<p><strong>Note</strong>: you can pass cursors as PL/SQL procedure input parameter just when using ruby-plsql on MRI 1.8/1.9 with ruby-oci8, unfortunately I have not found a way how to pass cursor as input parameter when using JRuby and JDBC.</p>
<h4>BOOLEAN</h4>
<p>And finally you can use also PL/SQL BOOLEAN type &#8211; it is quite tricky data type as it is supported just by PL/SQL but not supported as data type in Oracle tables. But now you can also use it with ruby-plsql:</p>
<pre>
CREATE OR REPLACE FUNCTION test_boolean
  ( p_boolean BOOLEAN )
  RETURN BOOLEAN
IS
BEGIN
  RETURN p_boolean;
END;
</pre>
<pre>
plsql.test_boolean(true) #=&gt; true
</pre>
<p>You can find more PL/SQL procedure call usage examples in <a href="http://github.com/rsim/ruby-plsql/blob/master/spec/plsql/procedure_spec.rb">ruby-plsql RSpec tests</a>.</p>
<h3>Table and sequence operations</h3>
<p>I have been using and promoting to others ruby-plsql as PL/SQL procedure unit testing tool. As current PL/SQL unit testing tools are not so advanced and easy to use as Ruby unit testing tools then I like better to use Ruby testing tools (like RSpec) together with ruby-plsql to write short and easy to understand PL/SQL unit tests.</p>
<p>In unit tests in setup and teardown methods you typically need some easy way how to create some sample data in necessary tables as well as to validate resulting data in tables after test execution.</p>
<p>If you are Ruby on Rails developer then you probably will use ActiveRecord (or DataMapper) for manipulation of table data. But if Ruby is used just for unit tests then probably ActiveRecord would be too complicated for this task.</p>
<p>Therefore I added some basic table operations to ruby-plsql which might be useful e.g. in unit tests. Some syntax ideas for these table operations are coming from <a href="http://github.com/jeremyevans/sequel/">Sequel</a> Ruby library.</p>
<h4>INSERT</h4>
<pre>
# insert one record
employee = { :employee_id =&gt; 1, :first_name =&gt; 'First', :last_name =&gt; 'Last', :hire_date =&gt; Time.local(2000,01,31) }
plsql.employees.insert employee # INSERT INTO employees VALUES (1, 'First', 'Last', ...)
</pre>
<pre>
# insert many records
employees = [employee1, employee2, ... ]  # array of many Hashes
plsql.employees.insert employees
</pre>
<p>If primary key values should be selected from sequence then you can get next sequence values with</p>
<pre>
plsql.employees_seq.nextval # SELECT employees_seq.NEXTVAL FROM dual
plsql.employees_seq.currval # SELECT employees_seq.CURRVAL FROM dual
</pre>
<h4>SELECT</h4>
<pre>
# select one record
plsql.employees.first # SELECT * FROM employees
                      # fetch first row =&gt; {:employee_id =&gt; ..., :first_name =&gt; '...', ...}
plsql.employees.first(:employee_id =&gt; 1)  # SELECT * FROM employees WHERE employee_id = 1
plsql.employees.first("WHERE employee_id = 1")
plsql.employees.first("WHERE employee_id = :employee_id", 1)
# select many records
plsql.employees.all                       # =&gt; [{...}, {...}, ...]
plsql.employees.all(:order_by =&gt; :employee_id)
plsql.employees.all("WHERE employee_id &gt; :employee_id", 5)
</pre>
<pre>
# count records
plsql.employees.count                     # SELECT COUNT(*) FROM employees
plsql.employees.count("WHERE employee_id &gt; :employee_id", 5)
</pre>
<h4>UPDATE</h4>
<pre>
# update records
plsql.employees.update(:first_name =&gt; 'Second', :where =&gt; {:employee_id =&gt; 1})
                      # UPDATE employees SET first_name = 'Second' WHERE employee_id = 1
</pre>
<h4>DELETE</h4>
<pre>
# delete records
plsql.employees.delete(:employee_id =&gt; 1) # DELETE FROM employees WHERE employee_id = 1
</pre>
<h4>Other SQL statements</h4>
<p>Any other SELECT statement can be executed with</p>
<pre>
plsql.select :first, "SELECT ..."
# or
plsql.select :all, "SELECT ..."
</pre>
<p>or any other non-SELECT SQL statement can be executed with</p>
<pre>
plsql.execute "..."
</pre>
<p>And also COMMIT or ROLLBACK could be executed simply with</p>
<pre>
plsql.commit
plsql.rollback
</pre>
<p>I plan to write a separate blog post about how I recommend to create PL/SQL unit tests using Ruby and ruby-plsql and RSpec.</p>
<h3>Install</h3>
<p>As always you can install latest version of ruby-plsql with</p>
<pre>
gem install ruby-plsql
</pre>
<p>Latest gem version is just on <a href="http://gemcutter.org/gems/ruby-plsql">Gemcutter</a> but now it should be available as default gem source for all Ruby installations.</p>
<p>And as always ruby-plsql is supported both on</p>
<ul>
<li>Ruby 1.8.6/1.8.7 or Ruby 1.9.1 with ruby-oci8 gem version 2.0.3 or later (some specific issues with complex data types will be fixed in later versions of ruby-oci8)</li>
<li>JRuby 1.3/1.4 with Oracle JDBC driver (testing mainly with ojdbc14.jar but also ojdbc5.jar or ojdbc6.jar should be fine)</li>
</ul>
<p>Please try it out and tell me if there are any issues with some particular data types or if there are still some unsupported PL/SQL data types that you would like to be supported in ruby-plsql. And also I encourage you to try ruby-plsql out for PL/SQL unit testing if you had no PL/SQL unit tests previously :)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rayapps.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rayapps.wordpress.com/122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rayapps.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rayapps.wordpress.com/122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rayapps.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rayapps.wordpress.com/122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rayapps.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rayapps.wordpress.com/122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rayapps.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rayapps.wordpress.com/122/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=122&subd=rayapps&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.rayapps.com/2009/11/25/more-oracle-data-types-supported-by-ruby-plsql-gem/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a94fbe334eb75d80da9dd0d3d352df1b?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">elietas</media:title>
		</media:content>
	</item>
		<item>
		<title>Notes from Oracle OpenWorld 2009</title>
		<link>http://blog.rayapps.com/2009/10/20/notes-from-oracle-openworld-2009/</link>
		<comments>http://blog.rayapps.com/2009/10/20/notes-from-oracle-openworld-2009/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 10:53:16 +0000</pubDate>
		<dc:creator>Raimonds Simanovskis</dc:creator>
				<category><![CDATA[oracle]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://rayapps.wordpress.com/?p=120</guid>
		<description><![CDATA[People Last week I participated in annual Oracle OpenWorld 2009 conference. There is quite wide coverage of conference in various web sites and blogs therefore I will write just some personal notes that I wanted to highlight. For me the most value was meeting with different interesting people. At first thanks to Justin Kestelyn and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=120&subd=rayapps&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<h3>People</h3>
<p>Last week I participated in annual <a href="http://www.oracle.com/us/openworld/018079.htm">Oracle OpenWorld 2009</a> conference. There is quite wide coverage of conference in various web sites and blogs therefore I will write just some personal notes that I wanted to highlight.</p>
<p>For me the most value was meeting with different interesting people. At first thanks to <a href="http://blogs.oracle.com/otn/">Justin Kestelyn</a> and all <a href="http://www.oracle.com/technology/index.html">OTN</a> team for Oracle community support. Oracle ACE dinner, bloggers meetup, OTN lounge and unconference were great places where to meet and discuss with interesting and active Oracle community members.</p>
<p>It was nice to meet <a href="http://db360.blogspot.com/">Kuassi Mensah</a> and <a href="http://blogs.oracle.com/opal/">Christopher Jones</a> who are supporters of dynamic languages in Oracle and supporters of Ruby in particular. And also had interesting discussions with <a href="http://twitter.com/rmanalan">Rich Manalang</a> &#8211; Ruby guru at Oracle, who is from the <a href="http://theappslab.com/">AppsLab</a> team.</p>
<p>This year there were quite a few Sun people in the conference. Scott McNealy and James Gosling were doing keynotes. And I had interesting discussions with <a href="http://blog.arungupta.me/">Arun Gupta</a> and <a href="http://www.tbray.org/ongoing/">Tim Bray</a>. BTW they have very good coverage of Oracle OpenWorld in their blogs (and also have a fresh look at it as they were for the first time here).</p>
<p>This year I did two <a href="http://wiki.oracle.com/page/Oracle+OpenWorld+Unconference">unconference</a> sessions &#8211; <a href="http://www.slideshare.net/rsim/oracle-adapters-for-ruby-orms">Oracle adapters for Ruby ORMs</a> and <a href="http://www.slideshare.net/rsim/server-installation-and-configuration-with-chef">Server Installation and Configuration with Chef</a>. They were not very many attendees but at least it seemed that those who attended were satisfied with content :) This year Oracle Develop track was located quite far from unconference location and probably this also was a reason why there were not very many attendees (as my sessions were quite developer oriented).</p>
<h3>Technologies</h3>
<p>Here is the list of Oracle products and technologies that I am interested in to spend some time investigating them:</p>
<ul>
<li><strong>Fustion applications.</strong> I expected to hear more about next-generation of new Fusion applications but there was just short demo in the final keynote and a promise that they will be available sometime next year. <a href="http://www.flickr.com/photos/oracleopenworld09/sets/72157622462805751/">User interface</a> of new applications seems much better than for the current Oracle applications as well as current beta-testers are telling that usability is really much better. So I am really looking for trying them out.
</li>
<li><strong>Application Development Framework (ADF).</strong> I am not a big fan of <a href="http://www.oracle.com/technology/products/adf/index.html">ADF</a> drag-and-drop development style (that&#8217;s why I prefer Ruby on Rails :)) but as ADF is the main development platform for Fusion Applications then it will be necessary to use it if we would like to extend or customize Fusion applications. But what I would be really interested in is how to integrate JRuby with ADF &#8211; it would be nice to use ADF Faces UI components to get ADF look and feel, but to use JRuby for model &amp; controller business logic development.
</li>
<li><strong>SQL Developer unit testing.</strong> It was nice to see that finally Oracle has PL/SQL unit testing support in latest version of <a href="http://www.oracle.com/technology/software/products/sql/index21_EA1.html">SQL Developer</a> which hopefully will increase awareness about unit testing among PL/SQL developers. <a href="http://www.toadworld.com/sf">Steven Feuerstein</a> gave very good &#8220;motivational&#8221; talk about unit testing during converence. But I still can&#8217;t decide if SQL Developer repository based unit tests is the best way how to do them. E.g. as all unit tests are stored in database repository you cannot version control them with Subversion or Git (which is the place where we store source of all PL/SQL procedures).<br />
Therefore I plan to make enhancements to my <a href="http://github.com/rsim/ruby-plsql">ruby-plsql</a> gem to support more PL/SQL data types and then it would be possible to write PL/SQL unit tests with Ruby and RSpec which would provide more compact syntax compared to current <a href="http://utplsql.sourceforge.net/">utPLSQL</a> framework. Need to write blog post about it :)
</li>
<li><strong>Oracle Coherence.</strong> Recently I have heard many references to <a href="http://www.oracle.com/technology/products/coherence/index.html">Oracle Coherence</a> in-memory data grid which is often used to achieve high-scalability of web applications. Therefore I am thinking about Ruby client for Coherence and potentially using Coherence as cache solution in Ruby on Rails applications.
</li>
<li><strong>Java in database.</strong> Recently I did some experiments with Java stored procedures in Oracle database &#8211; and the main reason is that it could provide integration of Oracle database with other systems that have Java based API. I already did experiments with creating Oracle client for <a href="http://www.rabbitmq.com/">RabbitMQ</a> messaging system.
</li>
<li><strong>Oracle object types.</strong> Many Oracle products (like Spatial Data option) are using Oracle object types for storing data. Currently these object data types are not supported by Ruby ActiveRecord and DataMapper ORMs. Need to do investigation how they could be supported and how to use Ruby e.g. for accessing spatial data in Oracle database.
</li>
</ul>
<h3>Oracle Magazine&#8217;s Developer of the Year</h3>
<p>And finally during Oracle OpenWorld annual Oracle Magazine Editors&#8217; Choice Awards 2009 were published. And it was pleasant surprise for me that in this year I got <a href="http://www.oracle.com/technology/oramag/oracle/09-nov/o69awards.html#simanovskis">Oracle Magazine&#8217;s Developer of the Year</a> award. Thanks to Oracle people who promoted me and thanks for congratulations that I received :) Here is my picture and profile from the latest Oracle Magazine:</p>
<div style="text-align:center;"><a href="http://rayapps.files.wordpress.com/2009/10/doty.png"><img src="http://rayapps.files.wordpress.com/2009/10/doty_450.png?w=450&#038;h=299" alt="DOTY_450.png" border="0" width="450" height="299" /></a></p>
<p><font size="-2">Photo &copy; Delmi Alvarez / Getty Images</font></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rayapps.wordpress.com/120/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rayapps.wordpress.com/120/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rayapps.wordpress.com/120/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rayapps.wordpress.com/120/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rayapps.wordpress.com/120/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rayapps.wordpress.com/120/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rayapps.wordpress.com/120/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rayapps.wordpress.com/120/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rayapps.wordpress.com/120/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rayapps.wordpress.com/120/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=120&subd=rayapps&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.rayapps.com/2009/10/20/notes-from-oracle-openworld-2009/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a94fbe334eb75d80da9dd0d3d352df1b?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">elietas</media:title>
		</media:content>

		<media:content url="http://rayapps.files.wordpress.com/2009/10/doty_450.png" medium="image">
			<media:title type="html">DOTY_450.png</media:title>
		</media:content>
	</item>
		<item>
		<title>New features in ActiveRecord Oracle enhanced adapter version 1.2.2</title>
		<link>http://blog.rayapps.com/2009/09/28/new-features-in-activerecord-oracle-enhanced-adapter-version-1-2-2/</link>
		<comments>http://blog.rayapps.com/2009/09/28/new-features-in-activerecord-oracle-enhanced-adapter-version-1-2-2/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 17:55:34 +0000</pubDate>
		<dc:creator>Raimonds Simanovskis</dc:creator>
				<category><![CDATA[jruby]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[oracle-enhanced]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://rayapps.wordpress.com/?p=116</guid>
		<description><![CDATA[During the last months many new features have been implemented for ActiveRecord Oracle enhanced adapter which are now included in Oracle enhanced adapter version 1.2.2. You can find full list in change history file, here I will tell about the main ones. Documentation Now Oracle enhanced adapter has improved RDoc documentation for all public methods. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=116&subd=rayapps&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>During the last months many new features have been implemented for ActiveRecord <a href="http://github.com/rsim/oracle-enhanced">Oracle enhanced adapter</a> which are now included in Oracle enhanced adapter version 1.2.2. You can find full list in <a href="http://github.com/rsim/oracle-enhanced/blob/master/History.txt">change history file</a>, here I will tell about the main ones.</p>
<h3>Documentation</h3>
<p>Now Oracle enhanced adapter has improved RDoc documentation for all public methods. So you can go to RDoc documentation of installed gem or go and <a href="http://oracle-enhanced.rubyforge.org/rdoc">view published documentation on-line</a>.</p>
<h3>Schema definition</h3>
<p>There are many new features in schema definition methods that you can use in migration files:</p>
<ul>
<li>When you use <strong>add_index</strong> then ActiveRecord is automatically generating index name using format index_table_name_on_column1_and_column2_&#8230; which previously could cause Oracle errors as Oracle identifiers should be up to 30 characters long. Now default index names are <strong>automatically shortened down to 30 or less characters</strong> (of course you can always use also :name option to specify shortened version by yourself).</li>
<li>Now adapter is <strong>ignoring :limit option for :text and :binary columns</strong> (as in Oracle you cannot specify limit for CLOB and BLOB data types). Previously it could cause errors if you tried to migrate Rails application from e.g. MySQL where :text and :binary columns could have :limit in schema definition.</li>
<li>If you define <strong>:string column with :limit option</strong> then it will define <strong>VARCHAR2 column with size in characters and not in bytes</strong> (this makes difference if you use UTF-8 with language where one character might be stored as several bytes). This is expected behavior from ActiveRecord that you define maximum string size in UTF-8 characters.</li>
<li>Now you can use <strong>add_foreign_key</strong> and <strong>remove_foreign_key</strong> to define foreign key constraints in migrations (see <a href="http://oracle-enhanced.rubyforge.org/rdoc/classes/ActiveRecord/ConnectionAdapters/OracleEnhancedSchemaStatementsExt.html#M000010">RDoc documentation for details</a>). Syntax and some implemenatation for foreign key definition was taken from <a href="http://github.com/matthuhiggins/foreigner">foreigner Rails plugin</a> as well as some ideas taken from <a href="http://github.com/eyestreet/active_record_oracle_extensions">active_record_oracle_extensions plugin</a>.</li>
<li><strong>add_foreign_key</strong> definitions will be also <strong>extracted in schema.rb</strong> by <strong>rake db:schema:dump</strong> task. Therefore they will be also present in test database when you will recreate it from schema.rb file.</li>
<li>Foreign keys are also safe for loading of fixtures (in case you are still using them instead of factories :)). <strong>disable_referential_integrity</strong> method is implemented for Oracle enhanced adapter which is called by ActiveRecord before loading fixtures and which disables all currently active foreign key constraints during loading of fixtures.</li>
<li>You can use <strong>add_synonym</strong> and <strong>remove_synonym</strong> to <a href="http://oracle-enhanced.rubyforge.org/rdoc/classes/ActiveRecord/ConnectionAdapters/OracleEnhancedSchemaStatementsExt.html#M000012">define database synonyms</a> to other tables, views or sequences. add_synonym definitions will also be extracted in schema.rb file.</li>
<li>It is possible to create tables with <a href="http://oracle-enhanced.rubyforge.org/rdoc/classes/ActiveRecord/ConnectionAdapters/OracleEnhancedAdapter.html#M000032">primary key trigger</a>. There will be no difference in terms how you would create new records in such table using ActiveRecord but in case you have also need to do direct INSERTs into the table then it will be easier as you can omit primary key from INSERT statement and primary key trigger will populate it automatically from corresponding sequence.</li>
<li>ActiveRecord <strong>schema dumper is patched</strong> to work correctly when default <strong>table prefixes or suffixes</strong> are used &#8211; they are now removed from schema.rb dump to avoid duplicate prefixes and suffixes when recreating schema from schema.rb.</li>
</ul>
<h3>Legacy schema support</h3>
<p>Some features which can support &#8220;weird&#8221; legacy database schemas:</p>
<ul>
<li>If you are using ActiveRecord with legacy schema which have tables with triggers that populate primary key triggers (and not using default Rails and Oracle enhanced adapter conventions) then you can use <strong>set_sequence_name :autogenerated</strong> in class definition to tell adapter to omit primary key value from INSERTs.</li>
<li>You can use ActiveRecord also with <strong>tables that you can access over database link</strong>. To do that you need to define local synonym to remote table (and also remote sequence if you want to insert records as well) and then use local synonym in set_table_name in class definition. Previously adapter could not get remote table columns, now it will get table columns also over database link.<br />
But still you cannot specify remote table (like &#8220;table_name@db_link&#8221;) directly in set_table_name as table_name will be used as column prefix in generated SQL statements where &#8220;@db_link&#8221; will not be valid syntax.<br />
And when you define local synonyms then please use the new add_synonym feature :)</li>
</ul>
<h3>Connection options</h3>
<ul>
<li><strong>cursor_sharing</strong> option default value is changed from &#8220;similar&#8221; to &#8220;<strong>force</strong>&#8221; &#8211; please read <a href="http://groups.google.com/group/oracle-enhanced/browse_thread/thread/90d1bfbbc02397b5">explanation in discussion group post</a> what it is and why the new default value is recommended choice.</li>
<li>When using <strong>JRuby</strong> and JDBC you can set TNS_ADMIN environment variable to tnsnames.ora directory and then use <strong>TNS database alias</strong> in database.yml file (specify just database: option and remove host: option). This might be useful for more complex TNS connection definitions, e.g. connection to load balanced Oracle RAC.</li>
<li>Adapter will not raise error if it cannot locate <strong>ojdbc14.jar</strong> file. So either put it in $JRUBY_HOME/lib or ensure that it will be loaded by application server. Would love to hear feedback from people who are using this adapter with JRuby to find out if this behaves well now :)</li>
</ul>
<h3>Logging</h3>
<ul>
<li>Now you can get <strong>PL/SQL debugging</strong> information into your ActiveRecord log file. Use <strong>dbms_output.put_line</strong> in your PL/SQL procedures and functions (that are called from ActiveRecord models) and in your ActiveRecord model use <strong>connection.enable_dbms_output</strong> and <strong>connection.disable_dbms_output</strong> around your database calls to get dbms_output logging information into ActiveRecord log file. But please use it just in development environment with debug log level as in production it would add too much overhead for each database call. And this feature also requires that you install ruby-plsql gem.</li>
</ul>
<p>As you see this probably is the largest &#8220;point&#8221; release that I have had :) Thanks also to other contributors which patches were included in this release.</p>
<p>As always you can install Oracle enhanced adapter on any Ruby platform (Ruby 1.8.6 / 1.8.7 or Ruby 1.9.1 or JRuby) with</p>
<pre>
gem install activerecord-oracle_enhanced-adapter
</pre>
<p>If you have any questions please use <a href="http://groups.google.com/group/oracle-enhanced">discussion group</a> or post comments here.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rayapps.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rayapps.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rayapps.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rayapps.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rayapps.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rayapps.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rayapps.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rayapps.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rayapps.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rayapps.wordpress.com/116/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.rayapps.com&blog=1589116&post=116&subd=rayapps&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.rayapps.com/2009/09/28/new-features-in-activerecord-oracle-enhanced-adapter-version-1-2-2/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a94fbe334eb75d80da9dd0d3d352df1b?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">elietas</media:title>
		</media:content>
	</item>
	</channel>
</rss>