rpc.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. const (
  21. fWithRecomp = 1
  22. fNoMetaData = 2
  23. fReuseMetaData = 4
  24. )
  25. var (
  26. sp_Cursor = procId{1, ""}
  27. sp_CursorOpen = procId{2, ""}
  28. sp_CursorPrepare = procId{3, ""}
  29. sp_CursorExecute = procId{4, ""}
  30. sp_CursorPrepExec = procId{5, ""}
  31. sp_CursorUnprepare = procId{6, ""}
  32. sp_CursorFetch = procId{7, ""}
  33. sp_CursorOption = procId{8, ""}
  34. sp_CursorClose = procId{9, ""}
  35. sp_ExecuteSql = procId{10, ""}
  36. sp_Prepare = procId{11, ""}
  37. sp_PrepExec = procId{13, ""}
  38. sp_PrepExecRpc = procId{14, ""}
  39. sp_Unprepare = procId{15, ""}
  40. )
  41. // http://msdn.microsoft.com/en-us/library/dd357576.aspx
  42. func sendRpc(buf *tdsBuffer, headers []headerStruct, proc procId, flags uint16, params []param, resetSession bool) (err error) {
  43. buf.BeginPacket(packRPCRequest, resetSession)
  44. writeAllHeaders(buf, headers)
  45. if len(proc.name) == 0 {
  46. var idswitch uint16 = 0xffff
  47. err = binary.Write(buf, binary.LittleEndian, &idswitch)
  48. if err != nil {
  49. return
  50. }
  51. err = binary.Write(buf, binary.LittleEndian, &proc.id)
  52. if err != nil {
  53. return
  54. }
  55. } else {
  56. err = writeUsVarChar(buf, proc.name)
  57. if err != nil {
  58. return
  59. }
  60. }
  61. err = binary.Write(buf, binary.LittleEndian, &flags)
  62. if err != nil {
  63. return
  64. }
  65. for _, param := range params {
  66. if err = writeBVarChar(buf, param.Name); err != nil {
  67. return
  68. }
  69. if err = binary.Write(buf, binary.LittleEndian, param.Flags); err != nil {
  70. return
  71. }
  72. err = writeTypeInfo(buf, &param.ti)
  73. if err != nil {
  74. return
  75. }
  76. err = param.ti.Writer(buf, param.ti, param.buffer)
  77. if err != nil {
  78. return
  79. }
  80. }
  81. return buf.FinishPacket()
  82. }