content: /*
   * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *      http://www.apache.org/licenses/LICENSE-2.0
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package me.ahoo.cosid.jdbc;
  
  import lombok.extern.slf4j.Slf4j;
  
  import javax.sql.DataSource;
  import java.sql.Connection;
  import java.sql.PreparedStatement;
  import java.sql.SQLException;
  
  /**
   * Jdbc MachineId Initializer.
   *
   * @author ahoo wang
   */
  @Slf4j
  public class JdbcMachineIdInitializer {
      private static final String INIT_COSID_MACHINE_TABLE_SQL =
          "create table if not exists cosid_machine\n"
              + "(\n"
              + "    name            varchar(100)     not null comment '{namespace}.{machine_id}',\n"
              + "    namespace       varchar(100)     not null,\n"
              + "    machine_id      integer unsigned not null default 0,\n"
              + "    last_timestamp  bigint unsigned  not null default 0,\n"
              + "    instance_id     varchar(100)     not null default '',\n"
              + "    distribute_time bigint unsigned  not null default 0,\n"
              + "    revert_time     bigint unsigned  not null default 0,\n"
              + "    constraint cosid_machine_pk\n"
              + "        primary key (name)\n"
              + ") engine = InnoDB;";
      
      private static final String INIT_NAMESPACE_IDX_SQL =
          "create index if not exists idx_namespace on cosid_machine (namespace);";
      
      private static final String INIT_INSTANCE_ID_IDX_SQL =
          "create index if not exists idx_instance_id on cosid_machine (instance_id);";
      
      private final DataSource dataSource;
      
      private final String initCosIdMachineTableSql;
      private final String initNamespaceIdxSql;
      private final String initInstanceIdIdxSql;
      
      public JdbcMachineIdInitializer(DataSource dataSource) {
          this(dataSource, INIT_COSID_MACHINE_TABLE_SQL, INIT_NAMESPACE_IDX_SQL, INIT_INSTANCE_ID_IDX_SQL);
      }
      
      public JdbcMachineIdInitializer(DataSource dataSource, String initCosIdMachineTableSql, String initNamespaceIdxSql, String initInstanceIdIdxSql) {
          this.dataSource = dataSource;
          this.initCosIdMachineTableSql = initCosIdMachineTableSql;
          this.initNamespaceIdxSql = initNamespaceIdxSql;
          this.initInstanceIdIdxSql = initInstanceIdIdxSql;
      }
      
      public void initCosIdMachineTable() throws SQLException {
          if (log.isInfoEnabled()) {
              log.info("Init CosIdMachineTable");
          }
          
          try (Connection connection = dataSource.getConnection()) {
              try (PreparedStatement initStatement = connection.prepareStatement(initCosIdMachineTableSql)) {
                  initStatement.executeUpdate();
              }
              try (PreparedStatement createNamespaceIdxStatement = connection.prepareStatement(initNamespaceIdxSql)) {
                  createNamespaceIdxStatement.executeUpdate();
              }
              try (PreparedStatement createInstanceIdIdxStatement = connection.prepareStatement(initInstanceIdIdxSql)) {
                  createInstanceIdIdxStatement.executeUpdate();
              }
          }
      }
      
      public boolean tryInitCosIdMachineTable() {
          try {
              initCosIdMachineTable();
              return true;
          } catch (Throwable throwable) {
              if (log.isInfoEnabled()) {
                  log.info("Try Init CosIdMachineTable failed.[{}]", throwable.getMessage());
              }
              return false;
          }
      }
  }
  