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 metode | Deskripsi |
|---|---|
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:
| Bidang | Tipe | Deskripsi |
|---|---|---|
columns | List<String> | Nama kolom dalam hasil yang dikembalikan |
metadata | List<String> | Tipe data kolom |
rows | List<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]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, danCallbackuntuk penanganan berbasis eventPenulisan sinkron dengan memanggil
.join()padaCompletableFutureyang 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 metode | Deskripsi |
|---|---|
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.");
}
}
});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 metode | Deskripsi |
|---|---|
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);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 metode | Deskripsi |
|---|---|
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:
| Parameter | Tipe | Deskripsi |
|---|---|---|
database | String | Nama database yang akan di-query |
sql | String | Pernyataan SQL yang akan dieksekusi. Untuk sintaksis yang didukung, lihat Sintaksis SQL. |
chunkSize | int | Jumlah 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:
| Bidang | Tipe | Deskripsi |
|---|---|---|
columns | List<String> | Nama kolom dalam hasil query |
metadata | List<String> | Tipe data kolom. Lihat Tipe data. |
rows | List<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();
}Selalu panggil resultSet.close() setelah query selesai, baik sukses maupun gagal. Jika tidak, akan terjadi kebocoran koneksi.