PageRenderTime 1663ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/github.com/depechebot/depechebot/model/sqlite/sqlite.go

https://bitbucket.org/depechebot/pyjamabot
Go | 289 lines | 219 code | 54 blank | 16 comment | 57 complexity | 596d5ebc8cf059fff5e78583c3ab013f MD5 | raw file
Possible License(s): BSD-3-Clause
  1. package sqlite
  2. import (
  3. "database/sql"
  4. "encoding/json"
  5. "errors"
  6. dbot "github.com/depechebot/depechebot"
  7. )
  8. type Model struct {
  9. db *sql.DB
  10. //tableName string
  11. //chats []*dbot.Chat
  12. }
  13. func NewModel(db *sql.DB) Model {
  14. return Model{db: db}
  15. }
  16. // Init initializes model.
  17. // num is the number of existing chats.
  18. func (m Model) Init() (chatIDs []dbot.ChatID, err error) {
  19. err = m.db.Ping()
  20. if err != nil {
  21. return nil, err
  22. }
  23. // slowing this model down cause of this bug:
  24. // https://github.com/mattn/go-sqlite3/issues/274
  25. m.db.SetMaxOpenConns(1)
  26. err = m.createTable()
  27. if err != nil {
  28. return nil, err
  29. }
  30. const sqlstr = `SELECT chat_id from ` + `chat`
  31. q, err := m.db.Query(sqlstr)
  32. if err != nil {
  33. return nil, err
  34. }
  35. defer q.Close()
  36. var chatID dbot.ChatID
  37. chatIDs = []dbot.ChatID{}
  38. for q.Next() {
  39. err = q.Scan(&chatID)
  40. if err != nil {
  41. return nil, err
  42. }
  43. chatIDs = append(chatIDs, chatID)
  44. }
  45. return chatIDs, nil
  46. }
  47. func (m Model) createTable() error {
  48. var err error
  49. const sqlstr = `CREATE TABLE IF NOT EXISTS ` +
  50. `chat` +
  51. ` (
  52. primary_id INTEGER NOT NULL PRIMARY KEY,
  53. chat_id BIGINT UNIQUE NOT NULL,
  54. type TEXT NOT NULL,
  55. abandoned INTEGER NOT NULL,
  56. user_id INTEGER NOT NULL,
  57. user_name TEXT NOT NULL DEFAULT '',
  58. first_name TEXT NOT NULL,
  59. last_name TEXT NOT NULL,
  60. open_time DATETIME NOT NULL,
  61. last_time DATETIME NOT NULL,
  62. state TEXT NOT NULL,
  63. params TEXT NOT NULL
  64. );
  65. `
  66. _, err = m.db.Exec(sqlstr)
  67. return err
  68. }
  69. // Exists determines if the Chat exists in the database.
  70. func (m Model) Exists(c *dbot.Chat) (exists bool, err error) {
  71. var cnt int
  72. var sqlstr = `SELECT count(*) as count from ` + `chat` + ` where chat_id = ?`
  73. err = m.db.QueryRow(sqlstr, c.ChatID).Scan(&cnt)
  74. return cnt != 0, err
  75. }
  76. // Insert inserts chat to the database.
  77. // Sets c.PrimaryID.
  78. func (m Model) Insert(c *dbot.Chat) error {
  79. var err error
  80. const sqlstr = `INSERT INTO chat (` +
  81. `chat_id, type, abandoned, user_id, user_name, first_name, last_name, open_time, last_time, state, params` +
  82. `) VALUES (` +
  83. `?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?` +
  84. `)`
  85. state, err := json.Marshal(c.State)
  86. if err != nil {
  87. return err
  88. }
  89. params, err := json.Marshal(c.Params)
  90. if err != nil {
  91. return err
  92. }
  93. res, err := m.db.Exec(sqlstr, c.ChatID, c.Type, c.Abandoned, c.UserID, c.UserName,
  94. c.FirstName, c.LastName, c.OpenTime, c.LastTime, string(state), string(params))
  95. if err != nil {
  96. return err
  97. }
  98. id, err := res.LastInsertId()
  99. if err != nil {
  100. return err
  101. }
  102. c.PrimaryID = int(id)
  103. return nil
  104. }
  105. // Update updates the Chat in the database.
  106. func (m Model) Update(c *dbot.Chat) error {
  107. var err error
  108. const sqlstr = `UPDATE chat SET ` +
  109. `primary_id = ?, type = ?, abandoned = ?, user_id = ?, user_name = ?, first_name = ?, last_name = ?, open_time = ?, last_time = ?, state = ?, params = ?` +
  110. ` WHERE chat_id = ?`
  111. state, err := json.Marshal(c.State)
  112. if err != nil {
  113. return err
  114. }
  115. params, err := json.Marshal(c.Params)
  116. if err != nil {
  117. return err
  118. }
  119. _, err = m.db.Exec(sqlstr, c.PrimaryID, c.Type, c.Abandoned, c.UserID, c.UserName,
  120. c.FirstName, c.LastName, c.OpenTime, c.LastTime, string(state), string(params), c.ChatID)
  121. return err
  122. }
  123. // Save saves the Chat to the database.
  124. // Prefer Update() if you know that chat exists.
  125. func (m Model) Save(c *dbot.Chat) error {
  126. exists, err := m.Exists(c)
  127. if err != nil {
  128. return err
  129. }
  130. if exists {
  131. return m.Update(c)
  132. }
  133. return m.Insert(c)
  134. }
  135. // Delete deletes the Chat from the database.
  136. func (m Model) Delete(c *dbot.Chat) error {
  137. var err error
  138. const sqlstr = `DELETE FROM chat WHERE chat_id = ?`
  139. _, err = m.db.Exec(sqlstr, c.ChatID)
  140. return err
  141. }
  142. // ChatByPrimaryID retrieves a chat by primaryID.
  143. func (m Model) ChatByPrimaryID(primaryID int) (*dbot.Chat, error) {
  144. var err error
  145. var state, params string
  146. const sqlstr = `SELECT ` +
  147. `primary_id, chat_id, type, abandoned, user_id, user_name, first_name, last_name, open_time, last_time, state, params ` +
  148. `FROM chat ` +
  149. `WHERE primary_id = ?`
  150. c := dbot.Chat{}
  151. err = m.db.QueryRow(sqlstr, primaryID).Scan(&c.PrimaryID, &c.ChatID, &c.Type, &c.Abandoned, &c.UserID, &c.UserName,
  152. &c.FirstName, &c.LastName, &c.OpenTime, &c.LastTime, &state, &params)
  153. if err != nil {
  154. if err == sql.ErrNoRows {
  155. return nil, errors.New("chat not found (use Model.Exist() before if not sure)")
  156. } else {
  157. return nil, err
  158. }
  159. }
  160. err = json.Unmarshal([]byte(state), &c.State)
  161. if err != nil {
  162. return nil, err
  163. }
  164. err = json.Unmarshal([]byte(params), &c.Params)
  165. if err != nil {
  166. return nil, err
  167. }
  168. return &c, nil
  169. }
  170. // ChatByChatID retrieves a chat by chatID.
  171. func (m Model) ChatByChatID(chatID dbot.ChatID) (*dbot.Chat, error) {
  172. var err error
  173. var state, params string
  174. const sqlstr = `SELECT ` +
  175. `primary_id, chat_id, type, abandoned, user_id, user_name, first_name, last_name, open_time, last_time, state, params ` +
  176. `FROM chat ` +
  177. `WHERE chat_id = ?`
  178. c := dbot.Chat{}
  179. err = m.db.QueryRow(sqlstr, chatID).Scan(&c.PrimaryID, &c.ChatID, &c.Type, &c.Abandoned, &c.UserID, &c.UserName,
  180. &c.FirstName, &c.LastName, &c.OpenTime, &c.LastTime, &state, &params)
  181. if err != nil {
  182. if err == sql.ErrNoRows {
  183. return nil, errors.New("chat not found (use Model.Exist() before if not sure)")
  184. } else {
  185. return nil, err
  186. }
  187. }
  188. err = json.Unmarshal([]byte(state), &c.State)
  189. if err != nil {
  190. return nil, err
  191. }
  192. err = json.Unmarshal([]byte(params), &c.Params)
  193. if err != nil {
  194. return nil, err
  195. }
  196. return &c, nil
  197. }
  198. // ChatsByParam retrieves chats with chat.Params matching param.
  199. func (m Model) ChatsByParam(param string) ([]*dbot.Chat, error) {
  200. var err error
  201. var state, params string
  202. const sqlstr = `SELECT ` +
  203. `primary_id, chat_id, type, abandoned, user_id, user_name, first_name, last_name, open_time, last_time, state, params ` +
  204. `FROM chat ` +
  205. `WHERE ` +
  206. `params like "%" || ? || "%"`
  207. q, err := m.db.Query(sqlstr, param)
  208. if err != nil {
  209. if err == sql.ErrNoRows {
  210. return []*dbot.Chat{}, nil
  211. } else {
  212. return nil, err
  213. }
  214. }
  215. defer q.Close()
  216. chats := []*dbot.Chat{}
  217. for q.Next() {
  218. c := dbot.Chat{}
  219. err = q.Scan(&c.PrimaryID, &c.ChatID, &c.Type, &c.Abandoned, &c.UserID, &c.UserName,
  220. &c.FirstName, &c.LastName, &c.OpenTime, &c.LastTime, &state, &params)
  221. if err != nil {
  222. return nil, err
  223. }
  224. err = json.Unmarshal([]byte(state), &c.State)
  225. if err != nil {
  226. return nil, err
  227. }
  228. err = json.Unmarshal([]byte(params), &c.Params)
  229. if err != nil {
  230. return nil, err
  231. }
  232. chats = append(chats, &c)
  233. }
  234. return chats, nil
  235. }