· 8 years ago · Dec 27, 2017, 04:18 PM
1package org.diablitozzz.backend.db.pg;
2
3import java.net.URI;
4import java.nio.charset.StandardCharsets;
5import java.util.HashSet;
6import java.util.List;
7import java.util.Set;
8import java.util.stream.Collectors;
9
10import javax.annotation.concurrent.ThreadSafe;
11
12import org.diablitozzz.backend.db.Db;
13import org.diablitozzz.backend.db.DbException;
14import org.diablitozzz.backend.db.DbVersions;
15import org.diablitozzz.backend.utils.ClassLoaderUtils;
16import org.diablitozzz.backend.utils.IOUtils;
17import org.diablitozzz.backend.utils.ObjectUtils;
18
19@ThreadSafe
20public class DbVersionsPg implements DbVersions {
21
22 protected static class Version implements Comparable<Version> {
23
24 public final long version;
25 public final URI uri;
26
27 public Version(final URI uri, final long version) {
28 this.uri = uri;
29 this.version = version;
30 }
31
32 @Override
33 public int compareTo(final Version o) {
34 return Long.compare(version, o.version);
35 }
36
37 @Override
38 public boolean equals(final Object obj) {
39 return ObjectUtils.equals(this, obj, b -> ObjectUtils.equals(version, b.version));
40 }
41
42 @Override
43 public int hashCode() {
44 return ObjectUtils.hashCode(version);
45 }
46
47 public String loadContent() throws Exception {
48 final byte[] blob = IOUtils.inputStreamToByteArray(uri.toURL().openStream(), 1024 * 1024);
49 return new String(blob, StandardCharsets.UTF_8).trim();
50 }
51
52 @Override
53 public String toString() {
54 return uri.toString();
55 }
56
57 }
58
59 private final Db db;
60 private final String path;
61 private final String tableName;
62
63 public DbVersionsPg(final Db db, final String tableName, final String path) {
64 this.db = db;
65 this.path = path;
66 this.tableName = tableName;
67 }
68
69 @Override
70 public void close() {
71 }
72
73 public Set<Version> loadVersions() throws Exception {
74
75 final Set<URI> uris = ClassLoaderUtils.listResourceDir(Thread.currentThread().getContextClassLoader(), path);
76 final Set<Version> versions = new HashSet<>(64);
77 for (final URI uri : uris) {
78 if (uri.getPath().endsWith("/")) {
79 continue;
80 }
81 final String[] items = uri.toURL().toExternalForm().split("/");
82 final String file = items[items.length - 1];
83 final long version = Long.valueOf(file.split("[\\.\\-\\_]")[0].trim());
84 versions.add(new Version(uri, version));
85 }
86 return versions;
87 }
88
89 @Override
90 public void up() throws DbException {
91 try {
92
93 db.exec(ctx -> ctx.exec(String.format(
94 "CREATE TABLE IF NOT EXISTS %s (version bigint NOT NULL PRIMARY KEY,created timestamp(0) with time zone NOT NULL DEFAULT now())",
95 tableName)));
96
97 final long lastVersion = db.select(ctx -> ctx
98 .select(String.format("SELECT COALESCE((SELECT MAX(version) FROM %s), 0)", tableName))
99 .first()
100 .get(0, Long.class));
101
102 final List<Version> versionsForUp = loadVersions().stream()
103 .filter(v -> lastVersion == 0 ? true : v.version > lastVersion)
104 .sorted()
105 .collect(Collectors.toList());
106
107 for (final Version version : versionsForUp) {
108 db.execT(ctx -> {
109 ctx.exec(version.loadContent());
110 ctx.exec(String.format("INSERT INTO %s (version,created) VALUES(?, NOW())", tableName), version.version);
111 });
112 }
113 } catch (final Exception e) {
114 throw DbException.create(e);
115 }
116 }
117
118}