All Products
Search
Document Center

Lindorm:Antarmuka

Last Updated:Mar 29, 2026

SDK LindormTSDB menyediakan tiga kategori antarmuka: antarmuka management untuk operasi DDL (Data Definition Language) dan DCL (Data Control Language), antarmuka write untuk memasukkan data time-series, serta antarmuka query untuk mengambil data menggunakan SQL.

Antarmuka management

Antarmuka management mengeksekusi pernyataan SQL terhadap LindormTSDB. Tersedia dua metode overloaded:

Signature metodeDeskripsi
Result execute(String sql)Mengeksekusi pernyataan SQL terhadap database default
Result execute(String database, String sql)Mengeksekusi pernyataan SQL terhadap database yang ditentukan

Objek Result berisi output eksekusi:

BidangTipeDeskripsi
columnsList<String>Nama kolom dalam hasil yang dikembalikan
metadataList<String>Tipe data kolom
rowsList<List<Object>>Hasil yang dikembalikan baris per baris

Manage database dan tabel

Gunakan pernyataan DDL untuk membuat, mendeskripsikan, dan menghapus database atau tabel. Contoh berikut menggambarkan siklus hidup lengkap dari pembuatan hingga penghapusan:

// 1. Daftar database yang ada.
String showDatabase = "show databases";
Result result = lindormTSDBClient.execute(showDatabase);
System.out.println("sebelum dibuat, daftar db: " +
    result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));

// 2. Buat database bernama "demo".
String createDatabase = "create database demo";
result = lindormTSDBClient.execute(createDatabase);
System.out.println("buat database:" + result.isSuccessful());

// 3. Verifikasi database telah dibuat.
result = lindormTSDBClient.execute(showDatabase);
System.out.println("setelah dibuat, daftar db: " +
    result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));

String database = "demo";

// 4. Daftar tabel yang ada di database.
String showTables = "show tables";
result = lindormTSDBClient.execute(database, showTables);
System.out.println("sebelum dibuat, daftar tabel: " +
    result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));

// 5. Buat tabel.
String createTable = "CREATE TABLE sensor (device_id VARCHAR TAG, region VARCHAR TAG, " +
    "time BIGINT, temperature DOUBLE, humidity DOUBLE, PRIMARY KEY(device_id))";
result = lindormTSDBClient.execute(database, createTable);
System.out.println("buat tabel: " + result.isSuccessful());

// 6. Verifikasi tabel telah dibuat.
result = lindormTSDBClient.execute(database, showTables);
System.out.println("setelah dibuat, daftar tabel: " +
    result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));

// 7. Deskripsikan skema tabel.
String describeTable = "describe table sensor";
result = lindormTSDBClient.execute(database, describeTable);
System.out.println("------------ deskripsi tabel -------------------");
List<String> columns = result.getColumns();
System.out.println("columns: " + columns);
List<String> metadata = result.getMetadata();
System.out.println("metadata: " + metadata);
List<List<Object>> rows = result.getRows();
for (int i = 0, size = rows.size(); i < size; i++) {
    List<Object> row = rows.get(i);
    System.out.println("kolom #" + i + " : " + row);
}
System.out.println("------------ deskripsi tabel -------------------");

// 8. Hapus tabel.
String dropTable = "drop table sensor";
result = lindormTSDBClient.execute(database, dropTable);
System.out.println("hapus tabel: " + result.isSuccessful());

// 9. Verifikasi tabel telah dihapus.
result = lindormTSDBClient.execute(database, showTables);
System.out.println("setelah dihapus, daftar tabel: " +
    result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));

// 10. Hapus database.
String dropDatabase = "drop database demo";
result = lindormTSDBClient.execute(dropDatabase);
System.out.println("hapus database:" + result.isSuccessful());

// 11. Verifikasi database telah dihapus.
result = lindormTSDBClient.execute(showDatabase);
System.out.println("setelah dihapus, daftar db : " +
    result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));

Output yang diharapkan:

