промежуточный. частичный рефакторинг с прицелом на библиотечную часть
This commit is contained in:
31
src/Common/Database/Tables/ColumnType.java
Normal file
31
src/Common/Database/Tables/ColumnType.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package Common.Database.Tables;
|
||||
public enum ColumnType {
|
||||
UNDEFINED,
|
||||
INT,
|
||||
LONG,
|
||||
DOUBLE,
|
||||
STRING;
|
||||
public static ColumnType valueOf(Class<?> type) {
|
||||
ColumnType res = UNDEFINED;
|
||||
try {
|
||||
res = valueOf(type.getSimpleName().toUpperCase());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public String getSQLType() {
|
||||
String res = "";
|
||||
switch (this) {
|
||||
case INT:
|
||||
case LONG:
|
||||
res = "INTEGER";
|
||||
break;
|
||||
case DOUBLE:
|
||||
res = "REAL";
|
||||
break;
|
||||
case STRING:
|
||||
res = "VARCHAR";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
37
src/Common/Database/Tables/DBTable.java
Normal file
37
src/Common/Database/Tables/DBTable.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package Common.Database.Tables;
|
||||
import Common.Database.Database;
|
||||
import Common.Database.Objects.DBObject;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
public abstract class DBTable<K, D extends DBObject> extends DataSet<K, D> {
|
||||
//-
|
||||
public DBTableColumn PK = null;
|
||||
private Database db = null; //база данных - владелец таблицы.
|
||||
public DBTable(Class<K> k_in, Class<D> d_in) {
|
||||
super(k_in, d_in);
|
||||
for (Field field : d.getFields()) {
|
||||
DBTableColumn column = new DBTableColumn(field);
|
||||
if ((!column.Ignore) && !columns.containsKey(column.Name)) {
|
||||
columns.put(column.Name, column);
|
||||
if (column.PrimaryKey) PK = column;
|
||||
}
|
||||
}
|
||||
}
|
||||
public Database getDb() {
|
||||
return db;
|
||||
}
|
||||
public void setDb(Database db_in) {
|
||||
db = db_in;
|
||||
}
|
||||
@Override
|
||||
public String getPKName() {
|
||||
return PK.Name;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder res = new StringBuilder(Name + "\n");
|
||||
for (DBTableColumn c : columns.values())
|
||||
res.append(c).append("\n");
|
||||
return res.toString();
|
||||
}
|
||||
}
|
||||
50
src/Common/Database/Tables/DBTableColumn.java
Normal file
50
src/Common/Database/Tables/DBTableColumn.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package Common.Database.Tables;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Vector;
|
||||
public class DBTableColumn {
|
||||
public String Name = "";
|
||||
public ColumnType type = ColumnType.UNDEFINED;
|
||||
public Vector<String> attributes = new Vector<String>();
|
||||
public boolean Ignore = false;
|
||||
public boolean PrimaryKey = false;
|
||||
public boolean AutoIncrement = false;
|
||||
public Object default_value = null;
|
||||
public DBTableColumn(Field field) {
|
||||
ExtractAttributes(field);
|
||||
PrimaryKey = attributes.contains("PRIMARY KEY");
|
||||
AutoIncrement = attributes.contains("AUTOINCREMENT");
|
||||
Name = field.getName();
|
||||
type = (field.getType().isEnum()) ? ColumnType.STRING : ColumnType.valueOf(field.getType());
|
||||
Ignore = ((Modifier.isStatic(field.getModifiers()) ||
|
||||
type.equals(ColumnType.UNDEFINED) ||
|
||||
attributes.contains("IGNORE")
|
||||
)
|
||||
);
|
||||
}
|
||||
public String QName() {
|
||||
return "\"" + Name + "\"";
|
||||
}
|
||||
public void ExtractAttributes(Field field) {
|
||||
attributes = new Vector<String>();
|
||||
Annotation[] annotations = field.getAnnotations();
|
||||
for (Annotation a : annotations) {
|
||||
String[] data = a.toString().split("value=");
|
||||
if (data.length > 1) {
|
||||
String[] attributes_ = data[1].split("[,\")]");
|
||||
for (String attribute : attributes_) {
|
||||
if (attribute.length() > 0)
|
||||
attributes.add(attribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
String res = QName() + " " + type.getSQLType();
|
||||
if (attributes.size() > 0)
|
||||
res += " " + String.join(" ", attributes);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
296
src/Common/Database/Tables/DataSet.java
Normal file
296
src/Common/Database/Tables/DataSet.java
Normal file
@@ -0,0 +1,296 @@
|
||||
package Common.Database.Tables;
|
||||
import Common_old.Current;
|
||||
import Common.Visual.DataSetFilter;
|
||||
import Common_old.UI.DataSetControlForm;
|
||||
import Common_old.UI.Menus_2023.DataMenuBar;
|
||||
import Common_old.UI.Tables.ColumnFilter;
|
||||
import Common_old.UI.UI;
|
||||
import Common_old.UI.Windows.Dialog.DBObjectDialog;
|
||||
import Common_old.UI.Windows.Dialog.DialogFields;
|
||||
import Common.Utils.TextLog;
|
||||
import Common.Database.Objects.DBObject;
|
||||
import Common.Visual.CommonUI;
|
||||
import Visual_DVM_2021.UI.Interface.FilterWindow;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
public class DataSet<K, D extends DBObject> extends DataSetAnchestor {
|
||||
//-
|
||||
public LinkedHashMap<Class, Object> selections = new LinkedHashMap<>();
|
||||
//---
|
||||
public String Name;
|
||||
public Class<K> k; //класс первичного ключа.
|
||||
public Class<D> d; //класс объектов.
|
||||
public LinkedHashMap<K, D> Data = new LinkedHashMap<>(); //наполнение
|
||||
//-
|
||||
public DataSetControlForm ui_;
|
||||
protected FilterWindow f_ui; // отображение количества объектов
|
||||
//-
|
||||
public LinkedHashMap<Integer, ColumnFilter> columnsFilters = new LinkedHashMap<>(); //текстовые фильтры столбцов
|
||||
//--
|
||||
protected Vector<DataSetFilter<D>> filters = new Vector<>();
|
||||
protected void createFilters() {
|
||||
}
|
||||
//--
|
||||
public DataSet(Class<K> k_in, Class<D> d_in) {
|
||||
k = k_in;
|
||||
d = d_in;
|
||||
Name = d.getSimpleName();
|
||||
}
|
||||
public void mountUI(JPanel content_in) {
|
||||
UI.Clear(content_in);
|
||||
//-->
|
||||
ui_ = createUI();
|
||||
ui_.setContent(content_in);
|
||||
//-->
|
||||
if ( CommonUI.menuBars.containsKey(getClass())) {
|
||||
DataMenuBar bar = CommonUI.menuBars.get(getClass());
|
||||
content_in.add(bar, BorderLayout.NORTH);
|
||||
setFilterUI(count -> CommonUI.menuBars.get(getClass()).countLabel.setText(String.valueOf(count)));
|
||||
if (ui_.hasCheckBox())
|
||||
bar.createSelectionButtons(this);
|
||||
}
|
||||
content_in.add(ui_.getDataPanel(), BorderLayout.CENTER);
|
||||
//----
|
||||
createFilters();
|
||||
if (!filters.isEmpty()) {
|
||||
DataMenuBar menuBar = CommonUI.menuBars.get(getClass());
|
||||
for (DataSetFilter<D> filter : filters)
|
||||
menuBar.addMenus(filter.menu);
|
||||
}
|
||||
}
|
||||
public DataSetControlForm getUi() {
|
||||
return ui_;
|
||||
}
|
||||
public void setFilterUI(FilterWindow ui_in) {
|
||||
f_ui = ui_in;
|
||||
}
|
||||
public void ClearUI() {
|
||||
if ((ui_ != null) && ui_.isShown()) {
|
||||
ui_.ClearSelection();
|
||||
ui_.Clear();
|
||||
if (f_ui != null)
|
||||
f_ui.ShowNoMatches();
|
||||
}
|
||||
}
|
||||
public void RefreshUI() {
|
||||
if (ui_ != null) ui_.Refresh();
|
||||
}
|
||||
public int getRowCountUI() {
|
||||
return ui_.getRowCount();
|
||||
}
|
||||
public void SetCurrentObjectUI(Object pk) {
|
||||
if (ui_ != null) {
|
||||
//todo возможно проверить, что текущий объект уже соответствует ключу, и если да, то ничего делать.
|
||||
ui_.ClearSelection(); //сброс текущего объекта и всего что с ним связано.
|
||||
ui_.Select(pk);
|
||||
}
|
||||
}
|
||||
//столбы/ потом переименовать обратно в getUIColumnNames.сейчас так для скорости переноса.
|
||||
public String[] getUIColumnNames() {
|
||||
return new String[]{};
|
||||
}
|
||||
protected DataSetControlForm createUI() {
|
||||
return null;
|
||||
}
|
||||
public boolean hasUI() {
|
||||
return ui_ != null;
|
||||
}
|
||||
public void CheckAll(boolean flag) {
|
||||
for (D object : Data.values()) {
|
||||
if (object.isVisible())
|
||||
object.Select(flag);
|
||||
}
|
||||
RefreshUI();
|
||||
}
|
||||
public D getFirstRecord() {
|
||||
return Data.values().stream().findFirst().orElse(null);
|
||||
}
|
||||
public Vector<D> getOrderedRecords(Comparator<D> comparator) {
|
||||
Vector<D> res = new Vector<>(Data.values());
|
||||
res.sort(comparator);
|
||||
return res;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public DBObjectDialog<D, ? extends DialogFields> getDialog() {
|
||||
return null;
|
||||
}
|
||||
public boolean ShowAddObjectDialog(DBObject object) {
|
||||
return getDialog().ShowDialog(getSingleDescription() + ": добавление", object);
|
||||
}
|
||||
public boolean ShowEditObjectDialog(DBObject object) {
|
||||
DBObjectDialog dialog = getDialog();
|
||||
dialog.edit = true;
|
||||
dialog.SetEditLimits();
|
||||
return dialog.ShowDialog(getSingleDescription() + ": редактирование", object);
|
||||
}
|
||||
public boolean ViewObject(DBObject object) {
|
||||
DBObjectDialog dialog = getDialog();
|
||||
dialog.SetReadonly();
|
||||
dialog.ShowDialog(getSingleDescription() + ": просмотр", object);
|
||||
return false;
|
||||
}
|
||||
public boolean ShowDeleteObjectDialog(DBObject object) {
|
||||
return UI.Warning(getSingleDescription() + " " + object.getBDialogName() + " будет удален(а)");
|
||||
}
|
||||
public String QName() {
|
||||
return "\"" + Name + "\"";
|
||||
}
|
||||
public String getPKName() {
|
||||
return "";
|
||||
} //получить имя ключевого поля. нужно для таблиц.
|
||||
public String getPluralDescription() {
|
||||
return "";
|
||||
}
|
||||
public String getSingleDescription() {
|
||||
return "";
|
||||
}
|
||||
//времянки
|
||||
public Current CurrentName() {
|
||||
return Current.Undefined;
|
||||
}
|
||||
public boolean CheckCurrent(TextLog log) {
|
||||
return Current.Check(log, CurrentName());
|
||||
}
|
||||
public boolean hasCurrent() {
|
||||
return Current.get(CurrentName()) != null;
|
||||
}
|
||||
public void dropCurrent() {
|
||||
Current.set(CurrentName(), null);
|
||||
}
|
||||
public D getCurrent() {
|
||||
return (D) Current.get(CurrentName());
|
||||
}
|
||||
public void setCurrent(D o) {
|
||||
Current.set(CurrentName(), o);
|
||||
}
|
||||
//-
|
||||
public void put(Object key, D object) {
|
||||
Data.put((K) key, object);
|
||||
}
|
||||
public D get(Object key) {
|
||||
return Data.get(key);
|
||||
}
|
||||
public Object getFieldAt(D object, int columnIndex) {
|
||||
return null;
|
||||
}
|
||||
public void clear() {
|
||||
Data.clear();
|
||||
}
|
||||
public int size() {
|
||||
return Data.size();
|
||||
}
|
||||
public boolean containsKey(Object key) {
|
||||
return Data.containsKey(key);
|
||||
}
|
||||
//-
|
||||
public Vector<K> getVisibleKeys() {
|
||||
Comparator<D> comparator = getComparator();
|
||||
Vector<K> res = new Vector<>();
|
||||
if (comparator == null) {
|
||||
for (K key : Data.keySet())
|
||||
if (Data.get(key).isVisible())
|
||||
res.add(key);
|
||||
} else {
|
||||
Vector<D> raw = new Vector<>();
|
||||
for (D object : Data.values()) {
|
||||
if (object.isVisible())
|
||||
raw.add(object);
|
||||
}
|
||||
raw.sort(comparator);
|
||||
for (D object : raw)
|
||||
res.add((K) object.getPK());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
protected Comparator<D> getComparator() {
|
||||
return null;
|
||||
}
|
||||
public int getCheckedCount() {
|
||||
return (int) Data.values().stream().filter(d -> d.isVisible() && d.isSelected()).count();
|
||||
}
|
||||
public Vector<D> getCheckedItems() {
|
||||
return Data.values().stream().filter(d -> d.isVisible() && d.isSelected()).collect(Collectors.toCollection(Vector::new));
|
||||
}
|
||||
public Vector<K> getCheckedKeys() {
|
||||
return Data.values().stream().filter(DBObject::isSelected).map(d -> (K) d.getPK()).collect(Collectors.toCollection(Vector::new));
|
||||
}
|
||||
//--
|
||||
public void SaveLastSelections() {
|
||||
if (hasUI()) {
|
||||
Object lastPk = null;
|
||||
if ((CurrentName() != Current.Undefined) && (getCurrent() != null))
|
||||
lastPk = getCurrent().getPK();
|
||||
if (!selections.containsKey(getClass()))
|
||||
selections.put(getClass(), lastPk);
|
||||
else selections.replace(getClass(), lastPk);
|
||||
}
|
||||
}
|
||||
public void RestoreLastSelections() {
|
||||
if (hasUI()) {
|
||||
Object lastPk = selections.get(getClass());
|
||||
if ((CurrentName() != Current.Undefined) && (lastPk != null)) {
|
||||
ui_.Select(lastPk);
|
||||
}
|
||||
}
|
||||
}
|
||||
//---
|
||||
// применить значение фильтра к фильру объекта напирмер Message.filterValue = text;
|
||||
public void changeColumnFilterValue(int columnIndex, String text) {
|
||||
}
|
||||
public Object getColumnFilterValue(int columnIndex) {
|
||||
return "";
|
||||
}
|
||||
//--
|
||||
public void ShowUI() {
|
||||
for (DataSetFilter<D> filter : filters)
|
||||
filter.Drop();
|
||||
//--
|
||||
if (ui_ != null) {
|
||||
ui_.Show();
|
||||
if (f_ui != null)
|
||||
f_ui.ShowMatchesCount(getRowCountUI());
|
||||
}
|
||||
//--
|
||||
for (DataSetFilter<D> filter : filters)
|
||||
filter.Refresh();
|
||||
}
|
||||
public void ShowUI(Object key) {
|
||||
for (DataSetFilter<D> filter : filters)
|
||||
filter.Drop();
|
||||
//--
|
||||
if (ui_ != null) {
|
||||
ui_.Show(key);
|
||||
if (f_ui != null)
|
||||
f_ui.ShowMatchesCount(getRowCountUI());
|
||||
}
|
||||
//--
|
||||
for (DataSetFilter<D> filter : filters)
|
||||
filter.Refresh();
|
||||
}
|
||||
public boolean applyFilters(D object) {
|
||||
for (DataSetFilter<D> filter : filters) {
|
||||
if (!filter.Validate(object))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//--
|
||||
public Vector<D> getCheckedOrCurrent() {
|
||||
Vector<D> res = new Vector<>();
|
||||
if (getCheckedCount() > 0)
|
||||
res = getCheckedItems();
|
||||
else {
|
||||
if (!CurrentName().equals(Current.Undefined)) {
|
||||
if (getCurrent() != null) {
|
||||
res.add(getCurrent());
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
13
src/Common/Database/Tables/DataSetAnchestor.java
Normal file
13
src/Common/Database/Tables/DataSetAnchestor.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package Common.Database.Tables;
|
||||
import Common.Database.Objects.DBObject;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
public abstract class DataSetAnchestor {
|
||||
//чтобы обмануть стирание типов во всех параметризованных полях. используется не во всех потомках.
|
||||
//ибо не все наборы данных относятся к базам.
|
||||
public LinkedHashMap<String, DBTableColumn> columns = new LinkedHashMap<>();
|
||||
//то же самое. на самом деле внешние ключи бывают только у таблиц бд
|
||||
public LinkedHashMap<Class<? extends DBObject>, FKBehaviour> getFKDependencies() {
|
||||
return new LinkedHashMap<>();
|
||||
}
|
||||
}
|
||||
9
src/Common/Database/Tables/FKBehaviour.java
Normal file
9
src/Common/Database/Tables/FKBehaviour.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package Common.Database.Tables;
|
||||
public class FKBehaviour {
|
||||
public FKDataBehaviour data; //поведение данных внешнего ключа при удалении/модификации
|
||||
public FKCurrentObjectBehaviuor ui; //поведение интерфейсов таблиц внешнего ключа при показе текущего объекта.
|
||||
public FKBehaviour(FKDataBehaviour data_in, FKCurrentObjectBehaviuor ui_in) {
|
||||
data = data_in;
|
||||
ui = ui_in;
|
||||
}
|
||||
}
|
||||
5
src/Common/Database/Tables/FKCurrentObjectBehaviuor.java
Normal file
5
src/Common/Database/Tables/FKCurrentObjectBehaviuor.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package Common.Database.Tables;
|
||||
public enum FKCurrentObjectBehaviuor {
|
||||
PASSIVE,
|
||||
ACTIVE
|
||||
}
|
||||
7
src/Common/Database/Tables/FKDataBehaviour.java
Normal file
7
src/Common/Database/Tables/FKDataBehaviour.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package Common.Database.Tables;
|
||||
//поведение таблиц имеющих внешние ключи
|
||||
public enum FKDataBehaviour {
|
||||
NONE,
|
||||
DROP,
|
||||
DELETE
|
||||
}
|
||||
7
src/Common/Database/Tables/iDBTable.java
Normal file
7
src/Common/Database/Tables/iDBTable.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package Common.Database.Tables;
|
||||
import Common.Database.Objects.iDBObject;
|
||||
public abstract class iDBTable<D extends iDBObject> extends DBTable<Integer, D> {
|
||||
public iDBTable(Class<D> d_in) {
|
||||
super(Integer.class, d_in);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user