On Sep 14, 2:27 pm, Brian Stevens <[email protected]>
wrote:
> I have a bit of Ruby experience, and am looking to improve.  I have access to 
> Oracle and would be happy to test and/or [attempt to] implement 
> patches/changes under your tutelage.  Let me know if you'd like me to test 
> something for you.

Great!  To get things working correctly you are going to want to
implement execute_insert in the oracle adapter (or last_insert_id if
modifying the JDBC oracle subadapter).  You'll want to remove the
hacky shared oracle adapter's DatasetMethods#insert, instead passing
the :sequence option to Database#execute_insert from
Dataset#execute_insert.  execute_insert should then recognize the
sequence value, and if present, run a "SELECT
#{literal(sequence)}.currval FROM dual" on the connection to get the
generated sequence value after it runs the insert SQL.

There are plenty of examples in other adapters, so you'll probably
want to review the other adapter code if you get stuck.  I think the
only thing that isn't done similarly in the other adapters is the
Dataset#execute_insert override, which can probably be:

    private
    def execute_insert(sql, opts={}, &block)
      opts = default_server_opts(opts)
      opts[:sequence] = @opts[:sequence] if @opts[:sequence]
      @db.execute_insert(sql, opts, &block)
    end

Supporting other types of sequence handling, such as getting the
sequence value before inserting instead of afterward via a trigger, is
possible as well, but the modifications would have to be to done
elsewhere.  The easiest way to support it would be to force the user
to set an option such as:

    def set_before_sequence(primary_key, sequence_name)
      clone(:before_sequence=>[primary_key, sequence_name])
    end
    ds = ds.set_before_sequence(:primary_key, :sequence_name)

Then you'd probably want to override insert to check for the values:

    def insert(*values)
      if (pk, seq = @opts[:before_sequence]) && values.length == 1 &&
(v = values.at(0)).is_a?(Hash) && !v.include?(pk)
        sequence_value = # code to get sequence value using seq
        super(v.merge(pk=>sequence_value))
      else
        super
      end
    end

That code can go in the shared oracle adapter, since it is adapter
independent.

If you have any questions, please let me know.  The best way to test
things is to run the test suite (rake spec_oracle), but you'll
probably want to set up a spec/spec_config.rb using spec/
spec_config.rb.example.

Thanks,
Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sequel-talk?hl=en.

Reply via email to