Skip to content

Commit c540289

Browse files
author
喆宇
committed
support writing schema metadata through java LanceFileWriter API.
1 parent abce5a5 commit c540289

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

java/lance-jni/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

java/lance-jni/src/file_writer.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,37 @@ pub extern "system" fn Java_com_lancedb_lance_file_LanceFileWriter_closeNative<'
149149
JObject::null()
150150
}
151151

152+
#[no_mangle]
153+
pub extern "system" fn Java_com_lancedb_lance_file_LanceFileWriter_nativeWriteSchemaMetadata<
154+
'local,
155+
>(
156+
mut env: JNIEnv<'local>,
157+
writer: JObject,
158+
schema_metadata: JObject, // Map<String, String>
159+
) -> JObject<'local> {
160+
if let Err(e) = inner_write_schema_metadata(&mut env, writer, schema_metadata) {
161+
e.throw(&mut env);
162+
return JObject::null();
163+
}
164+
JObject::null()
165+
}
166+
167+
fn inner_write_schema_metadata(
168+
env: &mut JNIEnv<'_>,
169+
writer: JObject,
170+
schema_metadata: JObject, // Map<String, String>
171+
) -> Result<()> {
172+
let metadata_map = JMap::from_env(env, &schema_metadata)?;
173+
let metadata = to_rust_map(env, &metadata_map)?;
174+
let writer_guard =
175+
unsafe { env.get_rust_field::<_, _, BlockingFileWriter>(writer, NATIVE_WRITER) }?;
176+
let mut writer = writer_guard.inner.lock().unwrap();
177+
metadata.into_iter().for_each(|(k, v)| {
178+
writer.add_schema_metadata(k, v);
179+
});
180+
Ok(())
181+
}
182+
152183
#[no_mangle]
153184
pub extern "system" fn Java_com_lancedb_lance_file_LanceFileWriter_writeNative<'local>(
154185
mut env: JNIEnv<'local>,

java/src/main/java/com/lancedb/lance/file/LanceFileWriter.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ public void write(VectorSchemaRoot batch) throws IOException {
120120
}
121121
}
122122

123+
/**
124+
* Write a schema metadata map to underlying file. User can retrieve those values from {@link
125+
* LanceFileReader#schema() reader schema}.
126+
*
127+
* @param metadata metadata
128+
* @throws IOException IOException
129+
*/
130+
public void writeSchemaMetadata(Map<String, String> metadata) throws IOException {
131+
nativeWriteSchemaMetadata(metadata);
132+
}
133+
134+
private native void nativeWriteSchemaMetadata(Map<String, String> metadata) throws IOException;
135+
123136
/**
124137
* Close the LanceFileWriter
125138
*

java/src/test/java/com/lancedb/lance/FileReaderWriterTest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.arrow.vector.types.pojo.Field;
2828
import org.apache.arrow.vector.types.pojo.Schema;
2929
import org.apache.arrow.vector.util.Text;
30+
import org.junit.jupiter.api.Assertions;
3031
import org.junit.jupiter.api.Test;
3132
import org.junit.jupiter.api.io.TempDir;
3233

@@ -258,4 +259,47 @@ void testInvalidPath() {
258259
} catch (IOException e) {
259260
}
260261
}
262+
263+
@Test
264+
void testWriteSchemaMetadata(@TempDir Path tempDir) throws Exception {
265+
String filePath = tempDir.resolve("write_schema_metadata.lance").toString();
266+
BufferAllocator allocator = new RootAllocator();
267+
try (LanceFileWriter writer = LanceFileWriter.open(filePath, allocator, null)) {
268+
try (VectorSchemaRoot batch = createBatch(allocator)) {
269+
writer.write(batch);
270+
writer.writeSchemaMetadata(Collections.singletonMap("testKey", "testValue"));
271+
writer.write(batch);
272+
// repeatedly write
273+
writer.writeSchemaMetadata(Collections.singletonMap("testKey1", "testValue1"));
274+
}
275+
}
276+
277+
try (LanceFileReader reader = LanceFileReader.open(filePath, allocator)) {
278+
Schema fileSchema = reader.schema();
279+
Map<String, String> metadata = fileSchema.getCustomMetadata();
280+
281+
Assertions.assertTrue(metadata.containsKey("testKey"));
282+
Assertions.assertEquals("testValue", metadata.get("testKey"));
283+
284+
Assertions.assertTrue(metadata.containsKey("testKey1"));
285+
Assertions.assertEquals("testValue1", metadata.get("testKey1"));
286+
}
287+
}
288+
289+
@Test
290+
void testWriteNullSchemaMetadata(@TempDir Path tempDir) throws Exception {
291+
String filePath = tempDir.resolve("write_null_schema_metadata.lance").toString();
292+
BufferAllocator allocator = new RootAllocator();
293+
try (LanceFileWriter writer = LanceFileWriter.open(filePath, allocator, null)) {
294+
try (VectorSchemaRoot batch = createBatch(allocator)) {
295+
writer.write(batch);
296+
Assertions.assertThrows(
297+
Exception.class,
298+
() -> writer.writeSchemaMetadata(Collections.singletonMap("someKey", null)));
299+
Assertions.assertThrows(
300+
Exception.class,
301+
() -> writer.writeSchemaMetadata(Collections.singletonMap(null, "someValue")));
302+
}
303+
}
304+
}
261305
}

0 commit comments

Comments
 (0)