2 import java.nio.file.*;
8 static final boolean CONFIG_PRINT_DB = false;
9 static final String CSV_SEPARATOR = ",";
10 static final String DB_URL = "jdbc:postgresql:migration";
11 static final String SQL_GET_USERS = "SELECT * FROM users;";
12 static final String SQL_UPSERT_USER =
14 INSERT INTO users VALUES (?, ?, ?, ?, ?)
18 CAN_READ = EXCLUDED.CAN_READ,
19 CAN_WRITE = EXCLUDED.CAN_WRITE,
20 CAN_DELETE = EXCLUDED.CAN_DELETE
27 public record Role(boolean read, boolean write, boolean delete) {
28 static final Role Default = new Role(false, false, false);
31 public record User(int id, String mail, Role role) {
32 public String toString() {
33 return this.id + " " + this.mail + " " + this.role;
40 public static String[][] LoadCSV(String filename) throws IOException {
41 var path = Paths.get(filename);
42 return Files.lines(path)
44 .map(line -> line.split(CSV_SEPARATOR))
45 .toArray(String[][]::new);
51 public static void insertUser(PreparedStatement stmt, User user) throws SQLException {
52 stmt.setInt(1, user.id);
53 stmt.setString(2, user.mail);
54 stmt.setBoolean(3, user.role.read);
55 stmt.setBoolean(4, user.role.write);
56 stmt.setBoolean(5, user.role.delete);
62 static User[] getUsers(Connection conn) throws SQLException {
63 var users = new ArrayList<User>();
65 try (var st = conn.createStatement();
66 var rs = st.executeQuery(SQL_GET_USERS); ) {
68 var userId = rs.getInt(1);
69 var userMail = rs.getString(2);
70 var userRole = new Role(rs.getBoolean(3), rs.getBoolean(4), rs.getBoolean(5));
71 users.add(new User(userId, userMail, userRole));
75 return users.toArray(User[]::new);
81 public static void main(String[] args) {
82 // filenames from command line args {{{
83 if (args.length != 2) {
84 System.out.printf("Usage: java src/DbMigrations.java <users.csv> <roles.csv>\n");
87 String filenameUsers = args[0];
88 String filenameRoles = args[1];
95 csvUsers = LoadCSV(filenameUsers);
96 csvRoles = LoadCSV(filenameRoles);
97 } catch (IOException e) {
98 System.out.printf("Expection occured while trying to load CSV: %s\n", e);
104 var roles = new HashMap<Integer, Role>();
105 for (var row : csvRoles) {
106 // get id and single role
107 var userId = Integer.parseInt(row[0], 10);
108 var roleStr = row[1];
110 // make sure userId is present
111 roles.putIfAbsent(userId, Role.Default);
113 // update value by setting one role to true and copying the rest
114 roles.computeIfPresent(
117 if (roleStr.equals("read")) return new Role(true, role.write, role.delete);
118 if (roleStr.equals("write")) return new Role(role.read, true, role.delete);
119 if (roleStr.equals("delete")) return new Role(role.read, role.write, true);
125 // OPTIONAL: open db connection for reading {{{
126 if (CONFIG_PRINT_DB) {
127 try (var conn = DriverManager.getConnection(DB_URL)) {
129 var users = getUsers(conn);
130 System.out.println("Before update:");
131 for (var user : users) {
132 System.out.println(user);
135 } catch (SQLException e) {
136 System.out.printf("Expection occured while accessing database: %s\n", e);
142 // open db connection for updating {{{
143 try (var conn = DriverManager.getConnection(DB_URL);
144 var stmt = conn.prepareStatement(SQL_UPSERT_USER); ) {
147 conn.setAutoCommit(false);
149 // update db from csv
150 for (var row : csvUsers) {
151 var userId = Integer.parseInt(row[0], 10);
152 var userMail = row[1];
153 var userRoles = roles.get(userId);
155 User user = new User(userId, userMail, userRoles);
156 insertUser(stmt, user);
163 } catch (SQLException e) {
164 System.out.printf("Expection occured while accessing database: %s\n", e);
169 System.out.println("Updated successfully");