package Common.Database.Tables;
import Common.Database.Database;
import Common.Database.Objects.DBObject;

import java.lang.reflect.Field;
import java.util.Vector;
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(getName() + "\n");
        for (DBTableColumn c : columns.values())
            res.append(c).append("\n");
        return res.toString();
    }
    boolean vectorContains(D object, Vector<D> vector) {
        for (D v_object : vector) {
            if (isEqual(object, v_object))
                return true;
        }
        return false;
    }
    public void ActualizeData(Vector<D> old, Vector<D> actual) throws Exception {
        //привести данные вектора old в соответствие с вектором new
        //те, что в нем появились вставить, те что отсутствуют но есть в old удалить
        Vector<D> to_delete = new Vector<>();
        Vector<D> to_insert = new Vector<>();
        for (D object : old) {
            if (!vectorContains(object, actual))
                to_delete.add(object);
        }
        for (D object : actual) {
            if (!vectorContains(object, old))
                to_insert.add(object);
        }
        db.BeginTransaction();
        for (D object : to_delete)
            db.Delete(object);
        for (D object : to_insert)
            db.Insert(object);
        db.Commit();
    }
}
