Skip to content

Instantly share code, notes, and snippets.

@aoetk
Created December 22, 2024 15:11
Show Gist options
  • Save aoetk/04ef7a767b016348ccca346d0b6cb8a0 to your computer and use it in GitHub Desktop.
Save aoetk/04ef7a767b016348ccca346d0b6cb8a0 to your computer and use it in GitHub Desktop.
SQLファイルとしてTsurugi上のテーブルデータをダンプするコード
package com.example.tsurugi;
import com.tsurugidb.iceaxe.TsurugiConnector;
import com.tsurugidb.iceaxe.session.TsurugiSession;
import com.tsurugidb.iceaxe.sql.result.TsurugiResultEntity;
import com.tsurugidb.iceaxe.transaction.option.TgTxOption;
import com.tsurugidb.sql.proto.SqlCommon;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static java.nio.file.StandardOpenOption.*;
public class TsurugiSqlDumper {
private final URI dbUrl;
private final String tableName;
private final Path outputDir;
public TsurugiSqlDumper(URI dbUrl, String tableName, Path outputDir) {
this.dbUrl = dbUrl;
this.tableName = tableName;
this.outputDir = outputDir;
}
public void dump() throws Exception {
var fileName = "insert_" + tableName + ".sql";
var filePath = outputDir.resolve(fileName);
var connector = TsurugiConnector.of(dbUrl);
var sql = "select * from " + tableName;
try (TsurugiSession session = connector.createSession();
var writer = new PrintWriter(Files.newBufferedWriter(filePath, WRITE, CREATE, TRUNCATE_EXISTING))) {
writer.println("start long transaction write preserve " + tableName + ";");
var metadata = session.findTableMetadata(tableName).orElseThrow();
List<? extends SqlCommon.Column> columnList = metadata.getLowColumnList();
var columnNameList = columnList.stream().map(SqlCommon.Column::getName).toList();
var tm = session.createTransactionManager(TgTxOption.ofRTX());
var resultList = tm.executeAndGetList(sql);
for (TsurugiResultEntity entity : resultList) {
var builder = new StringBuilder("insert or replace into ");
builder.append(tableName).append(" (").append(String.join(",", columnNameList)).append(") values (");
var valuesString = columnList.stream().map(column -> getValueString(entity, column)).toList();
builder.append(String.join(",", valuesString)).append(");");
writer.println(builder);
}
writer.println("commit;");
}
}
private String getValueString(TsurugiResultEntity entity, SqlCommon.Column column) {
var atomType = column.getAtomType();
var columnName = column.getName();
return switch (atomType) {
case INT4 -> entity.findInt(columnName).map(value -> Integer.toString(value)).orElse("NULL");
case INT8 -> entity.findLong(columnName).map(value -> Long.toString(value)).orElse("NULL");
case FLOAT4 -> entity.findFloat(columnName).map(value -> Float.toString(value)).orElse("NULL");
case FLOAT8 -> entity.findDouble(columnName).map(value -> Double.toString(value)).orElse("NULL");
case DECIMAL -> entity.findDecimal(columnName).map(BigDecimal::toPlainString).orElse("NULL");
case CHARACTER -> entity.findString(columnName).map(value -> "'" + value + "'").orElse("NULL");
case DATE -> entity.findDate(columnName).map(value -> "date '" + value + "'").orElse("NULL");
case TIME_POINT -> entity.findDateTime(columnName).map(value -> "timestamp '" + value + "'").orElse("NULL");
case TIME_POINT_WITH_TIME_ZONE ->
entity.findOffsetDateTime(columnName).map(value -> "timestamp with time zone '" + value + "'")
.orElse("NULL");
default -> "NULL";
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment