sqlqueries.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. package dataprovider
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. "github.com/drakkan/sftpgo/v2/vfs"
  7. )
  8. const (
  9. selectUserFields = "id,username,password,public_keys,home_dir,uid,gid,max_sessions,quota_size,quota_files,permissions,used_quota_size," +
  10. "used_quota_files,last_quota_update,upload_bandwidth,download_bandwidth,expiration_date,last_login,status,filters,filesystem," +
  11. "additional_info,description"
  12. selectFolderFields = "id,path,used_quota_size,used_quota_files,last_quota_update,name,description,filesystem"
  13. selectAdminFields = "id,username,password,status,email,permissions,filters,additional_info,description"
  14. selectAPIKeyFields = "key_id,name,api_key,scope,created_at,updated_at,last_use_at,expires_at,description,user_id,admin_id"
  15. )
  16. func getSQLPlaceholders() []string {
  17. var placeholders []string
  18. for i := 1; i <= 20; i++ {
  19. if config.Driver == PGSQLDataProviderName || config.Driver == CockroachDataProviderName {
  20. placeholders = append(placeholders, fmt.Sprintf("$%v", i))
  21. } else {
  22. placeholders = append(placeholders, "?")
  23. }
  24. }
  25. return placeholders
  26. }
  27. func getAdminByUsernameQuery() string {
  28. return fmt.Sprintf(`SELECT %v FROM %v WHERE username = %v`, selectAdminFields, sqlTableAdmins, sqlPlaceholders[0])
  29. }
  30. func getAdminsQuery(order string) string {
  31. return fmt.Sprintf(`SELECT %v FROM %v ORDER BY username %v LIMIT %v OFFSET %v`, selectAdminFields, sqlTableAdmins,
  32. order, sqlPlaceholders[0], sqlPlaceholders[1])
  33. }
  34. func getDumpAdminsQuery() string {
  35. return fmt.Sprintf(`SELECT %v FROM %v`, selectAdminFields, sqlTableAdmins)
  36. }
  37. func getAddAdminQuery() string {
  38. return fmt.Sprintf(`INSERT INTO %v (username,password,status,email,permissions,filters,additional_info,description)
  39. VALUES (%v,%v,%v,%v,%v,%v,%v,%v)`, sqlTableAdmins, sqlPlaceholders[0], sqlPlaceholders[1],
  40. sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7])
  41. }
  42. func getUpdateAdminQuery() string {
  43. return fmt.Sprintf(`UPDATE %v SET password=%v,status=%v,email=%v,permissions=%v,filters=%v,additional_info=%v,description=%v
  44. WHERE username = %v`, sqlTableAdmins, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2],
  45. sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7])
  46. }
  47. func getDeleteAdminQuery() string {
  48. return fmt.Sprintf(`DELETE FROM %v WHERE username = %v`, sqlTableAdmins, sqlPlaceholders[0])
  49. }
  50. func getAPIKeyByIDQuery() string {
  51. return fmt.Sprintf(`SELECT %v FROM %v WHERE key_id = %v`, selectAPIKeyFields, sqlTableAPIKeys, sqlPlaceholders[0])
  52. }
  53. func getAPIKeysQuery(order string) string {
  54. return fmt.Sprintf(`SELECT %v FROM %v ORDER BY key_id %v LIMIT %v OFFSET %v`, selectAPIKeyFields, sqlTableAPIKeys,
  55. order, sqlPlaceholders[0], sqlPlaceholders[1])
  56. }
  57. func getDumpAPIKeysQuery() string {
  58. return fmt.Sprintf(`SELECT %v FROM %v`, selectAPIKeyFields, sqlTableAPIKeys)
  59. }
  60. func getAddAPIKeyQuery() string {
  61. return fmt.Sprintf(`INSERT INTO %v (key_id,name,api_key,scope,created_at,updated_at,last_use_at,expires_at,description,user_id,admin_id)
  62. VALUES (%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v)`, sqlTableAPIKeys, sqlPlaceholders[0], sqlPlaceholders[1],
  63. sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6],
  64. sqlPlaceholders[7], sqlPlaceholders[8], sqlPlaceholders[9], sqlPlaceholders[10])
  65. }
  66. func getUpdateAPIKeyQuery() string {
  67. return fmt.Sprintf(`UPDATE %v SET name=%v,scope=%v,expires_at=%v,user_id=%v,admin_id=%v,description=%v,updated_at=%v
  68. WHERE key_id = %v`, sqlTableAPIKeys, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2],
  69. sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7])
  70. }
  71. func getDeleteAPIKeyQuery() string {
  72. return fmt.Sprintf(`DELETE FROM %v WHERE key_id = %v`, sqlTableAPIKeys, sqlPlaceholders[0])
  73. }
  74. func getRelatedUsersForAPIKeysQuery(apiKeys []APIKey) string {
  75. var sb strings.Builder
  76. for _, k := range apiKeys {
  77. if k.userID == 0 {
  78. continue
  79. }
  80. if sb.Len() == 0 {
  81. sb.WriteString("(")
  82. } else {
  83. sb.WriteString(",")
  84. }
  85. sb.WriteString(strconv.FormatInt(k.userID, 10))
  86. }
  87. if sb.Len() > 0 {
  88. sb.WriteString(")")
  89. } else {
  90. sb.WriteString("(0)")
  91. }
  92. return fmt.Sprintf(`SELECT id,username FROM %v WHERE id IN %v`, sqlTableUsers, sb.String())
  93. }
  94. func getRelatedAdminsForAPIKeysQuery(apiKeys []APIKey) string {
  95. var sb strings.Builder
  96. for _, k := range apiKeys {
  97. if k.adminID == 0 {
  98. continue
  99. }
  100. if sb.Len() == 0 {
  101. sb.WriteString("(")
  102. } else {
  103. sb.WriteString(",")
  104. }
  105. sb.WriteString(strconv.FormatInt(k.adminID, 10))
  106. }
  107. if sb.Len() > 0 {
  108. sb.WriteString(")")
  109. } else {
  110. sb.WriteString("(0)")
  111. }
  112. return fmt.Sprintf(`SELECT id,username FROM %v WHERE id IN %v`, sqlTableAdmins, sb.String())
  113. }
  114. func getUserByUsernameQuery() string {
  115. return fmt.Sprintf(`SELECT %v FROM %v WHERE username = %v`, selectUserFields, sqlTableUsers, sqlPlaceholders[0])
  116. }
  117. func getUsersQuery(order string) string {
  118. return fmt.Sprintf(`SELECT %v FROM %v ORDER BY username %v LIMIT %v OFFSET %v`, selectUserFields, sqlTableUsers,
  119. order, sqlPlaceholders[0], sqlPlaceholders[1])
  120. }
  121. func getDumpUsersQuery() string {
  122. return fmt.Sprintf(`SELECT %v FROM %v`, selectUserFields, sqlTableUsers)
  123. }
  124. func getDumpFoldersQuery() string {
  125. return fmt.Sprintf(`SELECT %v FROM %v`, selectFolderFields, sqlTableFolders)
  126. }
  127. func getUpdateQuotaQuery(reset bool) string {
  128. if reset {
  129. return fmt.Sprintf(`UPDATE %v SET used_quota_size = %v,used_quota_files = %v,last_quota_update = %v
  130. WHERE username = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  131. }
  132. return fmt.Sprintf(`UPDATE %v SET used_quota_size = used_quota_size + %v,used_quota_files = used_quota_files + %v,last_quota_update = %v
  133. WHERE username = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  134. }
  135. func getUpdateLastLoginQuery() string {
  136. return fmt.Sprintf(`UPDATE %v SET last_login = %v WHERE username = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1])
  137. }
  138. func getUpdateAPIKeyLastUseQuery() string {
  139. return fmt.Sprintf(`UPDATE %v SET last_use_at = %v WHERE key_id = %v`, sqlTableAPIKeys, sqlPlaceholders[0], sqlPlaceholders[1])
  140. }
  141. func getQuotaQuery() string {
  142. return fmt.Sprintf(`SELECT used_quota_size,used_quota_files FROM %v WHERE username = %v`, sqlTableUsers,
  143. sqlPlaceholders[0])
  144. }
  145. func getAddUserQuery() string {
  146. return fmt.Sprintf(`INSERT INTO %v (username,password,public_keys,home_dir,uid,gid,max_sessions,quota_size,quota_files,permissions,
  147. used_quota_size,used_quota_files,last_quota_update,upload_bandwidth,download_bandwidth,status,last_login,expiration_date,filters,
  148. filesystem,additional_info,description)
  149. VALUES (%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,0,0,0,%v,%v,%v,0,%v,%v,%v,%v,%v)`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1],
  150. sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7],
  151. sqlPlaceholders[8], sqlPlaceholders[9], sqlPlaceholders[10], sqlPlaceholders[11], sqlPlaceholders[12], sqlPlaceholders[13],
  152. sqlPlaceholders[14], sqlPlaceholders[15], sqlPlaceholders[16], sqlPlaceholders[17])
  153. }
  154. func getUpdateUserQuery() string {
  155. return fmt.Sprintf(`UPDATE %v SET password=%v,public_keys=%v,home_dir=%v,uid=%v,gid=%v,max_sessions=%v,quota_size=%v,
  156. quota_files=%v,permissions=%v,upload_bandwidth=%v,download_bandwidth=%v,status=%v,expiration_date=%v,filters=%v,filesystem=%v,
  157. additional_info=%v,description=%v WHERE id = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3],
  158. sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7], sqlPlaceholders[8], sqlPlaceholders[9],
  159. sqlPlaceholders[10], sqlPlaceholders[11], sqlPlaceholders[12], sqlPlaceholders[13], sqlPlaceholders[14], sqlPlaceholders[15],
  160. sqlPlaceholders[16], sqlPlaceholders[17])
  161. }
  162. func getDeleteUserQuery() string {
  163. return fmt.Sprintf(`DELETE FROM %v WHERE id = %v`, sqlTableUsers, sqlPlaceholders[0])
  164. }
  165. func getFolderByNameQuery() string {
  166. return fmt.Sprintf(`SELECT %v FROM %v WHERE name = %v`, selectFolderFields, sqlTableFolders, sqlPlaceholders[0])
  167. }
  168. func checkFolderNameQuery() string {
  169. return fmt.Sprintf(`SELECT name FROM %v WHERE name = %v`, sqlTableFolders, sqlPlaceholders[0])
  170. }
  171. func getAddFolderQuery() string {
  172. return fmt.Sprintf(`INSERT INTO %v (path,used_quota_size,used_quota_files,last_quota_update,name,description,filesystem)
  173. VALUES (%v,%v,%v,%v,%v,%v,%v)`, sqlTableFolders, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2],
  174. sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6])
  175. }
  176. func getUpdateFolderQuery() string {
  177. return fmt.Sprintf(`UPDATE %v SET path=%v,description=%v,filesystem=%v WHERE name = %v`, sqlTableFolders, sqlPlaceholders[0],
  178. sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  179. }
  180. func getDeleteFolderQuery() string {
  181. return fmt.Sprintf(`DELETE FROM %v WHERE id = %v`, sqlTableFolders, sqlPlaceholders[0])
  182. }
  183. func getClearFolderMappingQuery() string {
  184. return fmt.Sprintf(`DELETE FROM %v WHERE user_id = (SELECT id FROM %v WHERE username = %v)`, sqlTableFoldersMapping,
  185. sqlTableUsers, sqlPlaceholders[0])
  186. }
  187. func getAddFolderMappingQuery() string {
  188. return fmt.Sprintf(`INSERT INTO %v (virtual_path,quota_size,quota_files,folder_id,user_id)
  189. VALUES (%v,%v,%v,%v,(SELECT id FROM %v WHERE username = %v))`, sqlTableFoldersMapping, sqlPlaceholders[0],
  190. sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3], sqlTableUsers, sqlPlaceholders[4])
  191. }
  192. func getFoldersQuery(order string) string {
  193. return fmt.Sprintf(`SELECT %v FROM %v ORDER BY name %v LIMIT %v OFFSET %v`, selectFolderFields, sqlTableFolders,
  194. order, sqlPlaceholders[0], sqlPlaceholders[1])
  195. }
  196. func getUpdateFolderQuotaQuery(reset bool) string {
  197. if reset {
  198. return fmt.Sprintf(`UPDATE %v SET used_quota_size = %v,used_quota_files = %v,last_quota_update = %v
  199. WHERE name = %v`, sqlTableFolders, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  200. }
  201. return fmt.Sprintf(`UPDATE %v SET used_quota_size = used_quota_size + %v,used_quota_files = used_quota_files + %v,last_quota_update = %v
  202. WHERE name = %v`, sqlTableFolders, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  203. }
  204. func getQuotaFolderQuery() string {
  205. return fmt.Sprintf(`SELECT used_quota_size,used_quota_files FROM %v WHERE name = %v`, sqlTableFolders,
  206. sqlPlaceholders[0])
  207. }
  208. func getRelatedFoldersForUsersQuery(users []User) string {
  209. var sb strings.Builder
  210. for _, u := range users {
  211. if sb.Len() == 0 {
  212. sb.WriteString("(")
  213. } else {
  214. sb.WriteString(",")
  215. }
  216. sb.WriteString(strconv.FormatInt(u.ID, 10))
  217. }
  218. if sb.Len() > 0 {
  219. sb.WriteString(")")
  220. }
  221. return fmt.Sprintf(`SELECT f.id,f.name,f.path,f.used_quota_size,f.used_quota_files,f.last_quota_update,fm.virtual_path,
  222. fm.quota_size,fm.quota_files,fm.user_id,f.filesystem,f.description FROM %v f INNER JOIN %v fm ON f.id = fm.folder_id WHERE
  223. fm.user_id IN %v ORDER BY fm.user_id`, sqlTableFolders, sqlTableFoldersMapping, sb.String())
  224. }
  225. func getRelatedUsersForFoldersQuery(folders []vfs.BaseVirtualFolder) string {
  226. var sb strings.Builder
  227. for _, f := range folders {
  228. if sb.Len() == 0 {
  229. sb.WriteString("(")
  230. } else {
  231. sb.WriteString(",")
  232. }
  233. sb.WriteString(strconv.FormatInt(f.ID, 10))
  234. }
  235. if sb.Len() > 0 {
  236. sb.WriteString(")")
  237. }
  238. return fmt.Sprintf(`SELECT fm.folder_id,u.username FROM %v fm INNER JOIN %v u ON fm.user_id = u.id
  239. WHERE fm.folder_id IN %v ORDER BY fm.folder_id`, sqlTableFoldersMapping, sqlTableUsers, sb.String())
  240. }
  241. func getDatabaseVersionQuery() string {
  242. return fmt.Sprintf("SELECT version from %v LIMIT 1", sqlTableSchemaVersion)
  243. }
  244. func getUpdateDBVersionQuery() string {
  245. return fmt.Sprintf(`UPDATE %v SET version=%v`, sqlTableSchemaVersion, sqlPlaceholders[0])
  246. }