sebelum dibuat, daftar db: [default]
buat database:true
setelah dibuat, daftar db: [default, demo]
sebelum dibuat, daftar tabel: []
buat tabel: true
setelah dibuat, daftar tabel: [sensor]
------------ deskripsi tabel -------------------
columns: [columnName, typeName, columnKind]
metadata: [VARCHAR, VARCHAR, VARCHAR]
kolom #0 : [device_id, VARCHAR, TAG]
kolom #1 : [region, VARCHAR, TAG]
kolom #2 : [time, TIMESTAMP, TIMESTAMP]
kolom #3 : [temperature, DOUBLE, FIELD]
kolom #4 : [humidity, DOUBLE, FIELD]
------------ deskripsi tabel -------------------
hapus tabel: true
setelah dihapus, daftar tabel: []
hapus database:true
setelah dihapus, daftar db : [default]
Catatan

Operasi DDL untuk continuous query tidak dibahas di sini. Untuk sintaksis SQL lengkap yang didukung oleh LindormTSDB, lihat Sintaksis SQL.

Membuat antarmuka

Secara default, SDK LindormTSDB menulis data secara asinkron untuk memaksimalkan throughput. Antarmuka write mendukung:

  • Penulisan satu record dan batch (penulisan batch mengurangi kontensi lock pada antrian asinkron dan direkomendasikan)

  • Dua pola penanganan hasil: CompletableFuture<WriteResult> untuk pemrosesan inline, dan Callback untuk penanganan berbasis event

  • Penulisan sinkron dengan memanggil .join() pada CompletableFuture yang dikembalikan

Buat record write

Objek Record menyimpan satu baris data untuk ditulis. Tentukan nama tabel, timestamp, tag, dan nilai field:

Record record = Record
    .table("sensor")                    // Nama tabel
    .time(currentTime)                  // Timestamp dalam milidetik
    .tag("device_id", "F07A1260")       // Tag: dimensi key-value yang diindeks
    .tag("region", "north-cn")
    .addField("temperature", 12.1)      // Field: nilai metrik non-indeks
    .addField("humidity", 45.0)
    .build();

Secara default, SDK memvalidasi karakter yang valid saat membangun objek Record. Berikan parameter false ke metode build() untuk melewati validasi tersebut.

Write dengan CompletableFuture

Semua metode overloaded mengembalikan CompletableFuture<WriteResult>. Gunakan penulisan batch untuk mengurangi kontensi lock pada antrian asinkron.

Signature metodeDeskripsi
CompletableFuture<WriteResult> write(Record record)Menulis satu record ke database default
CompletableFuture<WriteResult> write(String database, Record record)Menulis satu record ke database yang ditentukan
CompletableFuture<WriteResult> write(List<Record> records)Menulis batch record ke database default (direkomendasikan)
CompletableFuture<WriteResult> write(String database, List<Record> records)Menulis batch record ke database yang ditentukan (direkomendasikan)

Satu record:

// Database default
CompletableFuture<WriteResult> future = lindormTSDBClient.write(record);

// Database yang ditentukan
String database = "demo";
CompletableFuture<WriteResult> future = lindormTSDBClient.write(database, record);

Penulisan batch (direkomendasikan):

List<Record> records;

// Database default
CompletableFuture<WriteResult> future = lindormTSDBClient.write(records);

// Database yang ditentukan
String database = "demo";
CompletableFuture<WriteResult> future = lindormTSDBClient.write(database, records);

Penanganan hasil:

CompletableFuture<WriteResult> future = lindormTSDBClient.write(records);

future.whenComplete((r, ex) -> {
    if (ex != null) {
        // Pengiriman write gagal.
        System.out.println("Gagal menulis.");
        Throwable throwable = ExceptionUtils.getRootCause(ex);
        if (throwable instanceof LindormTSDBException) {
            LindormTSDBException e = (LindormTSDBException) throwable;
            System.out.println("Kode kesalahan: " + e.getCode());
            System.out.println("SQL state:  " + e.getSqlstate());
            System.out.println("Pesan kesalahan: " + e.getMessage());
        } else {
            throwable.printStackTrace();
        }
    } else {
        // Write selesai.
        if (r.isSuccessful()) {
            System.out.println("Berhasil menulis.");
        } else {
            System.out.println("Gagal menulis.");
        }
    }
});
Penting

Hindari menjalankan perhitungan kompleks atau yang memakan waktu di dalam whenComplete. Pindahkan pekerjaan tersebut ke kolam thread independen. Untuk detail kode kesalahan, lihat Kode kesalahan umum.

