# # $Id: odbcext_sqlanywhere.rb,v 1.2 2008/04/22 16:54:57 source Exp $ # # OpenLink ODBC Adapter for Ruby on Rails # Copyright (C) 2006 OpenLink Software # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject # to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR # ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # module ODBCExt # ------------------------------------------------------------------------ # Mandatory methods # # #last_insert_id must be implemented for any database which returns # false from #prefetch_primary_key? def last_insert_id(table, sequence_name, stmt = nil) @logger.unknown("ODBCAdapter#last_insert_id>") if @trace select_value("select @@IDENTITY", 'last_insert_id') end # ------------------------------------------------------------------------ # Optional methods # # These are supplied for a DBMS only if necessary. # ODBCAdapter tests for optional methods using Object#respond_to? # Pre action for ODBCAdapter#insert def pre_insert(sql, name, pk, id_value, sequence_name) @iiTable = get_table_name(sql) @iiCol = get_autounique_column(@iiTable) @iiEnabled = false if @iiCol != nil if query_contains_autounique_col(sql, @iiCol) begin @connection.do(enable_identity_insert(@iiTable, true)) @iiEnabled = true rescue Exception => e raise ActiveRecordError, "IDENTITY_INSERT could not be turned on" end end end end # Post action for ODBCAdapter#insert def post_insert(sql, name, pk, id_value, sequence_name) if @iiEnabled begin @connection.do(enable_identity_insert(@iiTable, false)) rescue Exception => e raise ActiveRecordError, "IDENTITY_INSERT could not be turned off" end end end # ------------------------------------------------------------------------ # Method redefinitions # # DBMS specific methods which override the default implementation # provided by the ODBCAdapter core. def get_table_name(sql) if sql =~ /^\s*insert\s+into\s+([^\(\s]+)\s*|^\s*update\s+([^\(\s]+)\s*/i $1 elsif sql =~ /from\s+([^\(\s]+)\s*/i $1 else nil end end def get_autounique_column(table_name) @table_columns = {} unless @table_columns @table_columns[table_name] = columns(table_name) if @table_columns[table_name] == nil @table_columns[table_name].each do |col| return col.name if col.auto_unique? end return nil end def query_contains_autounique_col(sql, col) sql =~ /(\[#{col}\])|("#{col}")/ end def enable_identity_insert(table_name, enable = true) if has_autounique_column(table_name) "SET IDENTITY_INSERT #{table_name} #{enable ? 'ON' : 'OFF'}" end end def has_autounique_column(table_name) !get_autounique_column(table_name).nil? end end # module