rpc.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package mssql
  2. import (
  3. "encoding/binary"
  4. )
  5. type ProcId struct {
  6. id uint16
  7. name string
  8. }
  9. // parameter flags
  10. const (
  11. fByRevValue = 1
  12. fDefaultValue = 2
  13. )
  14. type Param struct {
  15. Name string
  16. Flags uint8
  17. ti typeInfo
  18. buffer []byte
  19. }
  20. func MakeProcId(name string) (res ProcId) {
  21. res.name = name
  22. if len(name) == 0 {
  23. panic("Proc name shouln't be empty")
  24. }
  25. if len(name) >= 0xffff {
  26. panic("Invalid length of procedure name, should be less than 0xffff")
  27. }
  28. return res
  29. }
  30. const (
  31. fWithRecomp = 1
  32. fNoMetaData = 2
  33. fReuseMetaData = 4
  34. )
  35. var (
  36. Sp_Cursor = ProcId{1, ""}
  37. Sp_CursorOpen = ProcId{2, ""}
  38. Sp_CursorPrepare = ProcId{3, ""}
  39. Sp_CursorExecute = ProcId{4, ""}
  40. Sp_CursorPrepExec = ProcId{5, ""}
  41. Sp_CursorUnprepare = ProcId{6, ""}
  42. Sp_CursorFetch = ProcId{7, ""}
  43. Sp_CursorOption = ProcId{8, ""}
  44. Sp_CursorClose = ProcId{9, ""}
  45. Sp_ExecuteSql = ProcId{10, ""}
  46. Sp_Prepare = ProcId{11, ""}
  47. Sp_PrepExec = ProcId{13, ""}
  48. Sp_PrepExecRpc = ProcId{14, ""}
  49. Sp_Unprepare = ProcId{15, ""}
  50. )
  51. // http://msdn.microsoft.com/en-us/library/dd357576.aspx
  52. func sendRpc(buf *tdsBuffer, headers []headerStruct, proc ProcId, flags uint16, params []Param) (err error) {
  53. buf.BeginPacket(packRPCRequest)
  54. writeAllHeaders(buf, headers)
  55. if len(proc.name) == 0 {
  56. var idswitch uint16 = 0xffff
  57. err = binary.Write(buf, binary.LittleEndian, &idswitch)
  58. if err != nil {
  59. return
  60. }
  61. err = binary.Write(buf, binary.LittleEndian, &proc.id)
  62. if err != nil {
  63. return
  64. }
  65. } else {
  66. err = writeUsVarChar(buf, proc.name)
  67. if err != nil {
  68. return
  69. }
  70. }
  71. err = binary.Write(buf, binary.LittleEndian, &flags)
  72. if err != nil {
  73. return
  74. }
  75. for _, param := range params {
  76. if err = writeBVarChar(buf, param.Name); err != nil {
  77. return
  78. }
  79. if err = binary.Write(buf, binary.LittleEndian, param.Flags); err != nil {
  80. return
  81. }
  82. err = writeTypeInfo(buf, &param.ti)
  83. if err != nil {
  84. return
  85. }
  86. err = param.ti.Writer(buf, param.ti, param.buffer)
  87. if err != nil {
  88. return
  89. }
  90. }
  91. return buf.FinishPacket()
  92. }