Write dengan callback

Berikan Callback ke metode write(). Metode onCompletion menerima hasil write, record terkait, dan exception (jika ada).

public interface Callback {
    void onCompletion(WriteResult result, List<Record> records, Throwable e);
}
Signature metodeDeskripsi
write(Record record, Callback callback)Menulis satu record ke database default dengan callback
write(String database, Record record, Callback callback)Menulis satu record ke database yang ditentukan dengan callback
write(List<Record> records, Callback callback)Menulis batch record ke database default dengan callback (direkomendasikan)
write(String database, List<Record> records, Callback callback)Menulis batch record ke database yang ditentukan dengan callback (direkomendasikan)

Implementasikan dan berikan callback:

Callback callback = new Callback() {
    @Override
    public void onCompletion(WriteResult result, List<Record> list, Throwable throwable) {
        if (throwable != null) {
            // Write gagal.
            if (throwable instanceof LindormTSDBException) {
                LindormTSDBException ex = (LindormTSDBException) throwable;
                System.out.println("errorCode: " + ex.getCode());
                System.out.println("sqlstate: " + ex.getSqlstate());
                System.out.println("message: " + ex.getMessage());
            } else {
                throwable.printStackTrace();
            }
        } else {
            if (result.isSuccessful()) {
                System.out.println("Berhasil menulis.");
            } else {
                System.out.println("Gagal menulis.");
            }
        }
    }
};

// Penulisan batch — direkomendasikan
List<Record> records;
lindormTSDBClient.write(records, callback);

// Satu record
lindormTSDBClient.write(record, callback);
Penting

Hindari menjalankan perhitungan kompleks atau yang memakan waktu di dalam onCompletion. Pindahkan pekerjaan tersebut ke kolam thread independen. Untuk detail kode kesalahan, lihat Kode kesalahan umum.

Antarmuka query

Antarmuka query mengeksekusi pernyataan SQL dan mengalirkan hasilnya dalam chunk. Semua metode overloaded mengembalikan ResultSet.

Signature metodeDeskripsi
ResultSet query(String sql)Melakukan query ke database default; mengembalikan maksimal 1.000 baris per chunk
ResultSet query(String database, String sql)Melakukan query ke database yang ditentukan; mengembalikan maksimal 1.000 baris per chunk
ResultSet query(String database, String sql, int chunkSize)Melakukan query ke database yang ditentukan dengan ukuran chunk kustom

Parameter:

ParameterTipeDeskripsi
databaseStringNama database yang akan di-query
sqlStringPernyataan SQL yang akan dieksekusi. Untuk sintaksis yang didukung, lihat Sintaksis SQL.
chunkSizeintJumlah baris yang dikembalikan per batch. Default: 1.000.

Proses hasil query

Iterasi ResultSet dengan next() hingga mengembalikan null, lalu tutup result set untuk melepaskan sumber daya I/O:

public interface ResultSet extends Closeable {
    QueryResult next();
    void close();
}

Setiap objek QueryResult berisi:

BidangTipeDeskripsi
columnsList<String>Nama kolom dalam hasil query
metadataList<String>Tipe data kolom. Lihat Tipe data.
rowsList<List<Object>>Hasil query yang dikembalikan baris per baris

Contoh:

String sql = "select * from sensor";
int chunkSize = 100;
ResultSet resultSet = lindormTSDBClient.query("demo", sql, chunkSize);

try {
    QueryResult result = null;
    // Iterasi hingga next() mengembalikan null — semua hasil telah diambil.
    while ((result = resultSet.next()) != null) {
        List<String> columns = result.getColumns();
        System.out.println("columns: " + columns);
        List<String> metadata = result.getMetadata();
        System.out.println("metadata: " + metadata);
        List<List<Object>> rows = result.getRows();
        for (int i = 0, size = rows.size(); i < size; i++) {
            List<Object> row = rows.get(i);
            System.out.println("baris #" + i + " : " + row);
        }
    }
} finally {
    // Selalu tutup ResultSet setelah query — baik sukses maupun gagal.
    resultSet.close();
}
Penting

Selalu panggil resultSet.close() setelah query selesai, baik sukses maupun gagal. Jika tidak, akan terjadi kebocoran koneksi.