All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.huaweicloud.dws.client.model.Record Maven / Gradle / Ivy

package com.huaweicloud.dws.client.model;

import com.huaweicloud.dws.client.DwsConfig;
import com.huaweicloud.dws.client.TableConfig;
import com.huaweicloud.dws.client.exception.InvalidException;
import com.huaweicloud.dws.client.util.AssertUtil;

import java.io.Serializable;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;

/**
 * @ProjectName: dws-connector
 * @ClassName: Record
 * @Description: 操作记录定义
 * @Date: 2022/12/22 18:25
 * @Version: 1.0
 */
public class Record implements Serializable {

    public static final String EMPTY = "";
    private final TableSchema schema;
    private OperationType type = OperationType.WRITE;

    private TableConfig config;

    /**
     * 记录每条数据值
     */
    private final Object[] values;

    /**
     * 记录被设置过的列
     */
    private final BitSet columnBit;

    /**
     * 记录需要忽略更新的列
     */
    private final BitSet ignoreUpdate;
    private BitSet compareField;


    /**
     * 生成该记录的数据库唯一key
     */
    public Record getRecordKey() {
        Record result = new Record(schema, type, null);
        result.type = this.type;
        // 如果没有主键或者没设置主键(可能数据库自增),则不存在更新问题,有主键则提取主键字段
        List keyNames = schema.getPrimaryKeyNames();
        if (!isUpsert()) {
            return this;
        }
        for (String name : keyNames) {
            Integer index = schema.getColumnIndex(name);
            result.setValue(index, values[index]);
        }
        return result;
    }

    /**
     * 检查是否是走upsert
     * 无主键或者自增主键返回 false
     * @return
     */
    public boolean isUpsert() {
        List keyNames = schema.getPrimaryKeyNames();
        // 没有设置主键时 需要保证是自增主键才能正常入库
        return !keyNames.isEmpty() && !EMPTY.equals(keyNames.stream().filter(this::isSet).findAny().orElse(EMPTY));
    }

    public BitSet getColumnBit() {
        return columnBit;
    }

    public BitSet getIgnoreUpdate() {
        return ignoreUpdate;
    }

    public OperationType getType() {
        return type;
    }

    public Record(TableSchema schema) {
        AssertUtil.nonNull(schema, new InvalidException("schema is null"));
        this.schema = schema;
        columnBit = new BitSet(schema.getColumns().size());
        ignoreUpdate = new BitSet(schema.getColumns().size());
        values = new Object[schema.getColumns().size()];
    }

    public Record(TableSchema schema, OperationType type) {
        this(schema, type, null);
    }

    public Record(TableSchema schema, OperationType type, DwsConfig config) {
        this(schema);
        AssertUtil.nonNull(type, new InvalidException("operation type is null"));
        this.type = type;
        if (config != null) {
            this.config = config.getTableConfig(schema.getTableName());
            if (this.config.getCompareField() != null) {
                this.compareField = new BitSet(schema.getColumns().size());
                for (String key : this.config.getCompareField()) {
                    Integer index = this.schema.getColumnIndex(key);
                    compareField.set(index);
                }
            }
        }
    }

    public TableSchema getTableSchema() {
        return schema;
    }

    public Record setValue(int i, Object value) {
        return this.setValue(i, value, false);
    }

    public Record setValue(String columnName, Object value, boolean ignoreUpdate) {
        return setValue(getAndCheckIndex(columnName), value, ignoreUpdate);
    }

    public Record setValue(int i, Object value, boolean ignoreUpdate) {
        values[i] = value;
        columnBit.set(i);
        if (ignoreUpdate) {
            this.ignoreUpdate.set(i);
        }
        return this;
    }

    public Object getValue(int i) {
        return values[i];
    }

    public Object getValue(String columnName) {
        return getValue(getAndCheckIndex(columnName));
    }

    private Integer getAndCheckIndex(String columnName) {
        Integer index = schema.getColumnIndex(columnName);
        checkIdx(index);
        return index;
    }

    public boolean isSet(String name) {
        Integer i = getAndCheckIndex(name);
        return columnBit.get(i);
    }

    public boolean isIgnoreUpdate(String name) {
        Integer i = getAndCheckIndex(name);
        return ignoreUpdate.get(i);
    }

    private void checkIdx(int i) {
        AssertUtil.isTrue(i < values.length && i >= 0, new InvalidException("not allowed i " + i));
    }

    /**
     * 用record中被设置的字段覆盖当前数据的对应字段
     */
    public void cover(Record record) {
        if (!schema.equals(record.schema)) {
            throw new InvalidException("schema not match");
        }
        if (compareField != null) {
            long count = compareField.stream().mapToObj(e -> {
                Object value = record.getValue(e);
                Object oldValue = this.getValue(e);
                return (value instanceof Comparable) && oldValue != null && ((Comparable) value).compareTo(oldValue) > 0;
            }).filter(x -> !x).count();
            if (count != 0) {
                // 当前值不比原有值大,忽略
                return;
            }
        }
        record.columnBit.stream().forEach(e -> {
            if (!record.ignoreUpdate.get(e)) {
                // 如果第二次数据标记冲突时忽略更新,则丢弃该字段二次数据
                this.setValue(e, record.getValue(e), record.ignoreUpdate.get(e));
            }
        });
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        } else if (!(o instanceof Record)) {
            return false;
        }
        return Arrays.deepEquals(this.values, ((Record) o).values);
    }

    @Override
    public int hashCode() {
        return Arrays.deepHashCode(this.values);
    }

    @Override
    public String toString() {
        return "Record{" +
                "schema=" + schema +
                ", values=" + Arrays.toString(values) +
                ", columnBit=" + columnBit +
                ", ignoreUpdate=" + ignoreUpdate +
                '}';
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy