lib/ass_launcher/enterprise/ole.rb
# encoding: utf-8
require 'ass_launcher/enterprise/ole/ole_binaries'
module AssLauncher
module Enterprise
# 1C:Enterprise ole objects layer
module Ole
# Wrapper for {OLE_CLIENT_TYPES}
def self.ole_client(type)
fail ArgumentError, "Invalid ole type `#{type}'. Use types:"\
" #{OLE_CLIENT_TYPES.keys}" unless OLE_CLIENT_TYPES.key? type
OLE_CLIENT_TYPES[type]
end
# 1C Infobase External Connection
class IbConnection
attr_reader :__ole__
protected :__ole__
# (see OleBinaries::AbstractAssOleBinary#initialize)
def initialize(requirement)
@requirement = requirement.to_s
end
# Open connection in to infobase described in conn_str
# @param conn_str [Support::ConnectionString::Server,
# Support::ConnectionString::File, String]
def __open__(conn_str)
return true if __opened__?
__init_ole__(__ole_binary__.ole.connect(__cs__(conn_str)))
true
end
def __init_ole__(ole)
@__ole__ = ole
end
private :__init_ole__
# Try close connection.
# @note *It* *not* *guaranteed* *real* *closing* *connection!*
# Connection keep alive while have any alive WIN32OLE refs
# generated this connection. {WIN32OLE#\_\_ass_ole_free\_\_} try kill
# refs but it work not always
# @see WIN32OLE
def __close__
return true if __closed__?
__ole__.send :__ass_ole_free__
@__ole__ = nil
true
end
# True if connection closed
def __closed__?
__ole__.nil?
end
# True if connection opened
def __opened__?
!__closed__?
end
# Set 1C Ole server properties
def __configure_com_connector__(opts)
opts.each do |k, v|
__ole_binary__.ole.setproperty(k, v)
end
end
def __cs__(conn_str)
return conn_str.to_ole_string if conn_str.respond_to? :to_ole_string
conn_str.to_s
end
protected :__cs__
def __ole_binary__
@__ole_binary__ ||= OleBinaries::COMConnector.new(@requirement)
end
protected :__ole_binary__
# Try call ole method
# @raise [RuntimeError] if object closed
def method_missing(method, *args)
fail "Attempt call method for closed object #{self.class.name}"\
if __closed__?
__ole__.send(method, *args)
end
protected :method_missing
end
# IWorkingProcessConnection
class WpConnection < IbConnection
# Connection with 1C Server working process described in uri
# @param uri [URI, String]
def __open__(uri)
return true if __opened__?
__init_ole__(__ole_binary__.ole.connectworkingprocess(uri.to_s))
true
end
end
# Wrapper for IServerAgentConnection
class AgentConnection < IbConnection
# Connection with 1C Server agent described in uri
# @param (see WpConnection#__open__)
def __open__(uri)
return true if __opened__?
__init_ole__(__ole_binary__.ole.connectagent(uri.to_s))
true
end
end
class ApplicationConnectError < StandardError; end
# Wrapper for V8xc.Application ole object
class ThinApplication < IbConnection
# Array of objects with opened connection for close all
def self.objects
@objects ||= []
end
# Close all opened connectons
def self.close_all
objects.each(&:__close__)
end
def initialize(requirement)
super
@opened = false
end
# (see IbConnection#__open__)
# @raise [ApplicationConnectError]
def __open__(conn_str)
return true if __opened__?
__try_open__(conn_str)
self.class.objects << self
__opened__?
end
def __try_open__(conn_str)
@opened = __ole_binary__.ole.connect(__cs__(conn_str))
fail ApplicationConnectError unless __opened__?
rescue StandardError => e
@opened = false
@__ole_binary__ = nil
raise e
end
protected :__try_open__
def __ole__
__ole_binary__.ole
end
protected :__ole__
def __opened__?
@opened
end
def __closed__?
!__opened__?
end
def __close__
return true if __closed__?
# rubocop:disable HandleExceptions
begin
__ole__.terminate
rescue
# NOP
ensure
@__ole_binary__ = nil
@opened = false
ThinApplication.objects.delete(self)
end
# rubocop:enable HandleExceptions
true
end
def __ole_binary__
@__ole_binary__ ||= OleBinaries::ThinApplication.new(@requirement)
end
protected :__ole_binary__
end
# Wrapper for V8x.Application ole object
class ThickApplication < ThinApplication
def __ole_binary__
@__ole_binary__ ||= OleBinaries::ThickApplication.new(@requirement)
end
protected :__ole_binary__
end
# Define type of 1C OLE clients
OLE_CLIENT_TYPES = {
external: AssLauncher::Enterprise::Ole::IbConnection,
wprocess: AssLauncher::Enterprise::Ole::WpConnection,
sagent: AssLauncher::Enterprise::Ole::AgentConnection,
thin: AssLauncher::Enterprise::Ole::ThinApplication,
thick: AssLauncher::Enterprise::Ole::ThickApplication
}
end
end
end