note description: "Sybase specification" legal: "See notice at end of class." status: "See notice at end of class."; date: "$Date$"; revision: "$Revision$" class SYBASE inherit DATABASE redefine results_order, result_order, dim_rep_diff, sql_adapt_db, map_var_before, map_var_after, proc_args end STRING_HANDLER feature -- Access database_handle_name: STRING = "SYBASE" feature -- For DATABASE_STATUS is_error_updated: BOOLEAN -- Has Sybase function been called since last update which may have -- updated error code, error message? is_warning_updated: BOOLEAN = True -- No warning implemented in C code. found: BOOLEAN -- Is there any record matching the last -- selection condition used ? clear_error -- Reset database error status. do end insert_auto_identity_column: BOOLEAN -- For INSERTs and UPDATEs should table auto-increment identity columns be explicitly included in the statement? do check to_be_implemented: False end end feature -- For DATABASE_CHANGE descriptor_is_available: BOOLEAN do Result := (syb_available_descriptor = 1) end results_order (no_descriptor: INTEGER): INTEGER do Result := syb_results_order (no_descriptor) end feature -- For DATABASE_FORMAT date_to_str (object: DATE_TIME): STRING -- String representation in SQL of `object' do create Result.make (1) Result.append (object.out) Result.precede ('%'') Result.extend ('%'') end string_format (object: detachable STRING): STRING -- String representation in SQL of `object' obsolete "Use `string_format_32' instead [2017-11-30]." do Result := string_format_32 (object).as_string_8_conversion end string_format_32 (object: detachable READABLE_STRING_GENERAL): STRING_32 -- String representation in SQL of `object' do if attached object as l_s then Result := l_s.as_string_32 if not is_binary (Result) then Result.precede ({CHARACTER_32}'%'') Result.extend ({CHARACTER_32}'%'') end else Result := {STRING_32}"IS NULL" end end True_representation: STRING = "1" False_representation: STRING = "0" feature -- For DATABASE_SELECTION, DATABASE_CHANGE normal_parse: BOOLEAN = True result_order (descriptor: INTEGER) do last_error_code := syb_result_order (descriptor) end feature -- Access last_error_code: INTEGER -- Last error returned by Handle. get_error_code: INTEGER do Result := last_error_code end feature -- For DATABASE_STORE dim_rep_diff (repository_dimension, ufield_count: INTEGER): BOOLEAN do Result := repository_dimension /= ufield_count end feature -- DATABASE_STRING sql_name_string: STRING once Result := "varchar(500)" ensure then Result.is_equal ("varchar(500)") end feature -- DECIMAL sql_name_decimal: STRING -- SQL type name for decimal once Result := " decimal" end feature -- DATABASE_REAL sql_name_real: STRING once Result := "float" ensure then Result.is_equal ("float") end feature -- DATABASE_DATETIME sql_name_datetime: STRING once Result := "datetime" ensure then Result.is_equal ("datetime") end feature -- DATABASE_DOUBLE sql_name_double: STRING once Result := "float" ensure then Result.is_equal ("float") end feature -- DATABASE_CHARACTER sql_name_character: STRING once Result := "char(1)" ensure then Result.is_equal ("char(1)") end feature -- DATABASE_INTEGER sql_name_integer: STRING once Result := "int" ensure then Result.is_equal ("int") end sql_name_integer_16: STRING once Result := "smallint" ensure then Result.is_equal ("smallint") end sql_name_integer_64: STRING once Result := "bigint" ensure then Result.is_equal ("bigint") end feature -- DATABASE_BOOLEAN sql_name_boolean: STRING once Result := "bit" ensure then textual_outlook: Result.is_equal ("bit") end feature -- LOGIN and DATABASE_APPL only for password_ok password_ok (upasswd: STRING): BOOLEAN do Result := upasswd /= Void end password_ensure (name, passwd, uname, upasswd: STRING): BOOLEAN do Result := name.is_equal(uname) and passwd.is_equal(upasswd) end feature -- For DATABASE_PROC support_sql_of_proc: BOOLEAN = True support_stored_proc: BOOLEAN = True sql_adapt_db (sql: STRING): STRING do Result := sql Result.replace_substring_all (":", "@") end sql_as: STRING = " as " sql_end: STRING = "" sql_execution: STRING = "exec " sql_creation: STRING = "create procedure " sql_after_exec: STRING = "" support_drop_proc: BOOLEAN = True name_proc_lower: BOOLEAN = False map_var_before: STRING = " " map_var_between: STRING = " @" map_var_name_32 (a_para: READABLE_STRING_GENERAL): STRING_32 -- Map variable string for late bound stored procedure execution do create Result.make (a_para.count + 1) Result.append ({STRING_32}":") Result.append_string_general (a_para) end map_var_after: STRING = "" Select_text_32 (proc_name: READABLE_STRING_GENERAL): STRING_32 do Result := {STRING_32}"select a.text from syscomments a, sysobjects b where b.name = :name and b.id = a.id" end Select_exists_32 (proc_name: READABLE_STRING_GENERAL): STRING_32 do Result := {STRING_32}"select count(*) from % %sysobjects where type = 'P' % %and name = :name" end proc_args: BOOLEAN = True feature -- For DATABASE_REPOSITORY Selection_string (rep_qualifier, rep_owner, repository_name: STRING): STRING do Result := "select owner_id = sysobjects.uid, % %table_id = sysobjects.id, table_name = sysobjects.name, % %table_type = sysobjects.type, creation_date = % %sysobjects.crdate, column_name = syscolumns.name, % %column_id = colid, data_type = syscolumns.type, % %data_length = length, status from sysobjects, % %syscolumns where sysobjects.id = syscolumns.id and % %sysobjects.name = :rep" end sql_string: STRING = "varchar(" sql_string2 (int: INTEGER): STRING do Result := " text" end sql_wstring: STRING = "unichar (" sql_wstring2 (int: INTEGER): STRING do Result := " unitext" end feature -- External features get_error_message: POINTER do Result := syb_get_error_message end get_error_message_string: STRING_32 local l_s: C_STRING do create l_s.make_by_pointer (syb_get_error_message) Result := l_s.string end get_warn_message: POINTER do Result := syb_get_warn_message end get_warn_message_string: STRING_32 local l_s: C_STRING do create l_s.make_by_pointer (syb_get_warn_message) Result := l_s.string end new_descriptor: INTEGER do Result := syb_new_descriptor end init_order (no_descriptor: INTEGER; command: READABLE_STRING_GENERAL) local c_temp: C_STRING do create c_temp.make (utf32_to_utf8 (command.as_string_32)) last_error_code := syb_init_order (no_descriptor, c_temp.item) end start_order (no_descriptor: INTEGER) do last_error_code := syb_start_order(no_descriptor) end next_row (no_descriptor: INTEGER) do found := (syb_next_row(no_descriptor) = 0) end terminate_order (no_descriptor: INTEGER) do -- We don't bother to change `last_error_code' because `syb_terminate_order' -- at C side always return 0, which wipes out actual last error. syb_terminate_order(no_descriptor).do_nothing end close_cursor (no_descriptor: INTEGER) -- Do nothing, for ODBC prepared statement do end exec_immediate (no_descriptor: INTEGER; command: READABLE_STRING_GENERAL) local c_temp: C_STRING do create c_temp.make (utf32_to_utf8 (command.as_string_32)) last_error_code := syb_exec_immediate(c_temp.item) end put_col_name (no_descriptor: INTEGER; index: INTEGER; ar: STRING; max_len:INTEGER): INTEGER local l_area: MANAGED_POINTER i: INTEGER do create l_area.make (max_len) Result := syb_put_col_name(no_descriptor, index, l_area.item) check Result <= max_len end ar.set_count (Result) from i := 1 until i > Result loop ar.put (l_area.read_integer_8 (i - 1).to_character_8, i) i := i + 1 end end put_data (no_descriptor: INTEGER; index: INTEGER; ar: STRING; max_len:INTEGER): INTEGER local l_area: MANAGED_POINTER i: INTEGER do create l_area.make (max_len) Result := syb_put_data (no_descriptor, index, l_area.item) check Result <= max_len end ar.set_count (Result) from i := 1 until i > Result loop ar.put (l_area.read_integer_8 (i - 1).to_character_8, i) i := i + 1 end end put_data_32 (no_descriptor: INTEGER; index: INTEGER; ar: STRING_32; max_len:INTEGER): INTEGER local l_sql_string: SYBASE_SQL_STRING l_area: MANAGED_POINTER do create l_area.make (max_len) Result := syb_put_data (no_descriptor, index, l_area.item) check Result <= max_len end Result := Result // {SYBASE_SQL_STRING}.character_size ar.grow (Result) ar.set_count (Result) create l_sql_string.make_shared_from_pointer_and_count (l_area.item, Result) l_sql_string.read_substring_into (ar, 1, Result) end conv_type (indicator: INTEGER; index: INTEGER): INTEGER do Result := syb_conv_type (index) end get_count (no_descriptor: INTEGER): INTEGER do Result := syb_get_count(no_descriptor) end get_data_len (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_data_len (no_descriptor, ind) end get_col_len (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_col_len (no_descriptor, ind) end get_col_type (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_col_type (no_descriptor,ind) end get_integer_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_integer_data (no_descriptor, ind) end get_integer_16_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER_16 do Result := syb_get_integer_16_data (no_descriptor, ind) end get_integer_64_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER_64 do Result := syb_get_integer_64_data (no_descriptor, ind) end get_float_data (no_descriptor: INTEGER; ind: INTEGER): DOUBLE do Result := syb_get_float_data (no_descriptor, ind) end get_real_data (no_descriptor: INTEGER; ind: INTEGER): REAL do Result := syb_get_real_data (no_descriptor, ind).truncated_to_real end get_boolean_data (no_descriptor: INTEGER; ind: INTEGER): BOOLEAN do Result := syb_get_boolean_data (no_descriptor, ind) end is_null_data (no_descriptor: INTEGER; ind: INTEGER): BOOLEAN -- is last retrieved data null? do end get_date_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_date_data (no_descriptor, ind) end get_hour (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_hour end get_sec (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_sec end get_min (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_min end get_year (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_year end get_day (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_day end get_month (no_descriptor: INTEGER; ind: INTEGER): INTEGER do Result := syb_get_month end get_decimal (no_descriptor: INTEGER; ind: INTEGER): detachable TUPLE [digits: STRING_8; sign, precision, scale: INTEGER] -- Function used to get decimal info do Result := ["0", 1, 1, 0] end decimal_tuple_from_string (a_str: STRING_8): detachable TUPLE [digits: STRING_8; sign, precision, scale: INTEGER] -- Decimal tuple from string -- Simple implementation do Result := ["0", 1, 1, 0] end database_make (i: INTEGER) do syb_database_make (i) end connect (user_name, user_passwd, data_source, application, hostname, roleId, rolePassWd, groupId: STRING) local c_temp1, c_temp2, c_temp3, c_temp4: C_STRING do create c_temp1.make (user_name) create c_temp2.make (user_passwd) create c_temp3.make (application) create c_temp4.make (hostname) last_error_code := syb_connect (c_temp1.item, c_temp2.item, c_temp3.item, c_temp4.item) end connect_by_connection_string (a_connect_string: STRING) -- Connect to database by connection string do end disconnect do last_error_code := syb_disconnect found := False end commit do last_error_code := syb_commit end rollback do last_error_code := syb_rollback end trancount: INTEGER do Result := syb_trancount end begin do last_error_code := syb_begin end feature {NONE} -- External features syb_get_error_message: POINTER external "C" end syb_get_warn_message: POINTER external "C" end syb_new_descriptor: INTEGER external "C" end syb_init_order (no_descriptor: INTEGER; command: POINTER): INTEGER external "C" end syb_start_order (no_descriptor: INTEGER): INTEGER external "C" end syb_next_row (no_descriptor: INTEGER): INTEGER external "C" end syb_terminate_order (no_descriptor: INTEGER): INTEGER external "C" end syb_exec_immediate (command: POINTER): INTEGER external "C" end syb_put_col_name (no_descriptor: INTEGER; index: INTEGER; ar: POINTER): INTEGER external "C" end syb_put_data (no_descriptor: INTEGER; index: INTEGER; ar: POINTER): INTEGER external "C" end syb_conv_type (index: INTEGER): INTEGER external "C" end syb_get_count (no_descriptor: INTEGER): INTEGER external "C" end syb_get_data_len (no_descriptor: INTEGER; ind: INTEGER): INTEGER external "C" end syb_get_col_len (no_descriptor: INTEGER; ind: INTEGER): INTEGER external "C" end syb_get_col_type (no_descriptor: INTEGER; ind: INTEGER): INTEGER external "C" end syb_get_integer_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER external "C" end syb_get_integer_16_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER_16 external "C" end syb_get_integer_64_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER_64 external "C" end syb_get_float_data (no_descriptor: INTEGER; ind: INTEGER): DOUBLE external "C" end syb_get_real_data (no_descriptor: INTEGER; ind: INTEGER): DOUBLE external "C" end syb_get_boolean_data (no_descriptor: INTEGER; ind: INTEGER): BOOLEAN external "C" end syb_get_date_data (no_descriptor: INTEGER; ind: INTEGER): INTEGER external "C" end syb_get_hour: INTEGER external "C" end syb_get_sec: INTEGER external "C" end syb_get_min: INTEGER external "C" end syb_get_year: INTEGER external "C" end syb_get_day: INTEGER external "C" end syb_get_month: INTEGER external "C" end syb_database_make (i: INTEGER) external "C" alias "c_syb_make" end syb_disconnect: INTEGER external "C" end syb_commit: INTEGER external "C" end syb_rollback: INTEGER external "C" end syb_trancount: INTEGER external "C" end syb_begin: INTEGER external "C" end syb_connect (user_name, user_passwd, appl, host: POINTER): INTEGER external "C" end syb_results_order (no_descriptor: INTEGER): INTEGER external "C" end syb_result_order (no_descriptor: INTEGER): INTEGER external "C" end is_binary (s: READABLE_STRING_GENERAL): BOOLEAN -- Is `s' a binary type? require s_not_void: s /= Void do Result := s.code (1) = ('0').natural_32_code and then s.code (2) = ('x').natural_32_code ensure result_condition: Result implies (s.code (1) = ('0').natural_32_code and then s.code (2) = ('x').natural_32_code) end syb_available_descriptor: INTEGER external "C" end note copyright: "Copyright (c) 1984-2017, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end -- class SYBASE