DatabaseResource.java 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package org.ssssssss.magicapi.adapter.resource;
  2. import org.springframework.jdbc.core.JdbcTemplate;
  3. import org.springframework.jdbc.support.rowset.SqlRowSet;
  4. import org.ssssssss.magicapi.adapter.Resource;
  5. import java.nio.charset.StandardCharsets;
  6. import java.util.*;
  7. import java.util.concurrent.ConcurrentHashMap;
  8. import java.util.function.Function;
  9. import java.util.stream.Collectors;
  10. public class DatabaseResource extends KeyValueResource {
  11. private final JdbcTemplate template;
  12. private final String tableName;
  13. private Map<String, String> cachedContent = new ConcurrentHashMap<>();
  14. public DatabaseResource(JdbcTemplate template, String tableName, String separator, String path, boolean readonly, KeyValueResource parent) {
  15. super(separator, path, readonly, parent);
  16. this.template = template;
  17. this.tableName = tableName;
  18. }
  19. public DatabaseResource(JdbcTemplate template, String tableName, String separator, String path, boolean readonly, Map<String, String> cachedContent, KeyValueResource parent) {
  20. this(template, tableName, separator, path, readonly, parent);
  21. this.cachedContent = cachedContent;
  22. }
  23. @Override
  24. public byte[] read() {
  25. String value = this.cachedContent.get(path);
  26. if (value == null) {
  27. String sql = String.format("select file_content from %s where file_path = ?", tableName);
  28. value = template.queryForObject(sql, String.class, this.path);
  29. }
  30. return value == null ? new byte[0] : value.getBytes(StandardCharsets.UTF_8);
  31. }
  32. @Override
  33. public void readAll() {
  34. this.cachedContent.clear();
  35. String sql = String.format("select file_path, file_content from %s where file_path like '%s%%'", tableName, this.path);
  36. SqlRowSet sqlRowSet = template.queryForRowSet(sql);
  37. while (sqlRowSet.next()) {
  38. this.cachedContent.put(sqlRowSet.getString(1), sqlRowSet.getString(2));
  39. }
  40. }
  41. @Override
  42. public boolean exists() {
  43. if (this.cachedContent.containsKey(this.path)) {
  44. return true;
  45. }
  46. String sql = String.format("select count(*) from %s where file_path = ?", tableName);
  47. Long value = template.queryForObject(sql, Long.class, this.path);
  48. return value != null && value > 0;
  49. }
  50. @Override
  51. public boolean write(String content) {
  52. String sql = String.format("update %s set file_content = ? where file_path = ?", tableName);
  53. if (exists()) {
  54. if (template.update(sql, content, this.path) > 0) {
  55. this.cachedContent.put(this.path, content);
  56. return true;
  57. }
  58. }
  59. sql = String.format("insert into %s (file_path,file_content) values(?,?)", tableName);
  60. if (template.update(sql, this.path, content) > 0) {
  61. this.cachedContent.put(this.path, content);
  62. return true;
  63. }
  64. return false;
  65. }
  66. @Override
  67. public Set<String> keys() {
  68. String sql = String.format("select file_path from %s where file_path like '%s%%'", tableName, isDirectory() ? this.path : (this.path + separator));
  69. return new HashSet<>(template.queryForList(sql, String.class));
  70. }
  71. @Override
  72. public boolean renameTo(Map<String, String> renameKeys) {
  73. List<Object[]> args = renameKeys.entrySet().stream().map(entry -> new Object[]{entry.getValue(), entry.getKey()}).collect(Collectors.toList());
  74. String sql = String.format("update %s set file_path = ? where file_path = ?", tableName);
  75. if (Arrays.stream(template.batchUpdate(sql, args)).sum() > 0) {
  76. renameKeys.forEach((oldKey, newKey) -> this.cachedContent.put(newKey, this.cachedContent.remove(oldKey)));
  77. return true;
  78. }
  79. return false;
  80. }
  81. @Override
  82. public boolean delete() {
  83. String sql = String.format("delete from %s where file_path = ? or file_path like '%s%%'", tableName, isDirectory() ? this.path : this.path + separator);
  84. if (template.update(sql, this.path) > 0) {
  85. this.cachedContent.remove(this.path);
  86. return true;
  87. }
  88. return false;
  89. }
  90. @Override
  91. public Function<String, Resource> mappedFunction() {
  92. return it -> new DatabaseResource(template, tableName, separator, it, readonly, this.cachedContent, this);
  93. }
  94. @Override
  95. public String toString() {
  96. return String.format("db://%s/%s", tableName, Objects.toString(this.path, ""));
  97. }
  98. }