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

io.github.shanqiang.sp.dimension.RdsDimensionTable Maven / Gradle / Ivy

The newest version!
package io.github.shanqiang.sp.dimension;

import io.github.shanqiang.exception.InconsistentColumnSizeException;
import io.github.shanqiang.exception.UnknownTypeException;
import io.github.shanqiang.table.Index;
import io.github.shanqiang.table.Table;
import io.github.shanqiang.table.TableBuilder;
import io.github.shanqiang.table.Type;
import io.github.shanqiang.Threads;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static java.lang.String.format;
import static java.util.Objects.requireNonNull;

public abstract class RdsDimensionTable extends DimensionTable {
    private static final Logger logger = LoggerFactory.getLogger(RdsDimensionTable.class);

    protected final String url;
    protected final String userName;
    protected final String password;
    private final Duration refreshInterval;
    private final Map columnTypeMap;
    private final String[] primaryKeyColumnNames;
    private final String sql;
    private final String myName;

    public RdsDimensionTable(String jdbcUrl,
                             String tableName,
                             final String userName,
                             final String password,
                             Duration refreshInterval,
                             Map columnTypeMap,
                             String... primaryKeyColumnNames) {
        this(jdbcUrl, userName, password, refreshInterval,
                format("select %s from %s", String.join(",", columnTypeMap.keySet()), tableName),
                columnTypeMap,
                primaryKeyColumnNames);
    }

    abstract protected DataSource newDataSource();

    public RdsDimensionTable(String jdbcUrl,
                             final String userName,
                             final String password,
                             Duration refreshInterval,
                             final String sql,
                             Map columnTypeMap,
                             String... primaryKeyColumnNames) {
        this.url = requireNonNull(jdbcUrl);
        this.userName = requireNonNull(userName);
        this.password = requireNonNull(password);
        this.refreshInterval = requireNonNull(refreshInterval);
        this.columnTypeMap = requireNonNull(columnTypeMap);
        if (columnTypeMap.size() < 1) {
            throw new IllegalArgumentException();
        }
        this.primaryKeyColumnNames = requireNonNull(primaryKeyColumnNames);
        if (primaryKeyColumnNames.length < 1) {
            throw new IllegalArgumentException();
        }

        this.sql = requireNonNull(sql);
        this.myName = format("%s: %s %s", this.getClass().getSimpleName(), url, sql.substring(0, sql.length() > 20 ? 20 : sql.length()));

        final DimensionTable that = this;
        new ScheduledThreadPoolExecutor(1, Threads.threadsNamed(myName)).
                scheduleWithFixedDelay(new Runnable() {
                    @Override
                    public void run() {
                        DataSource dataSource = newDataSource();
                        try (
                             Connection connection = dataSource.getConnection();
                             PreparedStatement preparedStatement = connection.prepareStatement(sql);
                             ResultSet resultSet = preparedStatement.executeQuery()
                        ) {
                            long pre = System.currentTimeMillis();
                            logger.info("begin to load {}", myName);
                            TableBuilder tableBuilder = new TableBuilder(columnTypeMap);

                            if (resultSet.getMetaData().getColumnCount() != columnTypeMap.size()) {
                                throw new InconsistentColumnSizeException();
                            }
                            int row = 0;
                            while (resultSet.next()) {
                                if (debug(row)) {
                                    break;
                                }

                                int i = 0;
                                for (Type type : columnTypeMap.values()) {
                                    int i1 = i + 1;
                                    switch (type) {
                                        case INT:
                                            tableBuilder.append(i, resultSet.getInt(i1));
                                            break;
                                        case BIGINT:
                                            tableBuilder.append(i, resultSet.getLong(i1));
                                            break;
                                        case DOUBLE:
                                            tableBuilder.append(i, resultSet.getDouble(i1));
                                            break;
                                        case VARBYTE:
                                            tableBuilder.append(i, resultSet.getString(i1));
                                            break;
                                        default:
                                            throw new UnknownTypeException(type.name());
                                    }
                                    i++;
                                }
                                row++;

                                long now = System.currentTimeMillis();
                                if (now - pre > 5000) {
                                    logger.info("{} have loaded {} rows", myName, row);
                                    pre = now;
                                }
                            }

                            Table table = tableBuilder.build();
                            Index index = table.createIndex(primaryKeyColumnNames);
                            tableIndex = new TableIndex(table, index);
                            callback(that);
                            logger.info("end to load {}, rows: {}, index.size: {}", myName, row, index.getColumns2Rows().size());
                        } catch (Throwable t) {
                            logger.error("", t);
                            try {
                                Thread.sleep(10_000);
                                run();
                            } catch (Throwable t1) {
                                logger.error("", t1);
                            }
                        }
                    }
                }, 0, refreshInterval.toMillis(), TimeUnit.MILLISECONDS);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy