Added several improvements, changes and bug fixes

This commit is contained in:
Robert Vokac 2024-03-16 13:26:35 +00:00
parent 402ff5b0a5
commit 82f8c9b683
No known key found for this signature in database
GPG Key ID: 693D30BEE3329055
8 changed files with 354 additions and 138 deletions

View File

@ -4,14 +4,18 @@ 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;
import org.nanoboot.utils.timecalc.utils.common.DateFormats;
import org.nanoboot.utils.timecalc.utils.common.FileConstants;
import org.nanoboot.utils.timecalc.utils.common.Utils;
import org.nanoboot.utils.timecalc.utils.property.StringProperty;
import javax.swing.JOptionPane;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.sql.Connection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -35,6 +39,11 @@ public class TimeCalcApp {
private SqliteConnectionFactory sqliteConnectionFactory;
public void start(String[] args) throws IOException {
File dbFile = new File(FileConstants.TC_DIRECTORY.getAbsolutePath() + "/" + "time-calc.sqlite3");
File dbFileBackup = new File(dbFile.getAbsolutePath() + ".backup." + DateFormats.DATE_TIME_FORMATTER_SHORT.format(new Date()).substring(0, 10) + ".sqlite3");
if(dbFile.exists() && !dbFileBackup.exists()) {
Files.copy(dbFile.toPath(), dbFileBackup.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
if (startNanoTime != 0l) {
throw new TimeCalcException("TimeCalcApp was already started.");
}

View File

@ -3,6 +3,8 @@ package org.nanoboot.utils.timecalc.entity;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ -14,6 +16,7 @@ import lombok.ToString;
@Getter
@Setter
@ToString
@AllArgsConstructor
public class Activity implements Comparable<Activity> {
private static final String SUBJECT_FIELD_SEPARATOR = " : ";

View File

@ -14,7 +14,21 @@ public class ActivityForStats extends Activity {
private int todayRemainsHours;
private int todayRemainsMinutes;
public ActivityForStats() {
public ActivityForStats(String id, int year, int month, int day,
String name,
String comment, String ticket, int spentHours, int spentMinutes,
String flags, String nextActivityId,
int todaySpentHours,
int todaySpentMinutes,
int todayRemainsHours,
int todayRemainsMinutes) {
super(id, year, month, day, name, comment, ticket, spentHours,
spentMinutes,
flags, nextActivityId);
this.todaySpentHours = todaySpentHours;
this.todaySpentMinutes = todaySpentMinutes;
this.todayRemainsHours = todayRemainsHours;
this.todayRemainsMinutes = todayRemainsMinutes;
}
public List<ActivityForStats> createList(List<Activity> list) {

View File

@ -14,8 +14,12 @@ public interface ActivityRepositoryApi {
Activity getLastActivityForDay(int year, int month, int day);
Activity getPreviousActivity(String id);
List<Activity> list(int year, int month, int day);
List<Activity> list(String ticket);
void update(Activity activity);
Activity read(String id);

View File

@ -11,6 +11,7 @@ import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi;
import java.util.List;
import org.nanoboot.utils.timecalc.app.TimeCalcException;
import org.nanoboot.utils.timecalc.entity.Activity;
import org.nanoboot.utils.timecalc.utils.common.Utils;
/**
* @author Robert Vokac
@ -71,151 +72,231 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
}
@Override
public void delete(String id) {
System.out.println("Going to delete: " + id);
if(!Utils.askYesNo(null, "Do you really want to delete this activity? " + read(id), "Deletion of activity")) {
return;
}
StringBuilder sb = new StringBuilder();
sb
.append("DELETE FROM ")
.append(ActivityTable.TABLE_NAME)
.append(" WHERE ").append(
ActivityTable.ID).append("=?");
String sql = sb.toString();
//System.err.println(sql);
try (
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
int i = 0;
stmt.setString(++i, id);
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();
throw new TimeCalcException(ex);
}
}
@Override
public List<Activity> list(int year, int month, int day) {
List<Activity> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
sb
.append("SELECT * FROM ")
.append(ActivityTable.TABLE_NAME)
.append(" WHERE ")
.append(ActivityTable.YEAR).append("=? AND ")
.append(ActivityTable.MONTH).append("=? AND ")
.append(ActivityTable.DAY).append("=? ");
String sql = sb.toString();
int i = 0;
ResultSet rs = null;
try (
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
stmt.setInt(++i, year);
stmt.setInt(++i, month);
stmt.setInt(++i, day);
rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractActivityFromResultSet(rs));
}
} catch (SQLException | ClassNotFoundException e) {
System.out.println(e.getMessage());
throw new RuntimeException(e);
} finally {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
throw new RuntimeException(ex);
}
}
return result;
//
}
@Override
public List<Activity> list(String ticket) {
List<Activity> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
sb
.append("SELECT * FROM ")
.append(ActivityTable.TABLE_NAME)
.append(" WHERE ")
.append(ActivityTable.TICKET).append("=? ");
String sql = sb.toString();
int i = 0;
ResultSet rs = null;
try (
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
stmt.setString(++i, ticket);
rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractActivityFromResultSet(rs));
}
} catch (SQLException | ClassNotFoundException e) {
System.out.println(e.getMessage());
throw new RuntimeException(e);
} finally {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
throw new RuntimeException(ex);
}
}
return result;
}
@Override
public void update(Activity activity) {
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
System.out.println("Going to update: " + activity.toString());
StringBuilder sb = new StringBuilder();
sb
.append("UPDATE ")
.append(ActivityTable.TABLE_NAME)
.append(" SET ")
.append(ActivityTable.NAME).append("=?, ")
.append(ActivityTable.COMMENT).append("=?, ")
.append(ActivityTable.TICKET).append("=?, ")
.append(ActivityTable.SPENT_HOURS).append("=?, ")
.append(ActivityTable.SPENT_MINUTES).append("=?, ")
.append(ActivityTable.FLAGS).append("=?, ")
.append(ActivityTable.NEXT_ACTIVITY_ID).append("=? ")
.append(" WHERE ").append(
ActivityTable.ID).append("=?");
String sql = sb.toString();
//System.err.println(sql);
try (
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
int i = 0;
stmt.setString(++i, activity.getName());
stmt.setString(++i, activity.getComment());
stmt.setString(++i, activity.getTicket());
stmt.setInt(++i, activity.getSpentHours());
stmt.setInt(++i, activity.getSpentMinutes());
stmt.setString(++i, activity.getFlags());
stmt.setString(++i, activity.getNextActivityId());
stmt.setString(++i, activity.getId());
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();
throw new TimeCalcException(ex);
}
}
@Override
public Activity read(String id) {
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
List<Activity> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
sb
.append("SELECT * FROM ")
.append(ActivityTable.TABLE_NAME)
.append(" WHERE ")
.append(ActivityTable.ID).append("=? ");
String sql = sb.toString();
int i = 0;
ResultSet rs = null;
try (
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
stmt.setString(++i, id);
rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractActivityFromResultSet(rs));
}
} catch (SQLException | ClassNotFoundException e) {
System.out.println(e.getMessage());
throw new RuntimeException(e);
} finally {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
throw new RuntimeException(ex);
}
}
return result.stream().findFirst().orElse(null);
}
@Override
public void delete(String id) {
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
private Activity extractActivityFromResultSet(final ResultSet rs) throws SQLException {
return new Activity(
rs.getString(ActivityTable.ID),
rs.getInt(ActivityTable.YEAR),
rs.getInt(ActivityTable.MONTH),
rs.getInt(ActivityTable.DAY),
rs.getString(ActivityTable.NAME),
rs.getString(ActivityTable.COMMENT),
rs.getString(ActivityTable.TICKET),
rs.getInt(ActivityTable.SPENT_HOURS),
rs.getInt(ActivityTable.SPENT_MINUTES),
rs.getString(ActivityTable.FLAGS),
rs.getString(ActivityTable.NEXT_ACTIVITY_ID)
);
}
//
// @Override
// public List<WorkingDay> list(int year, int month, int day) {
//
// List<WorkingDay> result = new ArrayList<>();
// StringBuilder sb = new StringBuilder();
// sb
// .append("SELECT * FROM ")
// .append(WorkingDayTable.TABLE_NAME)
// .append(" WHERE ")
// .append(WorkingDayTable.YEAR).append("=? AND ")
// .append(WorkingDayTable.MONTH).append("=? ");
// if (day != 0) {
// sb.append(" AND ").append(WorkingDayTable.DAY).append("=? ");
// }
//
// String sql = sb.toString();
// int i = 0;
// ResultSet rs = null;
// try (
// Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
//
// //System.err.println(stmt.toString());
// stmt.setInt(++i, year);
// stmt.setInt(++i, month);
// if (day != 0) {
// stmt.setInt(++i, day);
// }
// rs = stmt.executeQuery();
//
// while (rs.next()) {
// result.add(extractWorkingDayFromResultSet(rs));
// }
// } catch (SQLException e) {
// System.out.println(e.getMessage());
// throw new RuntimeException(e);
// } catch (ClassNotFoundException ex) {
// System.out.println(ex.getMessage());
// throw new RuntimeException(ex);
// } finally {
// try {
// if (rs != null) {
// rs.close();
// }
// } catch (SQLException ex) {
// System.out.println(ex.getMessage());
// throw new RuntimeException(ex);
// }
// }
// return result;
////
// }
//
// @Override
// public void update(WorkingDay workingDay) {
// if(list(workingDay.getYear(), workingDay.getMonth(),workingDay.getDay()).isEmpty()) {
// create(workingDay);
// return;
// }
// System.out.println("Going to update: " + workingDay.toString());
//
// StringBuilder sb = new StringBuilder();
// sb
// .append("UPDATE ")
// .append(WorkingDayTable.TABLE_NAME)
// .append(" SET ")
// .append(WorkingDayTable.ARRIVAL_HOUR).append("=?, ")
// .append(WorkingDayTable.ARRIVAL_MINUTE).append("=?, ")
// .append(WorkingDayTable.OVERTIME_HOUR).append("=?, ")
// .append(WorkingDayTable.OVERTIME_MINUTE).append("=?, ")
// .append(WorkingDayTable.WORKING_TIME_IN_MINUTES).append("=?, ")
// .append(WorkingDayTable.PAUSE_TIME_IN_MINUTES).append("=?, ")
// .append(WorkingDayTable.NOTE).append("=? ")
// .append(" WHERE ").append(
// WorkingDayTable.ID).append("=?");
//
// String sql = sb.toString();
// //System.err.println(sql);
// try (
// Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
// int i = 0;
// stmt.setInt(++i, workingDay.getArrivalHour());
// stmt.setInt(++i, workingDay.getArrivalMinute());
// stmt.setInt(++i, workingDay.getOvertimeHour());
// stmt.setInt(++i, workingDay.getOvertimeMinute());
// stmt.setInt(++i, workingDay.getWorkingTimeInMinutes());
// stmt.setInt(++i, workingDay.getPauseTimeInMinutes());
// stmt.setString(++i, workingDay.getNote());
//
// stmt.setString(++i, workingDay.getId());
//
// 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();
// throw new TimeCalcException(ex);
// }
// }
//
// @Override
// public WorkingDay read(int year, int month, int day) {
// List<WorkingDay> list = list(year, month, day);
// return list.isEmpty() ? null : list.get(0);
// }
//
// private WorkingDay extractWorkingDayFromResultSet(final ResultSet rs) throws SQLException {
// return new WorkingDay(
// rs.getString(WorkingDayTable.ID),
// rs.getInt(WorkingDayTable.YEAR),
// rs.getInt(WorkingDayTable.MONTH),
// rs.getInt(WorkingDayTable.DAY),
// rs.getInt(WorkingDayTable.ARRIVAL_HOUR),
// rs.getInt(WorkingDayTable.ARRIVAL_MINUTE),
// rs.getInt(WorkingDayTable.OVERTIME_HOUR),
// rs.getInt(WorkingDayTable.OVERTIME_MINUTE),
// rs.getInt(WorkingDayTable.WORKING_TIME_IN_MINUTES),
// rs.getInt(WorkingDayTable.PAUSE_TIME_IN_MINUTES),
// rs.getString(WorkingDayTable.NOTE)
// );
// }
//
@Override
public List<String> getYears() {
List<String> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
sb
.append("SELECT distinct ").append(WorkingDayTable.YEAR). append(" FROM ")
.append("SELECT distinct ").append(ActivityTable.YEAR). append(" FROM ")
.append(ActivityTable.TABLE_NAME);
String sql = sb.toString();
@ -227,7 +308,7 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
rs = stmt.executeQuery();
while (rs.next()) {
result.add(rs.getString(WorkingDayTable.YEAR));
result.add(rs.getString(ActivityTable.YEAR));
}
} catch (SQLException e) {
System.out.println(e.getMessage());
@ -251,13 +332,98 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi {
@Override
public Activity getLastActivityForDay(int year, int month, int day) {
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
List<Activity> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
sb
.append("SELECT * FROM ")
.append(ActivityTable.TABLE_NAME)
.append(" WHERE ")
.append(ActivityTable.YEAR).append("=? AND ")
.append(ActivityTable.MONTH).append("=? AND ")
.append(ActivityTable.DAY).append("=? AND ")
.append(ActivityTable.NEXT_ACTIVITY_ID)
.append(" IS NULL ");
String sql = sb.toString();
int i = 0;
ResultSet rs = null;
try (
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
stmt.setInt(++i, year);
stmt.setInt(++i, month);
stmt.setInt(++i, day);
rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractActivityFromResultSet(rs));
}
} catch (SQLException | ClassNotFoundException e) {
System.out.println(e.getMessage());
throw new RuntimeException(e);
} finally {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
throw new RuntimeException(ex);
}
}
if(result.isEmpty()) {
return null;
}
if(result.size() == 1) {
result.get(0);
}
throw new TimeCalcException("Fatal error: More than one activity per one day with next activity id set to null: " + year + ", " + month + day);
}
@Override
public List<Activity> list(int year, int month, int day) {
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
public Activity getPreviousActivity(String id) {
List<Activity> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
sb
.append("SELECT * FROM ")
.append(ActivityTable.TABLE_NAME)
.append(" WHERE ")
.append(ActivityTable.NEXT_ACTIVITY_ID).append("=? ");
String sql = sb.toString();
int i = 0;
ResultSet rs = null;
try (
Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) {
stmt.setString(++i, id);
rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractActivityFromResultSet(rs));
}
} catch (SQLException | ClassNotFoundException e) {
System.out.println(e.getMessage());
throw new RuntimeException(e);
} finally {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
throw new RuntimeException(ex);
}
}
if(result.isEmpty()) {
return null;
}
if(result.size() == 1) {
result.get(0);
}
throw new TimeCalcException("Fatal error: More than one activity, which is previous for this activity id:" + id);
}
}

View File

@ -28,7 +28,7 @@ public class WorkingDayRepositorySQLiteImpl implements WorkingDayRepositoryApi {
public void create(WorkingDay workingDay) {
System.out.println("Going to create: " + workingDay.toString());
if(!Utils.askYesNo(null, "Do you want to create new Working Day? " + workingDay, "Creation of newWorking Day")) {
if(!Utils.askYesNo(null, "Do you want to create new Working Day? " + workingDay, "Creation of new Working Day")) {
return;
}
StringBuilder sb = new StringBuilder();

View File

@ -21,6 +21,7 @@ import org.nanoboot.utils.timecalc.swing.progress.WalkingHumanProgress;
import org.nanoboot.utils.timecalc.swing.progress.WeekBattery;
import org.nanoboot.utils.timecalc.swing.progress.YearBattery;
import org.nanoboot.utils.timecalc.utils.common.Constants;
import org.nanoboot.utils.timecalc.utils.common.DateFormats;
import org.nanoboot.utils.timecalc.utils.common.FileConstants;
import org.nanoboot.utils.timecalc.utils.common.Jokes;
import org.nanoboot.utils.timecalc.utils.common.TTime;
@ -34,7 +35,13 @@ import java.awt.Component;
import java.awt.Insets;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Calendar;
import java.util.Date;
import org.nanoboot.utils.timecalc.entity.WorkingDay;
import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi;
import org.nanoboot.utils.timecalc.persistence.impl.sqlite.ActivityRepositorySQLiteImpl;
@ -701,9 +708,20 @@ public class MainWindow extends TWindow {
workingDayRepository.update(wd);
System.out.println(wd);
File dbFile = new File(FileConstants.TC_DIRECTORY.getAbsolutePath() + "/" + "time-calc.sqlite3");
while (true) {
File dbFileBackup = new File(dbFile.getAbsolutePath() + ".backup." + DateFormats.DATE_TIME_FORMATTER_SHORT.format(new Date()).substring(0, 10) + ".sqlite3");
if(dbFile.exists() && !dbFileBackup.exists()) {
try {
Files.copy(dbFile.toPath(), dbFileBackup.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
}
if (updateWindow(timeCalcApp, time, clock, minuteBattery, hourBattery,
dayBattery,
weekBattery, monthBattery, yearBattery,

View File

@ -23,6 +23,8 @@ public class DateFormats {
= new SimpleDateFormat("HH:mm:ss:SSS", Locale.ENGLISH);
public static DateFormat DATE_TIME_FORMATTER_VERY_LONG
= new SimpleDateFormat("yyyy:MM:dd:HH:mm:ss:EEEE", Locale.ENGLISH);
public static DateFormat DATE_TIME_FORMATTER_SHORT
= new SimpleDateFormat("yyyyMMddHHmmss");
private DateFormats() {
//Not meant to be instantiated.