local ss = analiz.libs.serv
local tick = CreateTimeServ()

if ss.factory == nil then ss.factory = {} end
if ss.factory.msbroker == nil then
    ss.factory.msbroker = {ver_id = 1, ver = "0.002"}
end
-- ---------------------------------------------------------------------------
-- ---------------------------------------------------------------------------
-- option.dsn - 
-- ---------------------------------------------------------------------------
-- ---------------------------------------------------------------------------
--  local ENGINE_TYPE_DEFAULT = "ado"
--local ENGINE_TYPE_DEFAULT = "oe"
local ENGINE_TYPE_DEFAULT = "sqlapi"

ss.e("GET_CURRENT_PROCESS_ID txm_pid")
local host_name = ss.b("$(COMPUTERNAME)")
local pid = ss.g("txm_pid")

local function fix_(str)
    if str:find("'") == nil then return str end
    return ss.ReplaceValue(str, "'", "''")
end


   local function exe_and_reconnect(owner,sql)
        local emessage = owner.engine:ExecSqlEx(sql)
        if emessage~="" then 
         owner:reconnect()
         ss.l("resend.i=2")
         emessage = owner.engine:ExecSqlEx(sql)        
         if emessage=="" then 
           ss.l("execute.sql:ok(i=2)")
         else
             owner:reconnect()
             ss.l("resend.i=3")
             emessage = owner.engine:ExecSqlEx(sql)        
             if emessage=="" then 
               ss.l("execute.sql:ok(i=3)")
             else
               for i=1,5 do 
                  ss.l("resend&sleep.i="..i)
                   owner:reconnect()
                   emessage = owner.engine:ExecSqlEx(sql)        
                   if emessage=="" then    ss.l("execute.sql:ok(ii="..i..")") break end
                   ss.e("sleep sec 1")
               end
             end


         end
        end
       return  emessage
   end


local function get_sql_for_type_(ret,option,ttype)
    local queue_name = option.queue
    local sub_name = ss.def(option.name, "")
    local islock = ss.def(option.islock, "0")

    if islock=="1" and ttype=="S" then 
    local handle_str = "'" .. ret.dialogID .. "'"
    if option.send_ex == true then handle_str = ":send_handle" end

    local sql_send_str = [[
DECLARE @Example1Dialog uniqueidentifier
--DECLARE @Message varchar(max)
DECLARE @bMessage VARBINARY(max)

set @Example1Dialog = ]] .. handle_str .. [[


SET @bMessage =  :message_val;

SEND ON CONVERSATION @Example1Dialog 
   MESSAGE TYPE ]] .. ret.type_name .. [[ (@bMessage)

]]
     return sql_send_str
    end

    if islock=="1" and ttype=="R" then 
        local recive_sql = [[waitfor (
RECEIVE top(@limit) cast( message_body as varchar(max)) AS message
   FROM ]] .. ret.reciver .. [[
   WHERE  conversation_handle=']] .. ret.reciver_id .. [['
   ),timeout @timeout ]]
       return recive_sql

    end

--[=[
 if ttype=="R" then 
   local sql =[[ exec dbo.sbp_nc_input_default_recv @limit,@timeout]]
   return sql
end 
--]=]                                              


local sql =[[
DECLARE @SQL_CMD NVARCHAR(MAX);
--create reciev sp::start
EXEC dbo.sbp_GetServiceSPText 
     @SQL_CMD OUTPUT,
     @type_of_sp = ']]..ttype..[[',
     @default_shema_name = 'dbo',
     @queue_name = ']]..queue_name..[[',
     @queue_type = ']]..sub_name..[[',
     @prefix='_xxx_',
     @creation_type = 3,
     @debug = 0;


select cast(@SQL_CMD as varchar(7999)) AS C
]]

   ss.s("tmp_sql",sql)
   ss.e("echo SET_PARAM_FROM_SQL tmp " .. option.pwd .. " C $(tmp_sql)")
   ss.e("SET_PARAM_FROM_SQL tmp " .. option.pwd .. " C $(tmp_sql)")
  local res = ss.g("tmp")
ss.l(res)
  if res=="" then 
     ss.l("failed.execute.empty result for queue:"..sql)
  end

   return res


end

