SQLite support - work in progress
This commit is contained in:
parent
e43df2feca
commit
48bac8b5f5
@ -1,5 +1,6 @@
|
||||
package org.nanoboot.utils.timecalc.app;
|
||||
|
||||
import java.io.File;
|
||||
import org.nanoboot.utils.timecalc.entity.Visibility;
|
||||
import org.nanoboot.utils.timecalc.swing.common.MainWindow;
|
||||
import org.nanoboot.utils.timecalc.utils.common.Constants;
|
||||
@ -9,6 +10,14 @@ import org.nanoboot.utils.timecalc.utils.property.StringProperty;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.nanoboot.utils.timecalc.persistence.api.VersionRepositoryApi;
|
||||
import org.nanoboot.utils.timecalc.persistence.impl.sqlite.SqliteConnectionFactory;
|
||||
import org.nanoboot.utils.timecalc.persistence.impl.sqlite.VersionRepositorySQLiteImpl;
|
||||
|
||||
/**
|
||||
* @author Robert Vokac
|
||||
@ -29,6 +38,11 @@ public class TimeCalcApp {
|
||||
if (!FileConstants.TC_DIRECTORY.exists()) {
|
||||
FileConstants.TC_DIRECTORY.mkdir();
|
||||
}
|
||||
try {
|
||||
initDB();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
while (true) {
|
||||
boolean test = FileConstants.TEST_TXT.exists();
|
||||
String oldStartTime = Utils.readTextFromFile(
|
||||
@ -99,4 +113,54 @@ public class TimeCalcApp {
|
||||
return System.nanoTime() - startNanoTime;
|
||||
}
|
||||
|
||||
private void initDB() {
|
||||
SqliteConnectionFactory sqliteConnectionFactory = new SqliteConnectionFactory();
|
||||
try {
|
||||
Connection conn = sqliteConnectionFactory.createConnection();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
Logger.getLogger(TimeCalcApp.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new TimeCalcException(ex);
|
||||
}
|
||||
List<String> files;
|
||||
try {
|
||||
|
||||
files = Utils.loadFilesFromJarResources(DB_MIGRATIONSQLITETIMECALC, getClass());
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(TimeCalcApp.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new TimeCalcException(ex);
|
||||
}
|
||||
Collections.sort(files);
|
||||
int lastVersion = 0;
|
||||
VersionRepositoryApi versionRepository = new VersionRepositorySQLiteImpl(sqliteConnectionFactory);
|
||||
int currentVersion = 0;
|
||||
try {
|
||||
currentVersion = versionRepository.read();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("currentVersion=" + currentVersion);
|
||||
for(String sql :files) {
|
||||
Integer version = Integer.valueOf(sql.split("__")[0].substring(1));
|
||||
lastVersion = version;
|
||||
System.out.println("version=" + version);
|
||||
if(currentVersion >= version) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
System.out.println("Reading this file: " + DB_MIGRATIONSQLITETIMECALC + "/" + sql);
|
||||
String text = Utils.readTextFromTextResourceInJar(DB_MIGRATIONSQLITETIMECALC + "/" + sql);
|
||||
System.out.println("Found sql: \n\n" + text);
|
||||
sqliteConnectionFactory.runSQL(text);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(TimeCalcApp.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new TimeCalcException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
if(currentVersion != lastVersion) {
|
||||
versionRepository.update(lastVersion);
|
||||
}
|
||||
}
|
||||
private static final String DB_MIGRATIONSQLITETIMECALC = "db_migrations/sqlite/timecalc";
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.nanoboot.utils.timecalc.app;
|
||||
|
||||
import org.nanoboot.utils.timecalc.utils.common.Utils;
|
||||
|
||||
/**
|
||||
* @author Robert Vokac
|
||||
* @since 21.02.2024
|
||||
@ -8,9 +10,11 @@ public class TimeCalcException extends RuntimeException {
|
||||
|
||||
public TimeCalcException(String msg) {
|
||||
super(msg);
|
||||
Utils.showNotification("Error happened: " + msg);
|
||||
}
|
||||
|
||||
public TimeCalcException(Exception e) {
|
||||
super(e);
|
||||
Utils.showNotification("Error happened: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ public class WorkingDay {
|
||||
private int overtimeHour;
|
||||
private int overtimeMinute;
|
||||
|
||||
private boolean halfDay;
|
||||
private int workingTimeInMinutes;
|
||||
private int pauseTimeInMinutes;
|
||||
private String note;
|
||||
|
@ -0,0 +1,13 @@
|
||||
package org.nanoboot.utils.timecalc.persistence.api;
|
||||
|
||||
/**
|
||||
* @author Robert Vokac
|
||||
* @since 23.02.2024
|
||||
*/
|
||||
public interface VersionRepositoryApi {
|
||||
|
||||
int read();
|
||||
|
||||
void update(int newVersion);
|
||||
|
||||
}
|
@ -23,7 +23,9 @@ import org.nanoboot.utils.timecalc.utils.common.FileConstants;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import org.nanoboot.utils.timecalc.app.TimeCalcException;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -34,14 +36,14 @@ public class SqliteConnectionFactory implements ConnectionFactory {
|
||||
private final String jdbcUrl;
|
||||
|
||||
private static String createJdbcUrl(String directoryWhereSqliteFileIs) {
|
||||
return "jdbc:sqlite:" + directoryWhereSqliteFileIs + "/" + ".time-calc.sqlite3?foreign_keys=on;";
|
||||
return "jdbc:sqlite:" + directoryWhereSqliteFileIs + "/" + "time-calc.sqlite3?foreign_keys=on;";
|
||||
}
|
||||
|
||||
public SqliteConnectionFactory() {
|
||||
this(FileConstants.TC_DIRECTORY.getName());
|
||||
}
|
||||
|
||||
public SqliteConnectionFactory(String directoryWhereSqliteFileIs) {
|
||||
private SqliteConnectionFactory(String directoryWhereSqliteFileIs) {
|
||||
this.jdbcUrl = createJdbcUrl(directoryWhereSqliteFileIs);
|
||||
}
|
||||
|
||||
@ -61,5 +63,29 @@ public class SqliteConnectionFactory implements ConnectionFactory {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public void runSQL(String sql) {
|
||||
String[] array = sql.split(";");
|
||||
|
||||
for (String s : array) {
|
||||
if (s.trim().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
System.err.println("Going to run this SQL \"" + s + "\"");
|
||||
try (
|
||||
Connection connection = createConnection(); PreparedStatement stmt = connection.prepareStatement(s);) {
|
||||
|
||||
System.err.println(stmt.toString());
|
||||
stmt.execute();
|
||||
|
||||
} catch (SQLException e) {
|
||||
System.out.println(e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
ex.printStackTrace();
|
||||
throw new TimeCalcException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,83 @@
|
||||
package org.nanoboot.utils.timecalc.persistence.impl.sqlite;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import org.nanoboot.utils.timecalc.app.TimeCalcException;
|
||||
import org.nanoboot.utils.timecalc.persistence.api.VersionRepositoryApi;
|
||||
|
||||
/**
|
||||
* @author Robert Vokac
|
||||
* @since 23.02.2024
|
||||
*/
|
||||
public class VersionRepositorySQLiteImpl implements VersionRepositoryApi {
|
||||
|
||||
private final SqliteConnectionFactory sqliteConnectionFactory;
|
||||
|
||||
public VersionRepositorySQLiteImpl(SqliteConnectionFactory sqliteConnectionFactory) {
|
||||
this.sqliteConnectionFactory = sqliteConnectionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb
|
||||
.append("SELECT * FROM ")
|
||||
.append(VersionTable.TABLE_NAME);
|
||||
|
||||
String sql = sb.toString();
|
||||
// System.err.println(sql);
|
||||
ResultSet rs = null;
|
||||
try (
|
||||
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
|
||||
|
||||
System.err.println(stmt.toString());
|
||||
rs = stmt.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
return rs.getInt(VersionTable.VALUE);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
ex.printStackTrace();
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
try {
|
||||
if (rs != null) {
|
||||
rs.close();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
throw new TimeCalcException("Version was not found in database.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int newVersion) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb
|
||||
.append("UPDATE ")
|
||||
.append(VersionTable.TABLE_NAME)
|
||||
.append(" SET ")
|
||||
.append(VersionTable.VALUE).append("=").append(newVersion);
|
||||
|
||||
String sql = sb.toString();
|
||||
//System.err.println(sql);
|
||||
try (
|
||||
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
|
||||
|
||||
int numberOfUpdatedRows = stmt.executeUpdate();
|
||||
System.out.println("numberOfUpdatedRows=" + numberOfUpdatedRows);
|
||||
} catch (SQLException e) {
|
||||
System.out.println(e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// bit-inspector: Tool detecting bit rots in files.
|
||||
// Copyright (C) 2023-2023 the original author or authors.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2
|
||||
// of the License only.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
package org.nanoboot.utils.timecalc.persistence.impl.sqlite;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:robertvokac@nanoboot.org">Robert Vokac</a>
|
||||
*/
|
||||
class VersionTable {
|
||||
|
||||
public static final String TABLE_NAME = "VERSION";
|
||||
|
||||
public static final String VALUE = "VALUE";
|
||||
|
||||
private VersionTable() {
|
||||
//Not meant to be instantiated.
|
||||
}
|
||||
|
||||
}
|
@ -33,9 +33,7 @@ class WorkingDayTable {
|
||||
|
||||
public static final String ARRIVAL_HOUR = "ARRIVAL_HOUR";
|
||||
public static final String ARRIVAL_MINUTE = "ARRIVAL_MINUTE";
|
||||
public static final String HALF_DAY = "HALF_DAY";
|
||||
public static final String OVERTIME_HOUR = "OVERTIME_HOUR";
|
||||
|
||||
public static final String OVERTIME_MINUTE = "OVERTIME_MINUTE";
|
||||
public static final String WORKING_TIME_IN_MINUTES = "WORKING_TIME_IN_MINUTES";
|
||||
public static final String PAUSE_TIME_IN_MINUTES = "PAUSE_TIME_IN_MINUTES";
|
||||
|
@ -696,6 +696,9 @@ public class MainWindow extends TWindow {
|
||||
TTime nowTime = TTime.of(time.asCalendar());
|
||||
TTime timeElapsed = TTime
|
||||
.computeTimeDiff(startTime, nowTime);
|
||||
System.out.println("timeElapsed=" + timeElapsed.toString());
|
||||
System.out.println("startTime=" + startTime.toString());
|
||||
System.out.println("nowTime=" + nowTime.toString());
|
||||
TTime timeRemains = TTime.computeTimeDiff(nowTime, endTime);
|
||||
TTime timeTotal = TTime.computeTimeDiff(startTime, endTime);
|
||||
String timeElapsedString = timeElapsed.toString();
|
||||
@ -724,8 +727,12 @@ public class MainWindow extends TWindow {
|
||||
int totalMilliseconds = timeTotal.toTotalMilliseconds();
|
||||
int totalMinutes = totalMilliseconds / 1000 / 60 ;
|
||||
|
||||
System.out.println("totalMillisecondsDone=" + totalMillisecondsDone);
|
||||
System.out.println("totalMilliseconds=" + totalMilliseconds);
|
||||
double done = ((double) totalMillisecondsDone)
|
||||
/ ((double) totalMilliseconds);
|
||||
if(done == 1)
|
||||
System.out.println("a");
|
||||
if (done < 0) {
|
||||
done = 0;
|
||||
}
|
||||
@ -788,8 +795,7 @@ public class MainWindow extends TWindow {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
walkingHumanProgress
|
||||
.setDonePercent(done);
|
||||
walkingHumanProgress.setDonePercent(done);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -66,15 +66,22 @@ public class Time extends Thread {
|
||||
|
||||
public Calendar asCalendar() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.YEAR, yearProperty.getValue());
|
||||
cal.set(Calendar.MONTH, monthProperty.getValue() - 1);
|
||||
cal.set(Calendar.DAY_OF_MONTH, dayProperty.getValue());
|
||||
cal.set(Calendar.HOUR_OF_DAY, hourProperty.getValue());
|
||||
cal.set(Calendar.MINUTE, minuteProperty.getValue());
|
||||
cal.set(Calendar.SECOND, secondProperty.getValue());
|
||||
cal.set(Calendar.MILLISECOND, millisecondProperty.getValue());
|
||||
cal.set(Calendar.YEAR, returnValueAsNeeded(yearProperty, yearCustomProperty));
|
||||
cal.set(Calendar.MONTH, returnValueAsNeeded(monthProperty, monthCustomProperty) - 1);
|
||||
cal.set(Calendar.DAY_OF_MONTH, returnValueAsNeeded(dayProperty, dayCustomProperty));
|
||||
cal.set(Calendar.HOUR_OF_DAY, returnValueAsNeeded(hourProperty, hourCustomProperty));
|
||||
cal.set(Calendar.MINUTE, returnValueAsNeeded(minuteProperty, minuteCustomProperty));
|
||||
cal.set(Calendar.SECOND, returnValueAsNeeded(secondProperty, secondCustomProperty));
|
||||
cal.set(Calendar.MILLISECOND, returnValueAsNeeded(millisecondProperty, millisecondCustomProperty));
|
||||
return cal;
|
||||
}
|
||||
private int returnValueAsNeeded(ReadOnlyProperty<Integer> p1, IntegerProperty p2) {
|
||||
return returnValueAsNeeded(p1.getValue(), p2.getValue());
|
||||
}
|
||||
|
||||
private int returnValueAsNeeded(int i1, int i2) {
|
||||
return i2 == Integer.MAX_VALUE ? i1 : i2;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
|
@ -17,8 +17,6 @@ import javax.swing.Timer;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.HashSet;
|
||||
@ -102,6 +100,8 @@ public class WalkingHumanProgress extends Widget implements
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final int donePercentInt = (int) (Math.floor(donePercent * 100));
|
||||
System.out.println("donePercent=" + donePercent);
|
||||
System.out.println("donePercentInt=" + donePercentInt);
|
||||
|
||||
int percentInt = donePercentInt;
|
||||
if (donePercentInt % 5 == 0 && !alreadyShownPercents.contains(donePercentInt)) {
|
||||
|
@ -10,12 +10,24 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.stream.Stream;
|
||||
import org.nanoboot.utils.timecalc.app.TimeCalcException;
|
||||
|
||||
/**
|
||||
* @author Robert Vokac
|
||||
@ -124,7 +136,55 @@ public class Utils {
|
||||
return base64Decoder
|
||||
.decode(s.getBytes());
|
||||
}
|
||||
public static List<String> loadFilesFromJarResources(String p, Class<?> clazz) throws IOException {
|
||||
List<String> result = new ArrayList<>();
|
||||
try {
|
||||
List<Path> paths = getPathsFromResourceJar(p, clazz);
|
||||
for (Path path : paths) {
|
||||
System.out.println("Path : " + path);
|
||||
|
||||
String filePathInJAR = path.toString();
|
||||
|
||||
if (filePathInJAR.startsWith("/")) {
|
||||
filePathInJAR = filePathInJAR.substring(1, filePathInJAR.length());
|
||||
}
|
||||
|
||||
System.out.println("filePathInJAR : " + filePathInJAR);
|
||||
|
||||
String[] array = filePathInJAR.split("/");
|
||||
result.add(array[array.length - 1]);
|
||||
}
|
||||
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
System.err.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
|
||||
throw new TimeCalcException(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<Path> getPathsFromResourceJar(String folder, Class<?> clazz)
|
||||
throws URISyntaxException, IOException {
|
||||
List<Path> result;
|
||||
|
||||
String jarPath = clazz.getProtectionDomain()
|
||||
.getCodeSource()
|
||||
.getLocation()
|
||||
.toURI()
|
||||
.getPath();
|
||||
System.out.println("JAR Path : " + jarPath);
|
||||
|
||||
URI uri = URI.create("jar:file:" + jarPath);
|
||||
try ( FileSystem fs = FileSystems.newFileSystem(uri, Collections.emptyMap());Stream<Path> stream = Files.walk(fs.getPath(folder))) {
|
||||
result = stream
|
||||
.filter(Files::isRegularFile)
|
||||
.toList();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
public static String readTextFromTextResourceInJar(String pathToFile)
|
||||
throws IOException {
|
||||
InputStream inputStream = ClassLoader.getSystemClassLoader().
|
||||
@ -139,7 +199,14 @@ public class Utils {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public static String loadStacktrace(Exception e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
public static void showNotification(String message) {
|
||||
showNotification(message, 0);
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
CREATE TABLE "VERSION" (
|
||||
"VALUE" NUMBER
|
||||
);
|
||||
INSERT INTO VERSION VALUES ("1");
|
@ -0,0 +1,17 @@
|
||||
CREATE TABLE "WORKING_DAY" (
|
||||
"ID" TEXT,
|
||||
"YEAR" NUMBER NOT NULL,
|
||||
"MONTH" NUMBER NOT NULL,
|
||||
"DAY" NUMBER NOT NULL,
|
||||
--
|
||||
"ARRIVAL_HOUR" NUMBER NOT NULL,
|
||||
"ARRIVAL_MINUTE" NUMBER NOT NULL,
|
||||
"OVERTIME_HOUR" NUMBER NOT NULL,
|
||||
"OVERTIME_MINUTE" NUMBER NOT NULL,
|
||||
--
|
||||
"WORKING_TIME_IN_MINUTES" NUMBER NOT NULL,
|
||||
"PAUSE_TIME_IN_MINUTES" NUMBER NOT NULL,
|
||||
--
|
||||
"NOTE" TEXT NOT NULL,
|
||||
PRIMARY KEY("ID")
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user