unsafe.go-disabled 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package native
  2. import (
  3. "github.com/ziutek/mymysql/mysql"
  4. "time"
  5. "unsafe"
  6. )
  7. type paramValue struct {
  8. typ uint16
  9. addr unsafe.Pointer
  10. raw bool
  11. length int // >=0 - length of value, <0 - unknown length
  12. }
  13. func (pv *paramValue) SetAddr(addr uintptr) {
  14. pv.addr = unsafe.Pointer(addr)
  15. }
  16. func (val *paramValue) Len() int {
  17. if val.addr == nil {
  18. // Invalid Value was binded
  19. return 0
  20. }
  21. // val.addr always points to the pointer - lets dereference it
  22. ptr := *(*unsafe.Pointer)(val.addr)
  23. if ptr == nil {
  24. // Binded Ptr Value is nil
  25. return 0
  26. }
  27. if val.length >= 0 {
  28. return val.length
  29. }
  30. switch val.typ {
  31. case MYSQL_TYPE_STRING:
  32. return lenStr(*(*string)(ptr))
  33. case MYSQL_TYPE_DATE:
  34. return lenDate(*(*mysql.Date)(ptr))
  35. case MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_DATETIME:
  36. return lenTime(*(*time.Time)(ptr))
  37. case MYSQL_TYPE_TIME:
  38. return lenDuration(*(*time.Duration)(ptr))
  39. case MYSQL_TYPE_TINY: // val.length < 0 so this is bool
  40. return 1
  41. }
  42. // MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_BLOB and type of Raw value
  43. return lenBin(*(*[]byte)(ptr))
  44. }
  45. func (pw *pktWriter) writeValue(val *paramValue) {
  46. if val.addr == nil {
  47. // Invalid Value was binded
  48. return
  49. }
  50. // val.addr always points to the pointer - lets dereference it
  51. ptr := *(*unsafe.Pointer)(val.addr)
  52. if ptr == nil {
  53. // Binded Ptr Value is nil
  54. return
  55. }
  56. if val.raw || val.typ == MYSQL_TYPE_VAR_STRING ||
  57. val.typ == MYSQL_TYPE_BLOB {
  58. pw.writeBin(*(*[]byte)(ptr))
  59. return
  60. }
  61. // We don't need unsigned bit to check type
  62. switch val.typ & ^MYSQL_UNSIGNED_MASK {
  63. case MYSQL_TYPE_NULL:
  64. // Don't write null values
  65. case MYSQL_TYPE_STRING:
  66. s := *(*string)(ptr)
  67. pw.writeBin([]byte(s))
  68. case MYSQL_TYPE_LONG, MYSQL_TYPE_FLOAT:
  69. pw.writeU32(*(*uint32)(ptr))
  70. case MYSQL_TYPE_SHORT:
  71. pw.writeU16(*(*uint16)(ptr))
  72. case MYSQL_TYPE_TINY:
  73. if val.length == -1 {
  74. // Translate bool value to MySQL tiny
  75. if *(*bool)(ptr) {
  76. pw.writeByte(1)
  77. } else {
  78. pw.writeByte(0)
  79. }
  80. } else {
  81. pw.writeByte(*(*byte)(ptr))
  82. }
  83. case MYSQL_TYPE_LONGLONG, MYSQL_TYPE_DOUBLE:
  84. pw.writeU64(*(*uint64)(ptr))
  85. case MYSQL_TYPE_DATE:
  86. pw.writeDate(*(*mysql.Date)(ptr))
  87. case MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_DATETIME:
  88. pw.writeTime(*(*time.Time)(ptr))
  89. case MYSQL_TYPE_TIME:
  90. pw.writeDuration(*(*time.Duration)(ptr))
  91. default:
  92. panic(mysql.ErrBindUnkType)
  93. }
  94. return
  95. }