local function fix_empty_sql_(sql, ttype)
  if sql~="" then return sql end
  ss.l("fix_empty_sql_.ttype:"..ttype.." failed sql" )
  return "RAISERROR('faield create "..ttype..".', 16, 10);"
end
local function GetDialogID(option)
    ss.l("GetDialogID.start")
    if option.sender_handle ~= nil then
        local ret = {}
        ret.type_name = option.type_name
        ret.sender_handle = option.sender_handle
        ret.dialogID = option.sender_handle
        return ret
    end

  ss.l("point1")
    ss.l("_____________")
    ss.tprint(option)
--    ss.l(debug.traceback())
    -- ss.a(1)




    local sub_name = ss.def(option.name, "")
    local queue_name = option.queue
    local islock = ss.def(option.islock, "0")



   if option.max_prior~=nil and islock=="0" then 
      for i=1,option.max_prior do
    local sql = [[EXEC dbo.gsp_GetBrokerMsgChannelInfo @queue_name = ']] ..
                    queue_name .. [[',
     @queue_type = ']] .. sub_name .. [[',
     @priority = ]]..i..[[,
     @is_locked = ]] .. islock .. [[,
     @comment = 'init prior ]] .. i .. [[',
     @create_sps=0
]]

      ss.s("tmp_sql",sql)
      ss.e("echo EXEC_SQL "..option.pwd.." $(tmp_sql)")
      ss.e("EXEC_SQL "..option.pwd.." $(tmp_sql)")

      end
   end

  ss.l("point2")
--  ss.l(debug.traceback())
    ss.l("queue_name:" .. queue_name)
    ss.l("sub_name:" .. sub_name)
    ss.l("sub_name:" .. islock)
    local comment = "todo"
    -- ss.a(1)

    local sql = [[EXEC dbo.gsp_GetBrokerMsgChannelInfo @queue_name = ']] ..
                    queue_name .. [[',
     @queue_type = ']] .. sub_name .. [[',
     @is_locked = ]] .. islock .. [[,
     @comment = ']] .. comment .. [[',
     @create_sps=0
]]

    ss.l("dbo.gsp_GetBrokerMsgChannelInfo:"..sql)

    ss.s("tmp_sql", sql)
    ss.e("CREATE_OR_CLEAR_STRING_MAP tmp_broker_map")
    ss.e("ADD_MAP_FROM_SQL_SILEN tmp_broker_map " .. option.pwd .. " $(tmp_sql)")

    local m = analiz:map_get("tmp_broker_map")
    local ret = {}
  ss.l("point3")
    ret.dialogID = m:get("conversation_handle_Sender")
    ret.reciver = m:get("t_queue_name")
    ret.reciver_id = m:get("conversation_handle_Receiver")
    ret.sender_type = m:get("Message_type_name")
    ret.sender_handle = ret.dialogID
    ret.type_name = m:get("Message_type_name") -- "Msg_Type_NC_System" 

    ret.sender_sql_ = fix_empty_sql_(get_sql_for_type_(ret,option,"S"),"sender")
    ret.recive_sql_ = fix_empty_sql_(get_sql_for_type_(ret,option,"R"),"reciver")

    ss.l("handle_sender:".. ret.dialogID)
ss.l("xxx.ret.sender_sql_:"..ret.sender_sql_)
ss.l("______________________________________")
ss.l("xxx.ret.recive_sql_:"..ret.recive_sql_)
ss.l("______________________________________")

    ret.islock = islock == "1"
    -- stub

    if ret.reciver == "" then
        ss.l("failed.ret.reciver is empty")
        ss.l("sql:" .. sql)
    end

--    if islock == "1" then     ss.l("___________________________")     ss.tprint(ret)     ss.a(1)    end

    return ret

end

-- ---------------------------------------------------------------------------
-- ---------------------------------------------------------------------------

local function CreateSendSql_(option, prop)
    ss.l("CreateSendSql_.start")
    local handle_str = "'" .. prop.dialogID .. "'"
    if option.send_ex == true then handle_str = ":send_handle" end


    if prop.sender_sql_~=nil and option.send_ex~=true then 
      local sql = [[
--msbroker.lua:CreateSendSql_
DECLARE @value VARBINARY(max);
DECLARE @priority int =:prior;
DECLARE @prior    int =:prior;
set  @value= :message_val;


]]..prop.sender_sql_
     return sql
    end


--    ss.tprint(prop)
--    ss.l("___________________")
--    ss.l(debug.traceback())

    local sql_send_str = [[
DECLARE @Example1Dialog uniqueidentifier
--DECLARE @Message varchar(max)
DECLARE @bMessage VARBINARY(max)
DECLARE @priority int;
set @Example1Dialog =  cast(]] .. handle_str .. [[ as uniqueidentifier)


SET @bMessage =  :message_val;


SET @priority = :prior;


SEND ON CONVERSATION @Example1Dialog 
   MESSAGE TYPE ]] .. prop.type_name .. [[ (@bMessage)

]]

    return sql_send_str
end

local function CreateSendSql_str(option, prop, some_message)
    ss.l("CreateSendSql_str(v0)")
    local handle_str = "'" .. prop.dialogID .. "'"
    if option.send_ex == true then handle_str = ":send_handle" end

    if prop.sender_sql_~=nil and option.send_ex~=true then 

      local sql = [[DECLARE @value VARBINARY(max);
DECLARE @priority int;
DECLARE @prior int;
set  @value = cast(]] .. some_message .. [[ as varbinary(max));
set  @priority =:prior;
set  @prior =:prior;
]]..prop.sender_sql_
     return sql
    end


    local sql = [[
DECLARE @handle uniqueidentifier
--DECLARE @Message varchar(7999)
DECLARE @Message varchar(max)
DECLARE @sessionID uniqueidentifier
--DECLARE @Message VARBINARY(max)
DECLARE @priority int;

set @handle = ]] .. handle_str .. [[;

set  @priority =:prior;

SET @Message =  ]] .. some_message .. [[;

SEND ON CONVERSATION @handle 
   MESSAGE TYPE ]] .. prop.type_name .. [[ (@Message)

]]
ss.l("sql:"..sql)

    return sql
end

local function check_(option)
    ss.l("check_:")
    --    ss.l(debug.traceback())	
    --  ss.l("__________________________")
    --  option.recive= ss.def(option.recive,option.contract.."_recvQueue")
    --  option.recive_service=ss.def(option.recive_service,option.queue.."_reciveService")
    --  option.send= ss.def(option.send,option.contract.."_sendQueue")
    --  option.send_service=ss.def(option.send_service,option.queue.."_sendService")

    option.name = ss.def(option.name, "default")
end

local function CreateDefaultIOObj()
    local io_ = {}
    function io_:load(mem)
        ss.l("CreateDefaultIOObj:load")
        return mem:read_obj()
    end

    function io_:save(mem, obj)
        ss.l("CreateDefaultIOObj:save")
        mem:truncate()
        mem:write_obj(obj)
    end

    return io_
end

local function common_init(s,option)

    check_(option)

    if option.io_obj ~= nil then
        s.io_obj_ = option.io_obj
    else
        s.io_obj_ = CreateDefaultIOObj()
    end



    s.option = option
    s.mem = ss.CreateMemItem(10000)
    s.session = GetDialogID(option)

    local engine_type = ENGINE_TYPE_DEFAULT
    --  local engine_type = "oe"
    ss.l("broker.common_init:" .. engine_type..":"..ss.def(option.queue,"<nil>")..":"..ss.def(option.name,"<nil>"))
    s.sql = ss.CreateKmpSQL()
    s.engine = createSqlEngine({
        pwd = option.pwd,
        ENGINE_TYPE = engine_type,
        sql = "."
    })

    function s:updateLockDT(options, lock_min)
        if self.session.islock == false then return end
        local lock_min = ss.def(lock_min, "10")

        --    local sql = "update msBrokerServ set lockDT=dateadd("..datepart..","..number..",GetDate()),comment ='"..host_name.." pid:"..pid.."' where ID="..self.ID
        local sql = "exec  dbo.gsp_SetLockBrokerMsgChannel @ch='" ..
                        self.session.dialogID .. "', @lock_time_minute=" ..
                        lock_min
        --    ss.l(sql)
        self.sql:setSql(sql)
        self.engine:ExecSqlEx(self.sql)
    end

    function s:Lock_finallize(options) self:updateLockDT(options, 0) end
    return s
end

function ss.factory.msbroker.CreateSender(option)
    local s = {}
    common_init(s,option)
    ss.l("________________________sesson info:")
    ss.tprint(s.session)
    ss.l("________________________options:")
    ss.tprint(option)
    ss.l("________________________")
    s.send_sql = CreateSendSql_(option, s.session)
    ss.l("________________________2")
    ss.tprint(s.session)

    s.send_sql_str = CreateSendSql_str(option, s.session, ':message_val')

    function s:IsInitFailed()
      return ss.def(self.session.sender_sql_,""):find("RAISERROR")==1 or
             ss.def(self.session.dialogID,"xx")==""
    end

    -- ---------------------------
    function s:sendval2(val)
        ss.l("broker.writer:sendval2")
        local sql = CreateSendSql_str(self.option, self.session,
                                      "'" .. fix_(val) .. "'")
        -- ss.l(sql)

        if self.sql == nil then ss.l("failed.self.sql is null") end
        if sql == nil then ss.l("sql is null") end
        -- ss.l("point1:"..sql)
        self.sql:setSql(sql)
--        ss.l("point2")
        local emessage = exe_and_reconnect(self,self.sql)
        if ss.def(emessage,"")=="" then     ss.l("broker.writer:sendval2:ok")
                                   else ss.l("broker.writer:sendval2:failed:"..emessage) end
        -- ss.l("sendobj.end")
       return emessage

    end

    function s:sendval(val,option)
        if option==nil then option={} end

--  ss.a(1)
        ss.l("s:sendval")

        -- ss.l("sql:"..self.send_sql_str)
--       ss.l(debug.traceback())
       ss.l("prior:"..ss.def(option.prior,1))
        local len = #val
        ss.l("value.len:" .. len)


        -- ss.l("value:"..val)

        self.sql:setSql(self.send_sql_str)
        -- ss.l("point1")
         self.mem:truncate(0)
         self.mem:check_size(len+10)
         self.mem:set_string(val)
         self.mem:set_point(len)
          ss.l("get_point():" .. self.mem:get_point())

        self.sql:Clear()

        self.sql:add_int("prior",ss.def(option.prior,1))
        self.sql:add_blob("message_val", self.mem)
        local emessage = exe_and_reconnect(self,self.sql)
        if ss.def(emessage,"")=="" then     ss.l("broker.writer:sendval:ok")
                                   else ss.l("broker.writer:sendval:failed:"..emessage)
         end

       return emessage


    end

    -- ---------------------------
    function s:sendobj(obj,option)
        ss.l("____________________________________sendobj.object")
--       ss.l(debug.traceback())
        if option==nil then option={} end
        -- ss.l(self.send_sql)
        self.io_obj_:save(self.mem, obj)

        -- ss.l("sendobj.1")
        self.sql:setSql(self.send_sql)



--        ss.l("send_sql:"..self.send_sql)
        ss.l("prior:"..ss.def(option.prior,1))
        ss.l("get_point():" .. self.mem:get_point())
     ss.l("____________________________________sendobj:")
        self.sql:Clear()
        self.sql:add_blob("message_val", self.mem)
        self.sql:add_int("prior",ss.def(option.prior,1))
        -- ss.l("sendobj.3")
        local emessage = exe_and_reconnect(self,self.sql)

        if ss.def(emessage,"")=="" then     ss.l("broker.writer:sendobj:ok")
                                   else ss.l("broker.writer:sendobj:failed:"..emessage)
end

       return emessage
    end
    function s:reconnect(op)
      if op==nil then op={} end
      ss.l("broker reconnect..")
      ss.l(debug.traceback())
      self:logout()

      if self:IsInitFailed() or op.force==true then 
        ss.l("sender.full reinit.start")
        common_init(self,self.option)
        self.send_sql = CreateSendSql_(option, s.session)
        self.send_sql_str = CreateSendSql_str(option, s.session, ':message_val')
        ss.l("sender.reinit.finish")
      end

      self:login()
      ss.l("broker reconnect..end")
    end
    function s:sendobj_ex(obj, options)
        ss.l("____________________________________sendobj_ex.object")
        -- ss.l(self.send_sql)
        self.io_obj_:save(self.mem, obj)
        ss.l("get_point():" .. self.mem:get_point())
        -- ss.l("sendobj.1")
        self.sql:setSql(self.send_sql)
        self.sql:Clear()
        self.sql:add_blob("message_val", self.mem)
        self.sql:add_string("send_handle", options.send_handle)
        self.sql:add_int("prior", ss.def(options.prior,1))
        ss.l("send to handle:"..options.send_handle)
        ss.l("prior:"..options.send_handle)
        -- ss.l("sendobj.3")
        local emessage = exe_and_reconnect(self,self.sql)
        if ss.def(emessage,"")=="" then     ss.l("broker.writer:sendobj_ex:ok")
                                   else ss.l("broker.writer:sendobj_ex:failed:"..emessage)
        end
        -- ss.l("sendobj.end")
       return emessage
    end

    function s:logout()
        if self.engine == nil then return end
        ss.l("broker engine:Destroy")
        self.engine:Destroy()
        self.engine = nil
    end
    function s:login()
        if self.engine==nil then 
         ss.l("broker engine:login()")
        local engine_type = ENGINE_TYPE_DEFAULT
        ss.l("s.login:" .. engine_type)

        self.engine = createSqlEngine({
            pwd = self.option.pwd,
            ENGINE_TYPE = engine_type,
            sql = "."
        })
        end
    end

    function s:close()
        if self.engine ~= nil then self.engine:Destroy() end
        self.sql:Destroy()
        self.mem:destroy()
    end

    return s
end

-- ---------------------------------------------------------------------------
-- ---------------------------------------------------------------------------
-- ---------------------------------------------------------------------------

function ss.factory.msbroker.CreateReciver(option)
    ss.l("ss.factory.msbroker.CreateReciver.start:"..ss.def(option.name,"<nil>"))
    -- ss.tprint(option)
    -- ss.a(11)


    local r = {}
    common_init(r,option)
    -- conversation_handle
    -- conversation_group_id
    -- ------------------------------------
    function r:IsInitFailed()
      return ss.def(self.session.recive_sql_,""):find("RAISERROR")==1 or 
             ss.def(self.session.dialogID,"xx")==""
    end
    function r:reconnect(op)
      if op==nil then op={} end
      ss.l("broker reconnect..")
      self:logout()
      if self:IsInitFailed() or op.force==true then 
        ss.l("reciver.full reinit.start")
        common_init(self,self.option)
        ss.l("reciver.reinit.finish")
      end

      self:login()
      ss.l("broker reconnect..end")
    end

    function r:recivevals(option)

        local objs = {}

    local recive_sql=[[SET NOCOUNT ON;
declare @flag int = 1;
declare @timeout int = ]]..option.timeout..[[;
declare @limit int = ]]..option.limit..[[;
]]..  self.session.recive_sql_

        self.engine:SetSql(recive_sql, "0")
        local ii = 0
  --     ss.l("before next")
        local isNext, emessage = self.engine:Next()
--       ss.l("after next")
        while isNext do
            if emessage ~= "" then break end
--       ss.l("before record")
            local r = self.engine:Record()
--       ss.l("after record")
            --    ss.l("print:")   ss.tprint(r)
--            objs[#objs + 1] = r.message
           local m ={msg= r.MESSAGE,prior = ss.def(r.priority,"1")}
           if m.prior:find(".0")~=nil  then m.prior=ss.ReplaceValue(m.prior,".0","") end

            objs[#objs + 1] =m
--ss.l("br:______________________")ss.tprint(objs[#objs].prior)ss.l("________")

            ii = ii + 1
            isNext, emessage = self.engine:Next()
        end
        if ss.def(emessage,"")=="" then 
             if #objs >0 then      ss.l("broker.reciver:recivevals:ok.count:"..(#objs)) end
       else ss.l("broker.reciver:recivevals:failed.Limit:"..option.limit..",read:"..(#objs)..",message:"..emessage)
       end
        --If anything is returned, those records need to be processed.
        if (#objs)>0 then return objs,"" end

        return objs, emessage
    end

    -- ------------------------------------
    function r:reciveobj(option)
        local objs = {}
    local recive_sql=[[SET NOCOUNT ON;
declare @flag int = 1;
declare @timeout int = ]]..option.timeout..[[;
declare @limit int = ]]..option.limit..[[;
]]..  self.session.recive_sql_

--          ss.l("recive_sql:"..recive_sql)
        --  ss.a(1)
        --   ss.l("point1")
        self.engine:SetSql(recive_sql, "0")
        local ii = 0
        local isNext, emessage = self.engine:Next()
        while isNext do
            if emessage ~= "" then break end
            local r = self.engine:Record()
            self.mem:truncate()

            self.engine:debug_get_blob(1, self.mem);
            --   ss.l("point3")
            local res = self.io_obj_:load(self.mem) --
            --   ss.l("point4")
           local m ={msg= res,prior = ss.def(r.priority,"1")}
           if m.prior:find(".0")~=nil  then m.prior=ss.ReplaceValue(m.prior,".0","") end

            objs[#objs + 1] = m
            ii = ii + 1
            isNext, emessage = self.engine:Next()
            --   ss.l("point5")
        end
        if ss.def(emessage,"")=="" then     
             if #objs >0 then      ss.l("broker.reciver:reciveobj:ok.count:"..(#objs)) end
        else ss.l("broker.reciver:reciveobj:failed.Limit:"..option.limit..",read:"..(#objs)..",message:"..emessage)
        end
           
        --If anything is returned, those records need to be processed.
        if #objs>0 then return objs,"" end

        return objs, emessage
    end

    -- ------------------------------------
    function r:logout()
     ss.l("reciver:logout")
        if self.engine == nil then return end
        ss.l("self.engine:Destroy...")
        self.engine:Destroy()
        self.engine = nil
    end
    function r:login()
     ss.l("reciver:login")
       if self.engine==nil then 
     ss.l("reciver:loginImpl")
         local engine_type = ENGINE_TYPE_DEFAULT
           ss.l("r.login:" .. engine_type)
           ss.l("reciver:login.createSqlEngine")
           self.engine = createSqlEngine({
            pwd = self.option.pwd,
            ENGINE_TYPE = engine_type,
            sql = "."
           })
        end
    end

    -- ------------------------------------
    function r:close()
        if self.engine ~= nil then self.engine:Destroy() end
        self.sql:Destroy()
        self.mem:destroy()

    end
    -- ------------------------------------  

    -- ------------------------------------
    return r

end

-- ---------------------------------------------------------------------------
-- ---------------------------------------------------------------------------
-- ---------------------------------------------------------------------------
-- initBroker
-- createType
-- 
-- option={pwd='xxx'}
function ss.factory.msbroker.CreateServ(option)
    local s = {}
    s.option = option

    function s:exeSql_(sql)
        ss.s("tmp", sql)
        ss.e("echo EXEC_SQL " .. self.option.pwd .. " $(tmp)")
        ss.e("EXEC_SQL " .. self.option.pwd .. " $(tmp)")
    end
    -- ---------------------------------------------  
    function s:initBroker()
        ss.e("SET_PARAM_FROM_SQL tmp " .. self.option.pwd ..
                 " C select db_name() as C")
        local database = ss.g("tmp")
        ss.l("msbroker:initBroker:" .. database)

        self:exeSql_([[--Enabling service broker
USE master
ALTER DATABASE  ]] .. database .. [[  
 SET ENABLE_BROKER; 
]])

    end

    -- ---------------------------------------------
    -- validate_type:"NONE","WELL_FORMED_XML"
    function s:CreateType(typeinfo)
        ss.l("msbroker:create type " .. typeinfo.typename .. " validation:" ..
                 typeinfo.validate_type)
        self:exeSql_("CREATE MESSAGE TYPE " .. typeinfo.typename ..
                         " VALIDATION = " .. typeinfo.validate_type)
    end

    function s:CreateContract(type_name, contractName)
        ss.l("msbroker:create contract " .. contractName .. " type:" ..
                 type_name)
        self:exeSql_("CREATE CONTRACT " .. contractName .. " (" .. type_name ..
                         " SENT BY any) ")
    end

    function s:CreateQueue(QueueName)
        ss.l("CREATE QUEUE " .. QueueName)
        --   ss.a(1)
        self:exeSql_("CREATE QUEUE " .. QueueName)
    end

    function s:CreateService(QueueName, ServiceName, contractName, comment)
        ss.l(
            "msbroker:create service:" .. ServiceName .. " Queue:" .. QueueName ..
                "contractName:" .. contractName .. " comment:" ..
                ss.def(comment, "none"))
        --   self:exeSql_("CREATE QUEUE "..QueueName)
        self:exeSql_("CREATE SERVICE " ..
                         ss.def(ServiceName, "!!ServceName_is_null!!") ..
                         " ON QUEUE " ..
                         ss.def(QueueName, "!!QueueName_is_NULL!!") .. "(" ..
                         ss.def(contractName, "!contractName_is_null!") .. ")")
    end

    function s:FullCreateService(name, option, typeOption)
        ss.def("option.send_service:")

        --   ss.a(1467)
        check_(option)
        ss.l("______________________________________________________")
        ss.tprint(option)

        ss.l("______________________________________________________")
        self:CreateContract(typeOption.typename, option.contract)
        ss.tprint(option)

        ss.l("______________________________________________________")
        local sendQ = name .. "_sendQueue"
        local recvQ = name .. "_recvQueue"
        self:CreateQueue(sendQ)
        self:CreateQueue(recvQ)

        ss.l("______________________________________________________")

        --    self:CreateService(name,name.."_send",option.contract,"send")
        self:CreateService(sendQ, option.send_service, option.contract, "send")
        ss.l("______________________________________________________")
        --    self:CreateService(name,name.."_recv",option.contract,"recive")
        self:CreateService(recvQ, option.recive_service, option.contract,
                           "recive")
        ss.l("______________________________________________________")
    end

    -- ----------------------------------------------------------------------

    function s:CreateProcedureSend(option, name)
        check_(option)
        local dialogID = GetDialogID(option).dialogID
        ss.l("send.dialogID:" .. dialogID)
        --  ss.a(11)

        local sql0 = [[
IF EXISTS ( SELECT * 
            FROM   sysobjects 
            WHERE  id = object_id(N'[dbo].[]] .. name .. [[]') 
                   and OBJECTPROPERTY(id, N'IsProcedure') = 1 )
BEGIN 
 DROP PROCEDURE [dbo].[]] .. name .. [[]
end
]]

        -- =============================================
        -- Author:		analiz.msbroker.serv
        -- Create date:]]..ss.b("$(now)").. [[ 
        -- Description:	Send value to msbroker
        -- =============================================

        local sql1 = [[


CREATE PROCEDURE ]] .. name .. [[
	@value as varchar(max)
AS
BEGIN
DECLARE @dialog_id uniqueidentifier
DECLARE @Message varchar(max)
--DECLARE @bMessage VARBINARY(max)

set @dialog_id = ']] .. dialogID .. [['


SET @Message =  @value;
SEND ON CONVERSATION @dialog_id
   MESSAGE TYPE ]] .. option.typeinfo.typename .. [[ (@Message)END

]]

        self:exeSql_(sql0)
        self:exeSql_(sql1)

        return "exec " .. name .. " 'hello word'"
    end
    -- ----------------------------------------------------------------------
    -- ----------------------------------------------------------------------

    function s:CreateProcedureRecv(option, name)
        check_(option)
        local dialogID = GetDialogID(option).dialogID
        ss.l("recive.dialogID:" .. dialogID)

        local sql0 = [[
IF EXISTS ( SELECT * 
            FROM   sysobjects 
            WHERE  id = object_id(N'[dbo].[]] .. name .. [[]') 
                   and OBJECTPROPERTY(id, N'IsProcedure') = 1 )
BEGIN 
 DROP PROCEDURE [dbo].[]] .. name .. [[]
end
]]

        -- =============================================
        -- Author:		analiz.msbroker.serv
        -- Create date: ]]..ss.b("$(now)").. [[ 
        -- Description:	Recive value to msbroker
        -- =============================================

        local sql1 = [[


CREATE PROCEDURE ]] .. name .. [[ 
	@limit as int,
	@timeout as int
AS
BEGIN
waitfor (
RECEIVE top(@limit )  cast(message_body as varchar(max)) AS message



   FROM ContractTestBin1_reciveQueue 
  ),timeout @timeout
end
]]
        --   where conversation_handle=']]..dialogID..[['
        self:exeSql_(sql0)
        self:exeSql_(sql1)

        return "exec " .. name .. " 10,10000"
    end

    return s
end

-- ---------------------------------------------------------------------------
-- ---------------------------------------------------------------------------
-- ---------------------------------------------------------------------------


