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:users";
11 static final String SQL_GET_USERS = "SELECT * FROM users;";
12 static final String SQL_UPSERT_USER =
14 INSERT INTO users VALUES (?, ?, ?, ?, ?)
18 CanRead = EXCLUDED.CanRead,
19 CanWrite = EXCLUDED.CanWrite,
20 CanDelete = EXCLUDED.CanDelete
26 public record User(int id, String mail, Role role) {
27 public String toString() {
28 return this.id + " " + this.mail + " " + this.role;
34 public record Role(boolean read, boolean write, boolean delete) {
35 static final Role Default = new Role(false, false, false);
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);
50 public static void insertUser(PreparedStatement stmt, User user) throws SQLException {
51 stmt.setInt(1, user.id);
52 stmt.setString(2, user.mail);
53 stmt.setBoolean(3, user.role.read);
54 stmt.setBoolean(4, user.role.write);
55 stmt.setBoolean(5, user.role.delete);
61 static User[] getUsers(Connection conn) throws SQLException {
62 var users = new ArrayList<User>();
64 try (var st = conn.createStatement();
65 var rs = st.executeQuery(SQL_GET_USERS); ) {
67 var userId = rs.getInt(1);
68 var userMail = rs.getString(2);
69 var userRole = new Role(rs.getBoolean(3), rs.getBoolean(4), rs.getBoolean(5));
70 users.add(new User(userId, userMail, userRole));
74 return users.toArray(User[]::new);
79 public static void main(String[] args) {
80 // filenames from command line args {{{
81 if (args.length != 2) {
82 System.out.printf("Usage: java src/DbMigrations.java <users.csv> <roles.csv>\n");
85 String filenameUsers = args[0];
86 String filenameRoles = args[1];
93 csvUsers = LoadCSV(filenameUsers);
94 csvRoles = LoadCSV(filenameRoles);
95 } catch (IOException e) {
96 System.out.printf("Expection occured while trying to load CSV: %s\n", e);
102 var roles = new HashMap<Integer, Role>();
103 for (var row : csvRoles) {
104 // get id and single role
105 var userId = Integer.parseInt(row[0], 10);
106 var roleStr = row[1];
108 // make sure userId is present
109 roles.putIfAbsent(userId, Role.Default);
111 // update value by setting one role to true and copying the rest
112 roles.computeIfPresent(
115 if (roleStr.equals("read")) return new Role(true, role.write, role.delete);
116 if (roleStr.equals("write")) return new Role(role.read, true, role.delete);
117 if (roleStr.equals("delete")) return new Role(role.read, role.write, true);
123 // OPTIONAL: open db connection for reading {{{
124 if (CONFIG_PRINT_DB) {
125 try (var conn = DriverManager.getConnection(DB_URL)) {
127 var users = getUsers(conn);
128 System.out.println("DB before update:");
129 for (var user : users) {
130 System.out.println(user);
133 } catch (SQLException e) {
134 System.out.printf("Expection occured while accessing database: %s\n", e);
140 // open db connection for updating {{{
141 try (var conn = DriverManager.getConnection(DB_URL);
142 var stmt = conn.prepareStatement(SQL_UPSERT_USER); ) {
144 conn.setAutoCommit(false);
146 // update db from csv
147 for (var row : csvUsers) {
148 var userId = Integer.parseInt(row[0], 10);
149 var userMail = row[1];
150 var userRoles = roles.get(userId);
152 User user = new User(userId, userMail, userRoles);
153 insertUser(stmt, user);
159 } catch (SQLException e) {
160 System.out.printf("Expection occured while accessing database: %s\n", e);
165 System.out.println("Updated successfully");