utils.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
  2. //
  3. // Copyright 2012 Julien Schmidt. All rights reserved.
  4. // http://www.julienschmidt.com
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla Public
  7. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  8. // You can obtain one at http://mozilla.org/MPL/2.0/.
  9. package mysql
  10. import (
  11. "crypto/sha1"
  12. "database/sql/driver"
  13. "encoding/binary"
  14. "fmt"
  15. "io"
  16. "log"
  17. "os"
  18. "regexp"
  19. "strings"
  20. "time"
  21. )
  22. // Logger
  23. var (
  24. errLog *log.Logger
  25. )
  26. func init() {
  27. errLog = log.New(os.Stderr, "[MySQL] ", log.Ldate|log.Ltime|log.Lshortfile)
  28. dsnPattern = regexp.MustCompile(
  29. `^(?:(?P<user>.*?)(?::(?P<passwd>.*))?@)?` + // [user[:password]@]
  30. `(?:(?P<net>[^\(]*)(?:\((?P<addr>[^\)]*)\))?)?` + // [net[(addr)]]
  31. `\/(?P<dbname>.*?)` + // /dbname
  32. `(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1&paramN=valueN]
  33. }
  34. // Data Source Name Parser
  35. var dsnPattern *regexp.Regexp
  36. func parseDSN(dsn string) (cfg *config, err error) {
  37. cfg = new(config)
  38. cfg.params = make(map[string]string)
  39. matches := dsnPattern.FindStringSubmatch(dsn)
  40. names := dsnPattern.SubexpNames()
  41. for i, match := range matches {
  42. switch names[i] {
  43. case "user":
  44. cfg.user = match
  45. case "passwd":
  46. cfg.passwd = match
  47. case "net":
  48. cfg.net = match
  49. case "addr":
  50. cfg.addr = match
  51. case "dbname":
  52. cfg.dbname = match
  53. case "params":
  54. for _, v := range strings.Split(match, "&") {
  55. param := strings.SplitN(v, "=", 2)
  56. if len(param) != 2 {
  57. continue
  58. }
  59. cfg.params[param[0]] = param[1]
  60. }
  61. }
  62. }
  63. // Set default network if empty
  64. if cfg.net == "" {
  65. cfg.net = "tcp"
  66. }
  67. // Set default adress if empty
  68. if cfg.addr == "" {
  69. cfg.addr = "127.0.0.1:3306"
  70. }
  71. cfg.loc, err = time.LoadLocation(cfg.params["loc"])
  72. return
  73. }
  74. // Encrypt password using 4.1+ method
  75. // http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#4.1_and_later
  76. func scramblePassword(scramble, password []byte) []byte {
  77. if len(password) == 0 {
  78. return nil
  79. }
  80. // stage1Hash = SHA1(password)
  81. crypt := sha1.New()
  82. crypt.Write(password)
  83. stage1 := crypt.Sum(nil)
  84. // scrambleHash = SHA1(scramble + SHA1(stage1Hash))
  85. // inner Hash
  86. crypt.Reset()
  87. crypt.Write(stage1)
  88. hash := crypt.Sum(nil)
  89. // outer Hash
  90. crypt.Reset()
  91. crypt.Write(scramble)
  92. crypt.Write(hash)
  93. scramble = crypt.Sum(nil)
  94. // token = scrambleHash XOR stage1Hash
  95. for i := range scramble {
  96. scramble[i] ^= stage1[i]
  97. }
  98. return scramble
  99. }
  100. func parseDateTime(str string, loc *time.Location) (driver.Value, error) {
  101. var t time.Time
  102. var err error
  103. switch len(str) {
  104. case 10: // YYYY-MM-DD
  105. if str == "0000-00-00" {
  106. return time.Time{}, nil
  107. }
  108. t, err = time.Parse(timeFormat[:10], str)
  109. case 19: // YYYY-MM-DD HH:MM:SS
  110. if str == "0000-00-00 00:00:00" {
  111. return time.Time{}, nil
  112. }
  113. t, err = time.Parse(timeFormat, str)
  114. default:
  115. return nil, fmt.Errorf("Invalid Time-String: %s", str)
  116. }
  117. // Adjust location
  118. if err == nil && loc != time.UTC {
  119. y, mo, d := t.Date()
  120. h, mi, s := t.Clock()
  121. return time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil
  122. }
  123. return t, err
  124. }
  125. func parseBinaryDateTime(num uint64, data []byte, loc *time.Location) (driver.Value, error) {
  126. switch num {
  127. case 0:
  128. return time.Time{}, nil
  129. case 4:
  130. return time.Date(
  131. int(binary.LittleEndian.Uint16(data[:2])), // year
  132. time.Month(data[2]), // month
  133. int(data[3]), // day
  134. 0, 0, 0, 0,
  135. loc,
  136. ), nil
  137. case 7:
  138. return time.Date(
  139. int(binary.LittleEndian.Uint16(data[:2])), // year
  140. time.Month(data[2]), // month
  141. int(data[3]), // day
  142. int(data[4]), // hour
  143. int(data[5]), // minutes
  144. int(data[6]), // seconds
  145. 0,
  146. loc,
  147. ), nil
  148. case 11:
  149. return time.Date(
  150. int(binary.LittleEndian.Uint16(data[:2])), // year
  151. time.Month(data[2]), // month
  152. int(data[3]), // day
  153. int(data[4]), // hour
  154. int(data[5]), // minutes
  155. int(data[6]), // seconds
  156. int(binary.LittleEndian.Uint32(data[7:11]))*1000, // nanoseconds
  157. loc,
  158. ), nil
  159. }
  160. return nil, fmt.Errorf("Invalid DATETIME-packet length %d", num)
  161. }
  162. func formatBinaryDate(num uint64, data []byte) (driver.Value, error) {
  163. switch num {
  164. case 0:
  165. return []byte("0000-00-00"), nil
  166. case 4:
  167. return []byte(fmt.Sprintf(
  168. "%04d-%02d-%02d",
  169. binary.LittleEndian.Uint16(data[:2]),
  170. data[2],
  171. data[3],
  172. )), nil
  173. }
  174. return nil, fmt.Errorf("Invalid DATE-packet length %d", num)
  175. }
  176. func formatBinaryDateTime(num uint64, data []byte) (driver.Value, error) {
  177. switch num {
  178. case 0:
  179. return []byte("0000-00-00 00:00:00"), nil
  180. case 4:
  181. return []byte(fmt.Sprintf(
  182. "%04d-%02d-%02d 00:00:00",
  183. binary.LittleEndian.Uint16(data[:2]),
  184. data[2],
  185. data[3],
  186. )), nil
  187. case 7:
  188. return []byte(fmt.Sprintf(
  189. "%04d-%02d-%02d %02d:%02d:%02d",
  190. binary.LittleEndian.Uint16(data[:2]),
  191. data[2],
  192. data[3],
  193. data[4],
  194. data[5],
  195. data[6],
  196. )), nil
  197. case 11:
  198. return []byte(fmt.Sprintf(
  199. "%04d-%02d-%02d %02d:%02d:%02d.%06d",
  200. binary.LittleEndian.Uint16(data[:2]),
  201. data[2],
  202. data[3],
  203. data[4],
  204. data[5],
  205. data[6],
  206. binary.LittleEndian.Uint32(data[7:11]),
  207. )), nil
  208. }
  209. return nil, fmt.Errorf("Invalid DATETIME-packet length %d", num)
  210. }
  211. func readBool(value string) bool {
  212. switch strings.ToLower(value) {
  213. case "true":
  214. return true
  215. case "1":
  216. return true
  217. }
  218. return false
  219. }
  220. /******************************************************************************
  221. * Convert from and to bytes *
  222. ******************************************************************************/
  223. func uint64ToBytes(n uint64) []byte {
  224. return []byte{
  225. byte(n),
  226. byte(n >> 8),
  227. byte(n >> 16),
  228. byte(n >> 24),
  229. byte(n >> 32),
  230. byte(n >> 40),
  231. byte(n >> 48),
  232. byte(n >> 56),
  233. }
  234. }
  235. func uint64ToString(n uint64) []byte {
  236. var a [20]byte
  237. i := 20
  238. // U+0030 = 0
  239. // ...
  240. // U+0039 = 9
  241. var q uint64
  242. for n >= 10 {
  243. i--
  244. q = n / 10
  245. a[i] = uint8(n-q*10) + 0x30
  246. n = q
  247. }
  248. i--
  249. a[i] = uint8(n) + 0x30
  250. return a[i:]
  251. }
  252. // treats string value as unsigned integer representation
  253. func stringToInt(b []byte) int {
  254. val := 0
  255. for i := range b {
  256. val *= 10
  257. val += int(b[i] - 0x30)
  258. }
  259. return val
  260. }
  261. func readLengthEnodedString(b []byte) ([]byte, bool, int, error) {
  262. // Get length
  263. num, isNull, n := readLengthEncodedInteger(b)
  264. if num < 1 {
  265. return nil, isNull, n, nil
  266. }
  267. n += int(num)
  268. // Check data length
  269. if len(b) >= n {
  270. return b[n-int(num) : n], false, n, nil
  271. }
  272. return nil, false, n, io.EOF
  273. }
  274. func skipLengthEnodedString(b []byte) (int, error) {
  275. // Get length
  276. num, _, n := readLengthEncodedInteger(b)
  277. if num < 1 {
  278. return n, nil
  279. }
  280. n += int(num)
  281. // Check data length
  282. if len(b) >= n {
  283. return n, nil
  284. }
  285. return n, io.EOF
  286. }
  287. func readLengthEncodedInteger(b []byte) (num uint64, isNull bool, n int) {
  288. switch b[0] {
  289. // 251: NULL
  290. case 0xfb:
  291. n = 1
  292. isNull = true
  293. return
  294. // 252: value of following 2
  295. case 0xfc:
  296. num = uint64(b[1]) | uint64(b[2])<<8
  297. n = 3
  298. return
  299. // 253: value of following 3
  300. case 0xfd:
  301. num = uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16
  302. n = 4
  303. return
  304. // 254: value of following 8
  305. case 0xfe:
  306. num = uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16 |
  307. uint64(b[4])<<24 | uint64(b[5])<<32 | uint64(b[6])<<40 |
  308. uint64(b[7])<<48 | uint64(b[8])<<54
  309. n = 9
  310. return
  311. }
  312. // 0-250: value of first byte
  313. num = uint64(b[0])
  314. n = 1
  315. return
  316. }
  317. func lengthEncodedIntegerToBytes(n uint64) []byte {
  318. switch {
  319. case n <= 250:
  320. return []byte{byte(n)}
  321. case n <= 0xffff:
  322. return []byte{0xfc, byte(n), byte(n >> 8)}
  323. case n <= 0xffffff:
  324. return []byte{0xfd, byte(n), byte(n >> 8), byte(n >> 16)}
  325. }
  326. return nil
  327. }