Skip to content

Commit d40f4c9

Browse files
authored
Merge pull request #8 from Embucket/write-metadata-file
Write metadata file
2 parents d5dd55e + cb32f4f commit d40f4c9

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

crates/catalog/src/service.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
use object_store::path::Path;
12
use async_trait::async_trait;
2-
use object_store::CredentialProvider;
3+
use object_store::{CredentialProvider, ObjectStore, PutPayload};
34
use std::collections::HashMap;
45
use std::fmt::Debug;
56
use std::sync::Arc;
6-
7+
use bytes::Bytes;
78
use control_plane::models::Warehouse;
89
use iceberg::{spec::TableMetadataBuilder, TableCreation};
9-
10+
use object_store::local::LocalFileSystem;
11+
use tokio::fs;
12+
use uuid::Uuid;
1013
use crate::error::{Error, Result}; // TODO: Replace this with this crate error and result
1114
use crate::models::{
1215
Config, Database, DatabaseIdent, Table, TableCommit, TableIdent, TableRequirementExt,
@@ -108,14 +111,17 @@ impl Catalog for CatalogImpl {
108111
.map(TableRequirementExt::new)
109112
.try_for_each(|req| req.assert(&table.metadata, true))?;
110113

114+
// TODO rewrite metadata file? need to research when metadata rewrite is needed
115+
// Currently the metadata file is only written once - during table creation
116+
111117
let mut builder =
112-
TableMetadataBuilder::new_from_metadata(table.metadata, Some(table.metadata_location));
118+
TableMetadataBuilder::new_from_metadata(table.metadata, Some(table.metadata_location.clone()));
113119

114120
for update in commit.updates {
115121
builder = update.apply(builder)?;
116122
}
117123
let result = builder.build()?;
118-
let metadata_location = result.metadata.location.clone();
124+
let metadata_location = table.metadata_location.clone();
119125
let metadata = result.metadata;
120126

121127
let table: Table = Table {
@@ -234,28 +240,40 @@ impl Catalog for CatalogImpl {
234240
// Take into account namespace location property if present
235241
// Take into account provided location if present
236242
// If none, generate location based on warehouse location
243+
let table_location = format!("{}/{}", warehouse.location, creation.name);
237244
let creation = {
238245
let mut creation = creation;
239-
creation.location = Some(format!("{}/{}", warehouse.location, creation.name));
246+
creation.location = Some(table_location.clone());
240247
creation
241248
};
242249
// TODO: Add checks
243250
// - Check if storage profile is valid (writtable)
244251

245252
let name = creation.name.to_string();
246253
let result = TableMetadataBuilder::from_table_creation(creation)?.build()?;
247-
let location = result.metadata.location.clone();
254+
let metadata = result.metadata.clone();
255+
let metadata_file_id = Uuid::new_v4().to_string();
256+
let metadata_relative_location = format!("{table_location}/metadata/{metadata_file_id}.metadata.json");
257+
// TODO un-hardcode "file://" and make it dynamic - filesystem or s3 (at least)
258+
let metadata_full_location = format!("file://object_store/{metadata_relative_location}");
248259

249260
let table = Table {
250-
metadata: result.metadata,
251-
metadata_location: location,
261+
metadata: metadata.clone(),
262+
metadata_location: metadata_full_location,
252263
ident: TableIdent {
253264
database: namespace.clone(),
254265
table: name.clone(),
255266
},
256267
};
257268
self.table_repo.put(&table).await?;
258-
// TODO: Write metadata contents to metadata_location
269+
270+
let local_dir = "object_store";
271+
fs::create_dir_all(local_dir).await.unwrap();
272+
let store = LocalFileSystem::new_with_prefix(local_dir).expect("Failed to initialize filesystem object store");
273+
let path = Path::from(metadata_relative_location);
274+
let json_data = serde_json::to_string(&table.metadata).unwrap();
275+
let content = Bytes::from(json_data);
276+
store.put(&path, PutPayload::from(content)).await.expect("Failed to write file");
259277

260278
Ok(table)
261279
}

crates/control_plane/src/service.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use uuid::Uuid;
88
use datafusion::prelude::*;
99
use iceberg_catalog_rest::{RestCatalog, RestCatalogConfig};
1010
use iceberg_datafusion::IcebergCatalogProvider;
11+
use datafusion::catalog_common::CatalogProvider;
1112
use std::collections::HashMap;
1213

1314
#[async_trait]
@@ -110,10 +111,14 @@ impl ControlService for ControlServiceImpl {
110111

111112
let catalog = RestCatalog::new(config);
112113

113-
// TODO need manifest file written before the code below works
114-
// let catalog = IcebergCatalogProvider::try_new(Arc::new(catalog))
115-
// .await
116-
// .unwrap();
114+
let catalog = IcebergCatalogProvider::try_new(Arc::new(catalog))
115+
.await
116+
.unwrap();
117+
118+
// Test that catalog loaded successfully
119+
println!("SCHEMAS: {:?}", catalog.schema_names());
120+
121+
// TODO rest of the query code
117122

118123
Ok(("OK"))
119124
}

0 commit comments

Comments
 (0)