sqlqueries.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. // Copyright (C) 2019-2022 Nicola Murino
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU Affero General Public License as published
  5. // by the Free Software Foundation, version 3.
  6. //
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU Affero General Public License for more details.
  11. //
  12. // You should have received a copy of the GNU Affero General Public License
  13. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. package dataprovider
  15. import (
  16. "fmt"
  17. "strconv"
  18. "strings"
  19. "github.com/drakkan/sftpgo/v2/vfs"
  20. )
  21. const (
  22. selectUserFields = "id,username,password,public_keys,home_dir,uid,gid,max_sessions,quota_size,quota_files,permissions,used_quota_size," +
  23. "used_quota_files,last_quota_update,upload_bandwidth,download_bandwidth,expiration_date,last_login,status,filters,filesystem," +
  24. "additional_info,description,email,created_at,updated_at,upload_data_transfer,download_data_transfer,total_data_transfer," +
  25. "used_upload_data_transfer,used_download_data_transfer"
  26. selectFolderFields = "id,path,used_quota_size,used_quota_files,last_quota_update,name,description,filesystem"
  27. selectAdminFields = "id,username,password,status,email,permissions,filters,additional_info,description,created_at,updated_at,last_login"
  28. selectAPIKeyFields = "key_id,name,api_key,scope,created_at,updated_at,last_use_at,expires_at,description,user_id,admin_id"
  29. selectShareFields = "s.share_id,s.name,s.description,s.scope,s.paths,u.username,s.created_at,s.updated_at,s.last_use_at," +
  30. "s.expires_at,s.password,s.max_tokens,s.used_tokens,s.allow_from"
  31. selectGroupFields = "id,name,description,created_at,updated_at,user_settings"
  32. )
  33. func getSQLPlaceholders() []string {
  34. var placeholders []string
  35. for i := 1; i <= 50; i++ {
  36. if config.Driver == PGSQLDataProviderName || config.Driver == CockroachDataProviderName {
  37. placeholders = append(placeholders, fmt.Sprintf("$%v", i))
  38. } else {
  39. placeholders = append(placeholders, "?")
  40. }
  41. }
  42. return placeholders
  43. }
  44. func getSQLTableGroups() string {
  45. if config.Driver == MySQLDataProviderName {
  46. return fmt.Sprintf("`%s`", sqlTableGroups)
  47. }
  48. return sqlTableGroups
  49. }
  50. func getAddSessionQuery() string {
  51. if config.Driver == MySQLDataProviderName {
  52. return fmt.Sprintf("INSERT INTO %s (`key`,`data`,`type`,`timestamp`) VALUES (%s,%s,%s,%s) "+
  53. "ON DUPLICATE KEY UPDATE `data`=VALUES(`data`), `timestamp`=VALUES(`timestamp`)",
  54. sqlTableSharedSessions, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  55. }
  56. return fmt.Sprintf(`INSERT INTO %s (key,data,type,timestamp) VALUES (%s,%s,%s,%s) ON CONFLICT(key) DO UPDATE SET data=
  57. EXCLUDED.data, timestamp=EXCLUDED.timestamp`,
  58. sqlTableSharedSessions, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  59. }
  60. func getDeleteSessionQuery() string {
  61. if config.Driver == MySQLDataProviderName {
  62. return fmt.Sprintf("DELETE FROM %s WHERE `key` = %s", sqlTableSharedSessions, sqlPlaceholders[0])
  63. }
  64. return fmt.Sprintf(`DELETE FROM %s WHERE key = %s`, sqlTableSharedSessions, sqlPlaceholders[0])
  65. }
  66. func getSessionQuery() string {
  67. if config.Driver == MySQLDataProviderName {
  68. return fmt.Sprintf("SELECT `key`,`data`,`type`,`timestamp` FROM %s WHERE `key` = %s", sqlTableSharedSessions,
  69. sqlPlaceholders[0])
  70. }
  71. return fmt.Sprintf(`SELECT key,data,type,timestamp FROM %s WHERE key = %s`, sqlTableSharedSessions,
  72. sqlPlaceholders[0])
  73. }
  74. func getCleanupSessionsQuery() string {
  75. return fmt.Sprintf(`DELETE from %s WHERE type = %s AND timestamp < %s`,
  76. sqlTableSharedSessions, sqlPlaceholders[0], sqlPlaceholders[1])
  77. }
  78. func getAddDefenderHostQuery() string {
  79. if config.Driver == MySQLDataProviderName {
  80. return fmt.Sprintf("INSERT INTO %v (`ip`,`updated_at`,`ban_time`) VALUES (%v,%v,0) ON DUPLICATE KEY UPDATE `updated_at`=VALUES(`updated_at`)",
  81. sqlTableDefenderHosts, sqlPlaceholders[0], sqlPlaceholders[1])
  82. }
  83. return fmt.Sprintf(`INSERT INTO %v (ip,updated_at,ban_time) VALUES (%v,%v,0) ON CONFLICT (ip) DO UPDATE SET updated_at = EXCLUDED.updated_at RETURNING id`,
  84. sqlTableDefenderHosts, sqlPlaceholders[0], sqlPlaceholders[1])
  85. }
  86. func getAddDefenderEventQuery() string {
  87. return fmt.Sprintf(`INSERT INTO %v (date_time,score,host_id) VALUES (%v,%v,(SELECT id from %v WHERE ip = %v))`,
  88. sqlTableDefenderEvents, sqlPlaceholders[0], sqlPlaceholders[1], sqlTableDefenderHosts, sqlPlaceholders[2])
  89. }
  90. func getDefenderHostsQuery() string {
  91. return fmt.Sprintf(`SELECT id,ip,ban_time FROM %v WHERE updated_at >= %v OR ban_time > 0 ORDER BY updated_at DESC LIMIT %v`,
  92. sqlTableDefenderHosts, sqlPlaceholders[0], sqlPlaceholders[1])
  93. }
  94. func getDefenderHostQuery() string {
  95. return fmt.Sprintf(`SELECT id,ip,ban_time FROM %v WHERE ip = %v AND (updated_at >= %v OR ban_time > 0)`,
  96. sqlTableDefenderHosts, sqlPlaceholders[0], sqlPlaceholders[1])
  97. }
  98. func getDefenderEventsQuery(hostIDS []int64) string {
  99. var sb strings.Builder
  100. for _, hID := range hostIDS {
  101. if sb.Len() == 0 {
  102. sb.WriteString("(")
  103. } else {
  104. sb.WriteString(",")
  105. }
  106. sb.WriteString(strconv.FormatInt(hID, 10))
  107. }
  108. if sb.Len() > 0 {
  109. sb.WriteString(")")
  110. } else {
  111. sb.WriteString("(0)")
  112. }
  113. return fmt.Sprintf(`SELECT host_id,SUM(score) FROM %v WHERE date_time >= %v AND host_id IN %v GROUP BY host_id`,
  114. sqlTableDefenderEvents, sqlPlaceholders[0], sb.String())
  115. }
  116. func getDefenderIsHostBannedQuery() string {
  117. return fmt.Sprintf(`SELECT id FROM %v WHERE ip = %v AND ban_time >= %v`,
  118. sqlTableDefenderHosts, sqlPlaceholders[0], sqlPlaceholders[1])
  119. }
  120. func getDefenderIncrementBanTimeQuery() string {
  121. return fmt.Sprintf(`UPDATE %v SET ban_time = ban_time + %v WHERE ip = %v`,
  122. sqlTableDefenderHosts, sqlPlaceholders[0], sqlPlaceholders[1])
  123. }
  124. func getDefenderSetBanTimeQuery() string {
  125. return fmt.Sprintf(`UPDATE %v SET ban_time = %v WHERE ip = %v`,
  126. sqlTableDefenderHosts, sqlPlaceholders[0], sqlPlaceholders[1])
  127. }
  128. func getDeleteDefenderHostQuery() string {
  129. return fmt.Sprintf(`DELETE FROM %v WHERE ip = %v`, sqlTableDefenderHosts, sqlPlaceholders[0])
  130. }
  131. func getDefenderHostsCleanupQuery() string {
  132. return fmt.Sprintf(`DELETE FROM %v WHERE ban_time < %v AND NOT EXISTS (
  133. SELECT id FROM %v WHERE %v.host_id = %v.id AND %v.date_time > %v)`,
  134. sqlTableDefenderHosts, sqlPlaceholders[0], sqlTableDefenderEvents, sqlTableDefenderEvents, sqlTableDefenderHosts,
  135. sqlTableDefenderEvents, sqlPlaceholders[1])
  136. }
  137. func getDefenderEventsCleanupQuery() string {
  138. return fmt.Sprintf(`DELETE FROM %v WHERE date_time < %v`, sqlTableDefenderEvents, sqlPlaceholders[0])
  139. }
  140. func getGroupByNameQuery() string {
  141. return fmt.Sprintf(`SELECT %s FROM %s WHERE name = %s`, selectGroupFields, getSQLTableGroups(), sqlPlaceholders[0])
  142. }
  143. func getGroupsQuery(order string, minimal bool) string {
  144. var fieldSelection string
  145. if minimal {
  146. fieldSelection = "id,name"
  147. } else {
  148. fieldSelection = selectGroupFields
  149. }
  150. return fmt.Sprintf(`SELECT %s FROM %s ORDER BY name %s LIMIT %v OFFSET %v`, fieldSelection, getSQLTableGroups(),
  151. order, sqlPlaceholders[0], sqlPlaceholders[1])
  152. }
  153. func getGroupsWithNamesQuery(numArgs int) string {
  154. var sb strings.Builder
  155. for idx := 0; idx < numArgs; idx++ {
  156. if sb.Len() == 0 {
  157. sb.WriteString("(")
  158. } else {
  159. sb.WriteString(",")
  160. }
  161. sb.WriteString(sqlPlaceholders[idx])
  162. }
  163. if sb.Len() > 0 {
  164. sb.WriteString(")")
  165. } else {
  166. sb.WriteString("('')")
  167. }
  168. return fmt.Sprintf(`SELECT %s FROM %s WHERE name in %s`, selectGroupFields, getSQLTableGroups(), sb.String())
  169. }
  170. func getUsersInGroupsQuery(numArgs int) string {
  171. var sb strings.Builder
  172. for idx := 0; idx < numArgs; idx++ {
  173. if sb.Len() == 0 {
  174. sb.WriteString("(")
  175. } else {
  176. sb.WriteString(",")
  177. }
  178. sb.WriteString(sqlPlaceholders[idx])
  179. }
  180. if sb.Len() > 0 {
  181. sb.WriteString(")")
  182. } else {
  183. sb.WriteString("('')")
  184. }
  185. return fmt.Sprintf(`SELECT username FROM %s WHERE id IN (SELECT user_id from %s WHERE group_id IN (SELECT id FROM %s WHERE name IN (%s)))`,
  186. sqlTableUsers, sqlTableUsersGroupsMapping, getSQLTableGroups(), sb.String())
  187. }
  188. func getDumpGroupsQuery() string {
  189. return fmt.Sprintf(`SELECT %s FROM %s`, selectGroupFields, getSQLTableGroups())
  190. }
  191. func getAddGroupQuery() string {
  192. return fmt.Sprintf(`INSERT INTO %s (name,description,created_at,updated_at,user_settings)
  193. VALUES (%v,%v,%v,%v,%v)`, getSQLTableGroups(), sqlPlaceholders[0], sqlPlaceholders[1],
  194. sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4])
  195. }
  196. func getUpdateGroupQuery() string {
  197. return fmt.Sprintf(`UPDATE %s SET description=%v,user_settings=%v,updated_at=%v
  198. WHERE name = %s`, getSQLTableGroups(), sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2],
  199. sqlPlaceholders[3])
  200. }
  201. func getDeleteGroupQuery() string {
  202. return fmt.Sprintf(`DELETE FROM %s WHERE name = %s`, getSQLTableGroups(), sqlPlaceholders[0])
  203. }
  204. func getAdminByUsernameQuery() string {
  205. return fmt.Sprintf(`SELECT %v FROM %v WHERE username = %v`, selectAdminFields, sqlTableAdmins, sqlPlaceholders[0])
  206. }
  207. func getAdminsQuery(order string) string {
  208. return fmt.Sprintf(`SELECT %v FROM %v ORDER BY username %v LIMIT %v OFFSET %v`, selectAdminFields, sqlTableAdmins,
  209. order, sqlPlaceholders[0], sqlPlaceholders[1])
  210. }
  211. func getDumpAdminsQuery() string {
  212. return fmt.Sprintf(`SELECT %v FROM %v`, selectAdminFields, sqlTableAdmins)
  213. }
  214. func getAddAdminQuery() string {
  215. return fmt.Sprintf(`INSERT INTO %v (username,password,status,email,permissions,filters,additional_info,description,created_at,updated_at,last_login)
  216. VALUES (%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,0)`, sqlTableAdmins, sqlPlaceholders[0], sqlPlaceholders[1],
  217. sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7],
  218. sqlPlaceholders[8], sqlPlaceholders[9])
  219. }
  220. func getUpdateAdminQuery() string {
  221. return fmt.Sprintf(`UPDATE %v SET password=%v,status=%v,email=%v,permissions=%v,filters=%v,additional_info=%v,description=%v,updated_at=%v
  222. WHERE username = %v`, sqlTableAdmins, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2],
  223. sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7], sqlPlaceholders[8])
  224. }
  225. func getDeleteAdminQuery() string {
  226. return fmt.Sprintf(`DELETE FROM %v WHERE username = %v`, sqlTableAdmins, sqlPlaceholders[0])
  227. }
  228. func getShareByIDQuery(filterUser bool) string {
  229. if filterUser {
  230. return fmt.Sprintf(`SELECT %v FROM %v s INNER JOIN %v u ON s.user_id = u.id WHERE s.share_id = %v AND u.username = %v`,
  231. selectShareFields, sqlTableShares, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1])
  232. }
  233. return fmt.Sprintf(`SELECT %v FROM %v s INNER JOIN %v u ON s.user_id = u.id WHERE s.share_id = %v`,
  234. selectShareFields, sqlTableShares, sqlTableUsers, sqlPlaceholders[0])
  235. }
  236. func getSharesQuery(order string) string {
  237. return fmt.Sprintf(`SELECT %v FROM %v s INNER JOIN %v u ON s.user_id = u.id WHERE u.username = %v ORDER BY s.share_id %v LIMIT %v OFFSET %v`,
  238. selectShareFields, sqlTableShares, sqlTableUsers, sqlPlaceholders[0], order, sqlPlaceholders[1], sqlPlaceholders[2])
  239. }
  240. func getDumpSharesQuery() string {
  241. return fmt.Sprintf(`SELECT %v FROM %v s INNER JOIN %v u ON s.user_id = u.id`,
  242. selectShareFields, sqlTableShares, sqlTableUsers)
  243. }
  244. func getAddShareQuery() string {
  245. return fmt.Sprintf(`INSERT INTO %v (share_id,name,description,scope,paths,created_at,updated_at,last_use_at,
  246. expires_at,password,max_tokens,used_tokens,allow_from,user_id) VALUES (%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v)`,
  247. sqlTableShares, sqlPlaceholders[0], sqlPlaceholders[1],
  248. sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6],
  249. sqlPlaceholders[7], sqlPlaceholders[8], sqlPlaceholders[9], sqlPlaceholders[10], sqlPlaceholders[11],
  250. sqlPlaceholders[12], sqlPlaceholders[13])
  251. }
  252. func getUpdateShareRestoreQuery() string {
  253. return fmt.Sprintf(`UPDATE %v SET name=%v,description=%v,scope=%v,paths=%v,created_at=%v,updated_at=%v,
  254. last_use_at=%v,expires_at=%v,password=%v,max_tokens=%v,used_tokens=%v,allow_from=%v,user_id=%v WHERE share_id = %v`, sqlTableShares,
  255. sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4],
  256. sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7], sqlPlaceholders[8], sqlPlaceholders[9],
  257. sqlPlaceholders[10], sqlPlaceholders[11], sqlPlaceholders[12], sqlPlaceholders[13])
  258. }
  259. func getUpdateShareQuery() string {
  260. return fmt.Sprintf(`UPDATE %v SET name=%v,description=%v,scope=%v,paths=%v,updated_at=%v,expires_at=%v,
  261. password=%v,max_tokens=%v,allow_from=%v,user_id=%v WHERE share_id = %v`, sqlTableShares,
  262. sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4],
  263. sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7], sqlPlaceholders[8], sqlPlaceholders[9],
  264. sqlPlaceholders[10])
  265. }
  266. func getDeleteShareQuery() string {
  267. return fmt.Sprintf(`DELETE FROM %v WHERE share_id = %v`, sqlTableShares, sqlPlaceholders[0])
  268. }
  269. func getAPIKeyByIDQuery() string {
  270. return fmt.Sprintf(`SELECT %v FROM %v WHERE key_id = %v`, selectAPIKeyFields, sqlTableAPIKeys, sqlPlaceholders[0])
  271. }
  272. func getAPIKeysQuery(order string) string {
  273. return fmt.Sprintf(`SELECT %v FROM %v ORDER BY key_id %v LIMIT %v OFFSET %v`, selectAPIKeyFields, sqlTableAPIKeys,
  274. order, sqlPlaceholders[0], sqlPlaceholders[1])
  275. }
  276. func getDumpAPIKeysQuery() string {
  277. return fmt.Sprintf(`SELECT %v FROM %v`, selectAPIKeyFields, sqlTableAPIKeys)
  278. }
  279. func getAddAPIKeyQuery() string {
  280. 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)
  281. VALUES (%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v)`, sqlTableAPIKeys, sqlPlaceholders[0], sqlPlaceholders[1],
  282. sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6],
  283. sqlPlaceholders[7], sqlPlaceholders[8], sqlPlaceholders[9], sqlPlaceholders[10])
  284. }
  285. func getUpdateAPIKeyQuery() string {
  286. return fmt.Sprintf(`UPDATE %v SET name=%v,scope=%v,expires_at=%v,user_id=%v,admin_id=%v,description=%v,updated_at=%v
  287. WHERE key_id = %v`, sqlTableAPIKeys, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2],
  288. sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7])
  289. }
  290. func getDeleteAPIKeyQuery() string {
  291. return fmt.Sprintf(`DELETE FROM %v WHERE key_id = %v`, sqlTableAPIKeys, sqlPlaceholders[0])
  292. }
  293. func getRelatedUsersForAPIKeysQuery(apiKeys []APIKey) string {
  294. var sb strings.Builder
  295. for _, k := range apiKeys {
  296. if k.userID == 0 {
  297. continue
  298. }
  299. if sb.Len() == 0 {
  300. sb.WriteString("(")
  301. } else {
  302. sb.WriteString(",")
  303. }
  304. sb.WriteString(strconv.FormatInt(k.userID, 10))
  305. }
  306. if sb.Len() > 0 {
  307. sb.WriteString(")")
  308. } else {
  309. sb.WriteString("(0)")
  310. }
  311. return fmt.Sprintf(`SELECT id,username FROM %v WHERE id IN %v`, sqlTableUsers, sb.String())
  312. }
  313. func getRelatedAdminsForAPIKeysQuery(apiKeys []APIKey) string {
  314. var sb strings.Builder
  315. for _, k := range apiKeys {
  316. if k.adminID == 0 {
  317. continue
  318. }
  319. if sb.Len() == 0 {
  320. sb.WriteString("(")
  321. } else {
  322. sb.WriteString(",")
  323. }
  324. sb.WriteString(strconv.FormatInt(k.adminID, 10))
  325. }
  326. if sb.Len() > 0 {
  327. sb.WriteString(")")
  328. } else {
  329. sb.WriteString("(0)")
  330. }
  331. return fmt.Sprintf(`SELECT id,username FROM %v WHERE id IN %v`, sqlTableAdmins, sb.String())
  332. }
  333. func getUserByUsernameQuery() string {
  334. return fmt.Sprintf(`SELECT %v FROM %v WHERE username = %v`, selectUserFields, sqlTableUsers, sqlPlaceholders[0])
  335. }
  336. func getUsersQuery(order string) string {
  337. return fmt.Sprintf(`SELECT %v FROM %v ORDER BY username %v LIMIT %v OFFSET %v`, selectUserFields, sqlTableUsers,
  338. order, sqlPlaceholders[0], sqlPlaceholders[1])
  339. }
  340. func getUsersForQuotaCheckQuery(numArgs int) string {
  341. var sb strings.Builder
  342. for idx := 0; idx < numArgs; idx++ {
  343. if sb.Len() == 0 {
  344. sb.WriteString("(")
  345. } else {
  346. sb.WriteString(",")
  347. }
  348. sb.WriteString(sqlPlaceholders[idx])
  349. }
  350. if sb.Len() > 0 {
  351. sb.WriteString(")")
  352. }
  353. return fmt.Sprintf(`SELECT id,username,quota_size,used_quota_size,total_data_transfer,upload_data_transfer,
  354. download_data_transfer,used_upload_data_transfer,used_download_data_transfer,filters FROM %v WHERE username IN %v`,
  355. sqlTableUsers, sb.String())
  356. }
  357. func getRecentlyUpdatedUsersQuery() string {
  358. return fmt.Sprintf(`SELECT %v FROM %v WHERE updated_at >= %v`, selectUserFields, sqlTableUsers, sqlPlaceholders[0])
  359. }
  360. func getDumpUsersQuery() string {
  361. return fmt.Sprintf(`SELECT %v FROM %v`, selectUserFields, sqlTableUsers)
  362. }
  363. func getDumpFoldersQuery() string {
  364. return fmt.Sprintf(`SELECT %v FROM %v`, selectFolderFields, sqlTableFolders)
  365. }
  366. func getUpdateTransferQuotaQuery(reset bool) string {
  367. if reset {
  368. return fmt.Sprintf(`UPDATE %v SET used_upload_data_transfer = %v,used_download_data_transfer = %v,last_quota_update = %v
  369. WHERE username = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  370. }
  371. return fmt.Sprintf(`UPDATE %v SET used_upload_data_transfer = used_upload_data_transfer + %v,
  372. used_download_data_transfer = used_download_data_transfer + %v,last_quota_update = %v
  373. WHERE username = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  374. }
  375. func getUpdateQuotaQuery(reset bool) string {
  376. if reset {
  377. return fmt.Sprintf(`UPDATE %v SET used_quota_size = %v,used_quota_files = %v,last_quota_update = %v
  378. WHERE username = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  379. }
  380. return fmt.Sprintf(`UPDATE %v SET used_quota_size = used_quota_size + %v,used_quota_files = used_quota_files + %v,last_quota_update = %v
  381. WHERE username = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  382. }
  383. func getSetUpdateAtQuery() string {
  384. return fmt.Sprintf(`UPDATE %v SET updated_at = %v WHERE username = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1])
  385. }
  386. func getUpdateLastLoginQuery() string {
  387. return fmt.Sprintf(`UPDATE %v SET last_login = %v WHERE username = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1])
  388. }
  389. func getUpdateAdminLastLoginQuery() string {
  390. return fmt.Sprintf(`UPDATE %v SET last_login = %v WHERE username = %v`, sqlTableAdmins, sqlPlaceholders[0], sqlPlaceholders[1])
  391. }
  392. func getUpdateAPIKeyLastUseQuery() string {
  393. return fmt.Sprintf(`UPDATE %v SET last_use_at = %v WHERE key_id = %v`, sqlTableAPIKeys, sqlPlaceholders[0], sqlPlaceholders[1])
  394. }
  395. func getUpdateShareLastUseQuery() string {
  396. return fmt.Sprintf(`UPDATE %v SET last_use_at = %v, used_tokens = used_tokens +%v WHERE share_id = %v`,
  397. sqlTableShares, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2])
  398. }
  399. func getQuotaQuery() string {
  400. return fmt.Sprintf(`SELECT used_quota_size,used_quota_files,used_upload_data_transfer,
  401. used_download_data_transfer FROM %v WHERE username = %v`,
  402. sqlTableUsers, sqlPlaceholders[0])
  403. }
  404. func getAddUserQuery() string {
  405. return fmt.Sprintf(`INSERT INTO %v (username,password,public_keys,home_dir,uid,gid,max_sessions,quota_size,quota_files,permissions,
  406. used_quota_size,used_quota_files,last_quota_update,upload_bandwidth,download_bandwidth,status,last_login,expiration_date,filters,
  407. filesystem,additional_info,description,email,created_at,updated_at,upload_data_transfer,download_data_transfer,total_data_transfer,
  408. used_upload_data_transfer,used_download_data_transfer)
  409. VALUES (%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,0,0,0,%v,%v,%v,0,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,0,0)`,
  410. sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4],
  411. sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7], sqlPlaceholders[8], sqlPlaceholders[9],
  412. sqlPlaceholders[10], sqlPlaceholders[11], sqlPlaceholders[12], sqlPlaceholders[13], sqlPlaceholders[14],
  413. sqlPlaceholders[15], sqlPlaceholders[16], sqlPlaceholders[17], sqlPlaceholders[18], sqlPlaceholders[19],
  414. sqlPlaceholders[20], sqlPlaceholders[21], sqlPlaceholders[22], sqlPlaceholders[23])
  415. }
  416. func getUpdateUserQuery() string {
  417. return fmt.Sprintf(`UPDATE %v SET password=%v,public_keys=%v,home_dir=%v,uid=%v,gid=%v,max_sessions=%v,quota_size=%v,
  418. quota_files=%v,permissions=%v,upload_bandwidth=%v,download_bandwidth=%v,status=%v,expiration_date=%v,filters=%v,filesystem=%v,
  419. additional_info=%v,description=%v,email=%v,updated_at=%v,upload_data_transfer=%v,download_data_transfer=%v,
  420. total_data_transfer=%v WHERE id = %v`,
  421. sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4],
  422. sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7], sqlPlaceholders[8], sqlPlaceholders[9],
  423. sqlPlaceholders[10], sqlPlaceholders[11], sqlPlaceholders[12], sqlPlaceholders[13], sqlPlaceholders[14],
  424. sqlPlaceholders[15], sqlPlaceholders[16], sqlPlaceholders[17], sqlPlaceholders[18], sqlPlaceholders[19],
  425. sqlPlaceholders[20], sqlPlaceholders[21], sqlPlaceholders[22])
  426. }
  427. func getUpdateUserPasswordQuery() string {
  428. return fmt.Sprintf(`UPDATE %v SET password=%v WHERE username = %v`, sqlTableUsers, sqlPlaceholders[0], sqlPlaceholders[1])
  429. }
  430. func getDeleteUserQuery() string {
  431. return fmt.Sprintf(`DELETE FROM %v WHERE id = %v`, sqlTableUsers, sqlPlaceholders[0])
  432. }
  433. func getFolderByNameQuery() string {
  434. return fmt.Sprintf(`SELECT %v FROM %v WHERE name = %v`, selectFolderFields, sqlTableFolders, sqlPlaceholders[0])
  435. }
  436. func getAddFolderQuery() string {
  437. return fmt.Sprintf(`INSERT INTO %v (path,used_quota_size,used_quota_files,last_quota_update,name,description,filesystem)
  438. VALUES (%v,%v,%v,%v,%v,%v,%v)`, sqlTableFolders, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2],
  439. sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6])
  440. }
  441. func getUpdateFolderQuery() string {
  442. return fmt.Sprintf(`UPDATE %v SET path=%v,description=%v,filesystem=%v WHERE name = %v`, sqlTableFolders, sqlPlaceholders[0],
  443. sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  444. }
  445. func getDeleteFolderQuery() string {
  446. return fmt.Sprintf(`DELETE FROM %v WHERE id = %v`, sqlTableFolders, sqlPlaceholders[0])
  447. }
  448. func getUpsertFolderQuery() string {
  449. if config.Driver == MySQLDataProviderName {
  450. return fmt.Sprintf("INSERT INTO %v (`path`,`used_quota_size`,`used_quota_files`,`last_quota_update`,`name`,"+
  451. "`description`,`filesystem`) VALUES (%v,%v,%v,%v,%v,%v,%v) ON DUPLICATE KEY UPDATE "+
  452. "`path`=VALUES(`path`),`description`=VALUES(`description`),`filesystem`=VALUES(`filesystem`)",
  453. sqlTableFolders, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4],
  454. sqlPlaceholders[5], sqlPlaceholders[6])
  455. }
  456. return fmt.Sprintf(`INSERT INTO %v (path,used_quota_size,used_quota_files,last_quota_update,name,description,filesystem)
  457. VALUES (%v,%v,%v,%v,%v,%v,%v) ON CONFLICT (name) DO UPDATE SET path = EXCLUDED.path,description=EXCLUDED.description,
  458. filesystem=EXCLUDED.filesystem`, sqlTableFolders, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2],
  459. sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6])
  460. }
  461. func getClearUserGroupMappingQuery() string {
  462. return fmt.Sprintf(`DELETE FROM %v WHERE user_id = (SELECT id FROM %v WHERE username = %v)`, sqlTableUsersGroupsMapping,
  463. sqlTableUsers, sqlPlaceholders[0])
  464. }
  465. func getAddUserGroupMappingQuery() string {
  466. return fmt.Sprintf(`INSERT INTO %v (user_id,group_id,group_type) VALUES ((SELECT id FROM %v WHERE username = %v),
  467. (SELECT id FROM %v WHERE name = %v),%v)`,
  468. sqlTableUsersGroupsMapping, sqlTableUsers, sqlPlaceholders[0], getSQLTableGroups(), sqlPlaceholders[1], sqlPlaceholders[2])
  469. }
  470. func getClearGroupFolderMappingQuery() string {
  471. return fmt.Sprintf(`DELETE FROM %v WHERE group_id = (SELECT id FROM %v WHERE name = %v)`, sqlTableGroupsFoldersMapping,
  472. getSQLTableGroups(), sqlPlaceholders[0])
  473. }
  474. func getAddGroupFolderMappingQuery() string {
  475. return fmt.Sprintf(`INSERT INTO %v (virtual_path,quota_size,quota_files,folder_id,group_id)
  476. VALUES (%v,%v,%v,(SELECT id FROM %v WHERE name = %v),(SELECT id FROM %v WHERE name = %v))`,
  477. sqlTableGroupsFoldersMapping, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlTableFolders,
  478. sqlPlaceholders[3], getSQLTableGroups(), sqlPlaceholders[4])
  479. }
  480. func getClearUserFolderMappingQuery() string {
  481. return fmt.Sprintf(`DELETE FROM %v WHERE user_id = (SELECT id FROM %v WHERE username = %v)`, sqlTableUsersFoldersMapping,
  482. sqlTableUsers, sqlPlaceholders[0])
  483. }
  484. func getAddUserFolderMappingQuery() string {
  485. return fmt.Sprintf(`INSERT INTO %v (virtual_path,quota_size,quota_files,folder_id,user_id)
  486. VALUES (%v,%v,%v,(SELECT id FROM %v WHERE name = %v),(SELECT id FROM %v WHERE username = %v))`,
  487. sqlTableUsersFoldersMapping, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlTableFolders,
  488. sqlPlaceholders[3], sqlTableUsers, sqlPlaceholders[4])
  489. }
  490. func getFoldersQuery(order string, minimal bool) string {
  491. var fieldSelection string
  492. if minimal {
  493. fieldSelection = "id,name"
  494. } else {
  495. fieldSelection = selectFolderFields
  496. }
  497. return fmt.Sprintf(`SELECT %v FROM %v ORDER BY name %v LIMIT %v OFFSET %v`, fieldSelection, sqlTableFolders,
  498. order, sqlPlaceholders[0], sqlPlaceholders[1])
  499. }
  500. func getUpdateFolderQuotaQuery(reset bool) string {
  501. if reset {
  502. return fmt.Sprintf(`UPDATE %v SET used_quota_size = %v,used_quota_files = %v,last_quota_update = %v
  503. WHERE name = %v`, sqlTableFolders, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  504. }
  505. return fmt.Sprintf(`UPDATE %v SET used_quota_size = used_quota_size + %v,used_quota_files = used_quota_files + %v,last_quota_update = %v
  506. WHERE name = %v`, sqlTableFolders, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3])
  507. }
  508. func getQuotaFolderQuery() string {
  509. return fmt.Sprintf(`SELECT used_quota_size,used_quota_files FROM %v WHERE name = %v`, sqlTableFolders,
  510. sqlPlaceholders[0])
  511. }
  512. func getRelatedGroupsForUsersQuery(users []User) string {
  513. var sb strings.Builder
  514. for _, u := range users {
  515. if sb.Len() == 0 {
  516. sb.WriteString("(")
  517. } else {
  518. sb.WriteString(",")
  519. }
  520. sb.WriteString(strconv.FormatInt(u.ID, 10))
  521. }
  522. if sb.Len() > 0 {
  523. sb.WriteString(")")
  524. }
  525. return fmt.Sprintf(`SELECT g.name,ug.group_type,ug.user_id FROM %v g INNER JOIN %v ug ON g.id = ug.group_id WHERE
  526. ug.user_id IN %v ORDER BY ug.user_id`, getSQLTableGroups(), sqlTableUsersGroupsMapping, sb.String())
  527. }
  528. func getRelatedFoldersForUsersQuery(users []User) string {
  529. var sb strings.Builder
  530. for _, u := range users {
  531. if sb.Len() == 0 {
  532. sb.WriteString("(")
  533. } else {
  534. sb.WriteString(",")
  535. }
  536. sb.WriteString(strconv.FormatInt(u.ID, 10))
  537. }
  538. if sb.Len() > 0 {
  539. sb.WriteString(")")
  540. }
  541. 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,
  542. 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
  543. fm.user_id IN %v ORDER BY fm.user_id`, sqlTableFolders, sqlTableUsersFoldersMapping, sb.String())
  544. }
  545. func getRelatedUsersForFoldersQuery(folders []vfs.BaseVirtualFolder) string {
  546. var sb strings.Builder
  547. for _, f := range folders {
  548. if sb.Len() == 0 {
  549. sb.WriteString("(")
  550. } else {
  551. sb.WriteString(",")
  552. }
  553. sb.WriteString(strconv.FormatInt(f.ID, 10))
  554. }
  555. if sb.Len() > 0 {
  556. sb.WriteString(")")
  557. }
  558. return fmt.Sprintf(`SELECT fm.folder_id,u.username FROM %v fm INNER JOIN %v u ON fm.user_id = u.id
  559. WHERE fm.folder_id IN %v ORDER BY fm.folder_id`, sqlTableUsersFoldersMapping, sqlTableUsers, sb.String())
  560. }
  561. func getRelatedGroupsForFoldersQuery(folders []vfs.BaseVirtualFolder) string {
  562. var sb strings.Builder
  563. for _, f := range folders {
  564. if sb.Len() == 0 {
  565. sb.WriteString("(")
  566. } else {
  567. sb.WriteString(",")
  568. }
  569. sb.WriteString(strconv.FormatInt(f.ID, 10))
  570. }
  571. if sb.Len() > 0 {
  572. sb.WriteString(")")
  573. }
  574. return fmt.Sprintf(`SELECT fm.folder_id,g.name FROM %v fm INNER JOIN %v g ON fm.group_id = g.id
  575. WHERE fm.folder_id IN %v ORDER BY fm.folder_id`, sqlTableGroupsFoldersMapping, getSQLTableGroups(), sb.String())
  576. }
  577. func getRelatedUsersForGroupsQuery(groups []Group) string {
  578. var sb strings.Builder
  579. for _, g := range groups {
  580. if sb.Len() == 0 {
  581. sb.WriteString("(")
  582. } else {
  583. sb.WriteString(",")
  584. }
  585. sb.WriteString(strconv.FormatInt(g.ID, 10))
  586. }
  587. if sb.Len() > 0 {
  588. sb.WriteString(")")
  589. }
  590. return fmt.Sprintf(`SELECT um.group_id,u.username FROM %v um INNER JOIN %v u ON um.user_id = u.id
  591. WHERE um.group_id IN %v ORDER BY um.group_id`, sqlTableUsersGroupsMapping, sqlTableUsers, sb.String())
  592. }
  593. func getRelatedFoldersForGroupsQuery(groups []Group) string {
  594. var sb strings.Builder
  595. for _, g := range groups {
  596. if sb.Len() == 0 {
  597. sb.WriteString("(")
  598. } else {
  599. sb.WriteString(",")
  600. }
  601. sb.WriteString(strconv.FormatInt(g.ID, 10))
  602. }
  603. if sb.Len() > 0 {
  604. sb.WriteString(")")
  605. }
  606. 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,
  607. fm.quota_size,fm.quota_files,fm.group_id,f.filesystem,f.description FROM %s f INNER JOIN %s fm ON f.id = fm.folder_id WHERE
  608. fm.group_id IN %v ORDER BY fm.group_id`, sqlTableFolders, sqlTableGroupsFoldersMapping, sb.String())
  609. }
  610. func getActiveTransfersQuery() string {
  611. return fmt.Sprintf(`SELECT transfer_id,connection_id,transfer_type,username,folder_name,ip,truncated_size,
  612. current_ul_size,current_dl_size,created_at,updated_at FROM %v WHERE updated_at > %v`,
  613. sqlTableActiveTransfers, sqlPlaceholders[0])
  614. }
  615. func getAddActiveTransferQuery() string {
  616. return fmt.Sprintf(`INSERT INTO %v (transfer_id,connection_id,transfer_type,username,folder_name,ip,truncated_size,
  617. current_ul_size,current_dl_size,created_at,updated_at) VALUES (%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v)`,
  618. sqlTableActiveTransfers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3],
  619. sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6], sqlPlaceholders[7], sqlPlaceholders[8],
  620. sqlPlaceholders[9], sqlPlaceholders[10])
  621. }
  622. func getUpdateActiveTransferSizesQuery() string {
  623. return fmt.Sprintf(`UPDATE %v SET current_ul_size=%v,current_dl_size=%v,updated_at=%v WHERE connection_id = %v AND transfer_id = %v`,
  624. sqlTableActiveTransfers, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4])
  625. }
  626. func getRemoveActiveTransferQuery() string {
  627. return fmt.Sprintf(`DELETE FROM %v WHERE connection_id = %v AND transfer_id = %v`,
  628. sqlTableActiveTransfers, sqlPlaceholders[0], sqlPlaceholders[1])
  629. }
  630. func getCleanupActiveTransfersQuery() string {
  631. return fmt.Sprintf(`DELETE FROM %v WHERE updated_at < %v`, sqlTableActiveTransfers, sqlPlaceholders[0])
  632. }
  633. func getDatabaseVersionQuery() string {
  634. return fmt.Sprintf("SELECT version from %v LIMIT 1", sqlTableSchemaVersion)
  635. }
  636. func getUpdateDBVersionQuery() string {
  637. return fmt.Sprintf(`UPDATE %v SET version=%v`, sqlTableSchemaVersion, sqlPlaceholders[0])
  638. }