diff --git a/Cargo.lock b/Cargo.lock index 4d392ef35f..502f25438b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1034,6 +1034,41 @@ dependencies = [ "winapi", ] +[[package]] +name = "darling" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "649c91bc01e8b1eac09fb91e8dbc7d517684ca6be8ebc75bb9cafc894f9fdb6f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "datafusion" version = "7.0.0" @@ -1163,6 +1198,37 @@ dependencies = [ "snafu", ] +[[package]] +name = "derive_builder" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07adf7be193b71cc36b193d0f5fe60b918a3a9db4dad0449f57bcfd519704a3" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" +dependencies = [ + "derive_builder_core", + "syn", +] + [[package]] name = "digest" version = "0.10.3" @@ -1647,6 +1713,12 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.2.3" @@ -3526,6 +3598,7 @@ dependencies = [ "common-error", "common-time", "datatypes", + "derive_builder", "futures", "object-store", "serde", @@ -3615,6 +3688,7 @@ dependencies = [ "datafusion", "datafusion-common", "datatypes", + "derive_builder", "futures", "serde", "snafu", diff --git a/src/storage/benches/memtable/util/regiondesc_util.rs b/src/storage/benches/memtable/util/regiondesc_util.rs index 71626cee20..a01d7d39c5 100644 --- a/src/storage/benches/memtable/util/regiondesc_util.rs +++ b/src/storage/benches/memtable/util/regiondesc_util.rs @@ -17,14 +17,15 @@ impl RegionDescBuilder { let key_builder = RowKeyDescriptorBuilder::new( ColumnDescriptorBuilder::new(2, TIMESTAMP_NAME, ConcreteDataType::int64_datatype()) .is_nullable(false) - .build(), + .build() + .unwrap(), ); Self { name: name.into(), last_column_id: 2, key_builder, - default_cf_builder: ColumnFamilyDescriptorBuilder::new(), + default_cf_builder: ColumnFamilyDescriptorBuilder::default(), } } @@ -38,8 +39,8 @@ impl RegionDescBuilder { RegionDescriptor { id: 0, name: self.name, - row_key: self.key_builder.build(), - default_cf: self.default_cf_builder.build(), + row_key: self.key_builder.build().unwrap(), + default_cf: self.default_cf_builder.build().unwrap(), extra_cfs: Vec::new(), } } @@ -54,5 +55,6 @@ impl RegionDescBuilder { ColumnDescriptorBuilder::new(self.alloc_column_id(), column_def.0, datatype) .is_nullable(column_def.2) .build() + .unwrap() } } diff --git a/src/storage/src/metadata.rs b/src/storage/src/metadata.rs index d98ae387e1..900df11905 100644 --- a/src/storage/src/metadata.rs +++ b/src/storage/src/metadata.rs @@ -316,6 +316,7 @@ fn version_column_desc() -> ColumnDescriptor { ) .is_nullable(false) .build() + .unwrap() } // TODO(yingwen): Add tests for using invalid row_key/cf to build metadata. @@ -381,20 +382,26 @@ mod tests { fn new_metadata(enable_version_column: bool) -> RegionMetadata { let timestamp = ColumnDescriptorBuilder::new(2, "ts", ConcreteDataType::int64_datatype()) .is_nullable(false) - .build(); + .build() + .unwrap(); let row_key = RowKeyDescriptorBuilder::new(timestamp) .push_column( ColumnDescriptorBuilder::new(3, "k1", ConcreteDataType::int64_datatype()) .is_nullable(false) - .build(), + .build() + .unwrap(), ) .enable_version_column(enable_version_column) - .build(); - let cf = ColumnFamilyDescriptorBuilder::new() + .build() + .unwrap(); + let cf = ColumnFamilyDescriptorBuilder::default() .push_column( - ColumnDescriptorBuilder::new(4, "v1", ConcreteDataType::int64_datatype()).build(), + ColumnDescriptorBuilder::new(4, "v1", ConcreteDataType::int64_datatype()) + .build() + .unwrap(), ) - .build(); + .build() + .unwrap(); RegionMetadataBuilder::new() .row_key(row_key) .unwrap() diff --git a/src/storage/src/test_util/descriptor_util.rs b/src/storage/src/test_util/descriptor_util.rs index ad221a3e4e..0e374279de 100644 --- a/src/storage/src/test_util/descriptor_util.rs +++ b/src/storage/src/test_util/descriptor_util.rs @@ -24,7 +24,8 @@ impl RegionDescBuilder { ConcreteDataType::int64_datatype(), ) .is_nullable(false) - .build(), + .build() + .unwrap(), ); Self { @@ -32,7 +33,7 @@ impl RegionDescBuilder { name: name.into(), last_column_id: 2, key_builder, - default_cf_builder: ColumnFamilyDescriptorBuilder::new(), + default_cf_builder: ColumnFamilyDescriptorBuilder::default(), } } @@ -43,8 +44,17 @@ impl RegionDescBuilder { // This will reset the row key builder, so should be called before `push_key_column()` // and `enable_version_column()`, or just call after `new()`. + // + // NOTE(ning): it's now possible to change this function to: + // + // ``` + // self.key_builder.timestamp(self.new_column(column_def)) + // ``` + // to resolve the constraint above + pub fn timestamp(mut self, column_def: ColumnDef) -> Self { let builder = RowKeyDescriptorBuilder::new(self.new_column(column_def)); + self.key_builder = builder; self } @@ -70,8 +80,8 @@ impl RegionDescBuilder { RegionDescriptor { id: self.id, name: self.name, - row_key: self.key_builder.build(), - default_cf: self.default_cf_builder.build(), + row_key: self.key_builder.build().unwrap(), + default_cf: self.default_cf_builder.build().unwrap(), extra_cfs: Vec::new(), } } @@ -86,5 +96,6 @@ impl RegionDescBuilder { ColumnDescriptorBuilder::new(self.alloc_column_id(), column_def.0, datatype) .is_nullable(column_def.2) .build() + .unwrap() } } diff --git a/src/store-api/Cargo.toml b/src/store-api/Cargo.toml index 6b6493686a..2e084fc277 100644 --- a/src/store-api/Cargo.toml +++ b/src/store-api/Cargo.toml @@ -16,6 +16,7 @@ futures = "0.3" object-store = { path = "../object-store" } serde = { version = "1.0", features = ["derive"] } snafu = { version = "0.7", features = ["backtraces"] } +derive_builder = "0.11" [dev-dependencies] async-stream = "0.3" diff --git a/src/store-api/src/lib.rs b/src/store-api/src/lib.rs index 2ab02d5077..ab381487f0 100644 --- a/src/store-api/src/lib.rs +++ b/src/store-api/src/lib.rs @@ -1,5 +1,4 @@ //! Storage related APIs - pub mod logstore; pub mod manifest; pub mod storage; diff --git a/src/store-api/src/storage/descriptors.rs b/src/store-api/src/storage/descriptors.rs index 6fbe5910db..e2b149f069 100644 --- a/src/store-api/src/storage/descriptors.rs +++ b/src/store-api/src/storage/descriptors.rs @@ -1,4 +1,5 @@ use datatypes::value::Value; +use derive_builder::Builder; use serde::{Deserialize, Serialize}; use crate::manifest::MetadataId; @@ -20,19 +21,35 @@ pub fn gen_region_name(id: RegionId) -> String { // TODO(yingwen): Validate default value has same type with column, and name is a valid column name. /// A [ColumnDescriptor] contains information to create a column. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Builder)] +#[builder(pattern = "owned")] pub struct ColumnDescriptor { pub id: ColumnId, + #[builder(setter(into))] pub name: String, pub data_type: ConcreteDataType, /// Is column nullable, default is true. + #[builder(default = "true")] pub is_nullable: bool, /// Default value of column, default is None, which means no default value /// for this column, and user must provide value for a not-null column. + #[builder(default)] pub default_value: Option, + #[builder(default, setter(into))] pub comment: String, } +impl ColumnDescriptorBuilder { + pub fn new>(id: ColumnId, name: S, data_type: ConcreteDataType) -> Self { + Self { + id: Some(id), + name: Some(name.into()), + data_type: Some(data_type), + ..Default::default() + } + } +} + impl From<&ColumnDescriptor> for ColumnSchema { fn from(desc: &ColumnDescriptor) -> ColumnSchema { ColumnSchema::new(&desc.name, desc.data_type.clone(), desc.is_nullable) @@ -40,32 +57,39 @@ impl From<&ColumnDescriptor> for ColumnSchema { } /// A [RowKeyDescriptor] contains information about row key. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Builder)] +#[builder(pattern = "owned")] pub struct RowKeyDescriptor { + #[builder(default)] pub columns: Vec, /// Timestamp key column. pub timestamp: ColumnDescriptor, /// Enable version column in row key if this field is true. /// - /// The default value is true. - // FIXME(yingwen): Change default value to true (Disable version column by default). + /// The default value is false. + #[builder(default = "false")] pub enable_version_column: bool, } /// A [ColumnFamilyDescriptor] contains information to create a column family. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Builder)] pub struct ColumnFamilyDescriptor { + #[builder(default = "consts::DEFAULT_CF_ID")] pub cf_id: ColumnFamilyId, + #[builder(default = "consts::DEFAULT_CF_NAME.to_string()", setter(into))] pub name: String, /// Descriptors of columns in this column family. + #[builder(default)] pub columns: Vec, } /// A [RegionDescriptor] contains information to create a region. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Builder)] +#[builder(pattern = "owned")] pub struct RegionDescriptor { pub id: RegionId, /// Region name. + #[builder(setter(into))] pub name: String, /// Row key descriptor of this region. pub row_key: RowKeyDescriptor, @@ -75,154 +99,51 @@ pub struct RegionDescriptor { pub extra_cfs: Vec, } -pub struct ColumnDescriptorBuilder { - id: ColumnId, - name: String, - data_type: ConcreteDataType, - is_nullable: bool, - default_value: Option, - comment: String, -} - -impl ColumnDescriptorBuilder { - pub fn new>(id: ColumnId, name: T, data_type: ConcreteDataType) -> Self { - Self { - id, - name: name.into(), - data_type, - is_nullable: true, - default_value: None, - comment: "".to_string(), - } - } - - pub fn is_nullable(mut self, is_nullable: bool) -> Self { - self.is_nullable = is_nullable; - self - } - - pub fn default_value(mut self, value: Option) -> Self { - self.default_value = value; - self - } - - pub fn comment>(mut self, comment: T) -> Self { - self.comment = comment.into(); - self - } - - pub fn build(self) -> ColumnDescriptor { - ColumnDescriptor { - id: self.id, - name: self.name, - data_type: self.data_type, - is_nullable: self.is_nullable, - default_value: self.default_value, - comment: self.comment, - } - } -} - -pub struct RowKeyDescriptorBuilder { - columns: Vec, - timestamp: ColumnDescriptor, - enable_version_column: bool, -} - impl RowKeyDescriptorBuilder { pub fn new(timestamp: ColumnDescriptor) -> Self { Self { - columns: Vec::new(), - timestamp, - enable_version_column: false, + timestamp: Some(timestamp), + ..Default::default() } } pub fn columns_capacity(mut self, capacity: usize) -> Self { - self.columns.reserve(capacity); + self.columns = Some(Vec::with_capacity(capacity)); self } pub fn push_column(mut self, column: ColumnDescriptor) -> Self { - self.columns.push(column); + let columns = self.columns.get_or_insert_with(Vec::new); + columns.push(column); self } - - pub fn enable_version_column(mut self, enable: bool) -> Self { - self.enable_version_column = enable; - self - } - - pub fn build(self) -> RowKeyDescriptor { - RowKeyDescriptor { - columns: self.columns, - timestamp: self.timestamp, - enable_version_column: self.enable_version_column, - } - } -} - -pub struct ColumnFamilyDescriptorBuilder { - cf_id: ColumnFamilyId, - name: String, - columns: Vec, } impl ColumnFamilyDescriptorBuilder { - pub fn new() -> Self { - Self { - cf_id: consts::DEFAULT_CF_ID, - name: consts::DEFAULT_CF_NAME.to_string(), - columns: Vec::new(), - } - } - - pub fn cf_id(mut self, cf_id: ColumnFamilyId) -> Self { - self.cf_id = cf_id; - self - } - - pub fn name>(mut self, name: T) -> Self { - self.name = name.into(); - self - } - pub fn columns_capacity(mut self, capacity: usize) -> Self { - self.columns.reserve(capacity); + self.columns = Some(Vec::with_capacity(capacity)); self } pub fn push_column(mut self, column: ColumnDescriptor) -> Self { - self.columns.push(column); + let columns = self.columns.get_or_insert_with(Vec::new); + columns.push(column); self } - - pub fn build(self) -> ColumnFamilyDescriptor { - ColumnFamilyDescriptor { - cf_id: self.cf_id, - name: self.name, - columns: self.columns, - } - } -} - -impl Default for ColumnFamilyDescriptorBuilder { - fn default() -> ColumnFamilyDescriptorBuilder { - ColumnFamilyDescriptorBuilder::new() - } } #[cfg(test)] mod tests { use super::*; + #[inline] fn new_column_desc_builder() -> ColumnDescriptorBuilder { ColumnDescriptorBuilder::new(3, "test", ConcreteDataType::int32_datatype()) } #[test] fn test_column_descriptor_builder() { - let desc = new_column_desc_builder().build(); + let desc = new_column_desc_builder().build().unwrap(); assert_eq!(3, desc.id); assert_eq!("test", desc.name); assert_eq!(ConcreteDataType::int32_datatype(), desc.data_type); @@ -230,73 +151,98 @@ mod tests { assert!(desc.default_value.is_none()); assert!(desc.comment.is_empty()); - let desc = new_column_desc_builder().is_nullable(false).build(); + let desc = new_column_desc_builder() + .is_nullable(false) + .build() + .unwrap(); assert!(!desc.is_nullable); let desc = new_column_desc_builder() .default_value(Some(Value::Null)) - .build(); + .build() + .unwrap(); assert_eq!(Value::Null, desc.default_value.unwrap()); let desc = new_column_desc_builder() .default_value(Some(Value::Int32(123))) - .build(); + .build() + .unwrap(); assert_eq!(Value::Int32(123), desc.default_value.unwrap()); - let desc = new_column_desc_builder().comment("A test column").build(); + let desc = new_column_desc_builder() + .comment("A test column") + .build() + .unwrap(); assert_eq!("A test column", desc.comment); } fn new_timestamp_desc() -> ColumnDescriptor { - ColumnDescriptorBuilder::new(5, "timestamp", ConcreteDataType::int64_datatype()).build() + ColumnDescriptorBuilder::new(5, "timestamp", ConcreteDataType::int64_datatype()) + .build() + .unwrap() } #[test] fn test_row_key_descriptor_builder() { let timestamp = new_timestamp_desc(); - let desc = RowKeyDescriptorBuilder::new(timestamp.clone()).build(); + let desc = RowKeyDescriptorBuilder::new(timestamp.clone()) + .build() + .unwrap(); assert!(desc.columns.is_empty()); assert!(!desc.enable_version_column); let desc = RowKeyDescriptorBuilder::new(timestamp.clone()) .columns_capacity(1) .push_column( - ColumnDescriptorBuilder::new(6, "c1", ConcreteDataType::int32_datatype()).build(), + ColumnDescriptorBuilder::new(6, "c1", ConcreteDataType::int32_datatype()) + .build() + .unwrap(), ) .push_column( - ColumnDescriptorBuilder::new(7, "c2", ConcreteDataType::int32_datatype()).build(), + ColumnDescriptorBuilder::new(7, "c2", ConcreteDataType::int32_datatype()) + .build() + .unwrap(), ) - .build(); + .build() + .unwrap(); assert_eq!(2, desc.columns.len()); assert!(!desc.enable_version_column); let desc = RowKeyDescriptorBuilder::new(timestamp) .enable_version_column(false) - .build(); + .build() + .unwrap(); assert!(desc.columns.is_empty()); assert!(!desc.enable_version_column); } #[test] fn test_cf_descriptor_builder() { - let desc = ColumnFamilyDescriptorBuilder::default().build(); + let desc = ColumnFamilyDescriptorBuilder::default().build().unwrap(); assert_eq!(consts::DEFAULT_CF_ID, desc.cf_id); assert_eq!(consts::DEFAULT_CF_NAME, desc.name); assert!(desc.columns.is_empty()); - let desc = ColumnFamilyDescriptorBuilder::new() + let desc = ColumnFamilyDescriptorBuilder::default() .cf_id(32) .name("cf1") - .build(); + .build() + .unwrap(); assert_eq!(32, desc.cf_id); assert_eq!("cf1", desc.name); - let desc = ColumnFamilyDescriptorBuilder::new() + let desc = ColumnFamilyDescriptorBuilder::default() .push_column( - ColumnDescriptorBuilder::new(6, "c1", ConcreteDataType::int32_datatype()).build(), + ColumnDescriptorBuilder::default() + .id(6) + .name("c1") + .data_type(ConcreteDataType::int32_datatype()) + .build() + .unwrap(), ) - .build(); + .build() + .unwrap(); assert_eq!(1, desc.columns.len()); } diff --git a/src/table-engine/src/engine.rs b/src/table-engine/src/engine.rs index fba67bc597..efbeb3f550 100644 --- a/src/table-engine/src/engine.rs +++ b/src/table-engine/src/engine.rs @@ -116,27 +116,33 @@ impl MitoEngineInner { let host_column = ColumnDescriptorBuilder::new(0, "host", ConcreteDataType::string_datatype()) .is_nullable(false) - .build(); + .build() + .unwrap(); let cpu_column = ColumnDescriptorBuilder::new(1, "cpu", ConcreteDataType::float64_datatype()) .is_nullable(true) - .build(); + .build() + .unwrap(); let memory_column = ColumnDescriptorBuilder::new(2, "memory", ConcreteDataType::float64_datatype()) .is_nullable(true) - .build(); - let ts_column = - ColumnDescriptorBuilder::new(0, "ts", ConcreteDataType::int64_datatype()).build(); + .build() + .unwrap(); + let ts_column = ColumnDescriptorBuilder::new(0, "ts", ConcreteDataType::int64_datatype()) + .build() + .unwrap(); let row_key = RowKeyDescriptorBuilder::new(ts_column) .push_column(host_column) .enable_version_column(false) - .build(); + .build() + .unwrap(); let default_cf = ColumnFamilyDescriptorBuilder::default() .push_column(cpu_column) .push_column(memory_column) - .build(); + .build() + .unwrap(); let region = self .storage_engine @@ -155,17 +161,20 @@ impl MitoEngineInner { .context(error::CreateRegionSnafu)?; // Use region meta schema instead of request schema - let table_meta = TableMetaBuilder::new(region.in_memory_metadata().schema().clone()) + let table_meta = TableMetaBuilder::default() + .schema(region.in_memory_metadata().schema().clone()) .engine(DEFAULT_ENGINE) - .build(); + .build() + .unwrap(); let table_name = request.name; let table_info = TableInfoBuilder::new(table_name.clone(), table_meta) - .table_id(self.next_table_id()) + .ident(self.next_table_id()) .table_version(0u64) .table_type(TableType::Base) .desc(request.desc) - .build(); + .build() + .unwrap(); let table = Arc::new(MitoTable::new(table_info, region)); diff --git a/src/table/Cargo.toml b/src/table/Cargo.toml index 6760db3f39..f9f3229892 100644 --- a/src/table/Cargo.toml +++ b/src/table/Cargo.toml @@ -15,3 +15,4 @@ datatypes = { path = "../datatypes" } futures = "0.3" serde = "1.0.136" snafu = { version = "0.7", features = ["backtraces"] } +derive_builder = "0.11" diff --git a/src/table/src/metadata.rs b/src/table/src/metadata.rs index c095a43ea1..ff72a51c78 100644 --- a/src/table/src/metadata.rs +++ b/src/table/src/metadata.rs @@ -1,7 +1,8 @@ use std::collections::HashMap; -use chrono::{DateTime, NaiveDateTime, TimeZone, Utc}; +use chrono::{DateTime, Utc}; use datatypes::schema::SchemaRef; +use derive_builder::Builder; pub type TableId = u64; pub type TableVersion = u64; @@ -40,24 +41,56 @@ pub struct TableIdent { pub version: TableVersion, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Builder)] +#[builder(pattern = "owned")] pub struct TableMeta { pub schema: SchemaRef, + #[builder(default, setter(into))] pub engine: String, + #[builder(default)] pub engine_options: HashMap, + #[builder(default)] pub options: HashMap, + #[builder(default = "Utc::now()")] pub created_on: DateTime, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Builder)] +#[builder(pattern = "owned")] pub struct TableInfo { + #[builder(default, setter(into))] pub ident: TableIdent, + #[builder(setter(into))] pub name: String, + #[builder(default, setter(into))] pub desc: Option, pub meta: TableMeta, + #[builder(default = "TableType::Base")] pub table_type: TableType, } +impl TableInfoBuilder { + pub fn new>(name: S, meta: TableMeta) -> Self { + Self { + name: Some(name.into()), + meta: Some(meta), + ..Default::default() + } + } + + pub fn table_id(mut self, id: impl Into) -> Self { + let ident = self.ident.get_or_insert_with(TableIdent::default); + ident.table_id = id.into(); + self + } + + pub fn table_version(mut self, version: impl Into) -> Self { + let ident = self.ident.get_or_insert_with(TableIdent::default); + ident.version = version.into(); + self + } +} + impl TableIdent { pub fn new(table_id: TableId) -> Self { Self { @@ -67,102 +100,8 @@ impl TableIdent { } } -pub struct TableMetaBuilder { - schema: SchemaRef, - engine: String, - engine_options: HashMap, - options: HashMap, -} - -impl TableMetaBuilder { - pub fn new(schema: SchemaRef) -> Self { - Self { - schema, - engine: String::default(), - engine_options: HashMap::default(), - options: HashMap::default(), - } - } - - pub fn engine(mut self, engine: impl Into) -> Self { - self.engine = engine.into(); - self - } - - pub fn table_option(mut self, name: &str, val: &str) -> Self { - self.options.insert(name.to_string(), val.to_string()); - self - } - - pub fn engine_option(mut self, name: &str, val: &str) -> Self { - self.engine_options - .insert(name.to_string(), val.to_string()); - self - } - - pub fn build(self) -> TableMeta { - TableMeta { - schema: self.schema, - engine: self.engine, - engine_options: self.engine_options, - options: self.options, - // TODO(dennis): use time utilities helper function - created_on: Utc.from_utc_datetime(&NaiveDateTime::from_timestamp(0, 0)), - } - } -} - -pub struct TableInfoBuilder { - ident: TableIdent, - name: String, - desc: Option, - meta: TableMeta, - table_type: TableType, -} - -impl TableInfoBuilder { - pub fn new(name: impl Into, meta: TableMeta) -> Self { - Self { - ident: TableIdent::new(0), - name: name.into(), - desc: None, - meta, - table_type: TableType::Base, - } - } - - pub fn table_id(mut self, id: impl Into) -> Self { - self.ident.table_id = id.into(); - self - } - - pub fn table_version(mut self, version: impl Into) -> Self { - self.ident.version = version.into(); - self - } - - pub fn table_type(mut self, table_type: TableType) -> Self { - self.table_type = table_type; - self - } - - pub fn metadata(mut self, meta: TableMeta) -> Self { - self.meta = meta; - self - } - - pub fn desc(mut self, desc: Option) -> Self { - self.desc = desc; - self - } - - pub fn build(self) -> TableInfo { - TableInfo { - ident: self.ident, - name: self.name, - desc: self.desc, - meta: self.meta, - table_type: self.table_type, - } +impl From for TableIdent { + fn from(table_id: TableId) -> Self { + Self::new(table_id) } }