refactor: use derive_builder for boilerplate builders (#116)

* refactor: remove boilerplate builder code with derive_builder macro

* refactor: better build creation using Default::default()

* refactor: resolve api change issues in benchmark code

* refactor: address some review issues

* refactor: address clippy issues

* chore: doc and todo update

* refactor: add builder for RegionDescriptor
This commit is contained in:
Ning Sun
2022-07-29 14:31:12 +08:00
committed by GitHub
parent 45490b6293
commit 62cb649389
10 changed files with 250 additions and 261 deletions

74
Cargo.lock generated
View File

@@ -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",

View File

@@ -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()
}
}

View File

@@ -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()

View File

@@ -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()
}
}

View File

@@ -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"

View File

@@ -1,5 +1,4 @@
//! Storage related APIs
pub mod logstore;
pub mod manifest;
pub mod storage;

View File

@@ -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<Value>,
#[builder(default, setter(into))]
pub comment: String,
}
impl ColumnDescriptorBuilder {
pub fn new<S: Into<String>>(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<ColumnDescriptor>,
/// 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<ColumnDescriptor>,
}
/// 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<ColumnFamilyDescriptor>,
}
pub struct ColumnDescriptorBuilder {
id: ColumnId,
name: String,
data_type: ConcreteDataType,
is_nullable: bool,
default_value: Option<Value>,
comment: String,
}
impl ColumnDescriptorBuilder {
pub fn new<T: Into<String>>(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<Value>) -> Self {
self.default_value = value;
self
}
pub fn comment<T: Into<String>>(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<ColumnDescriptor>,
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<ColumnDescriptor>,
}
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<T: Into<String>>(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());
}

View File

@@ -116,27 +116,33 @@ impl<Store: StorageEngine> MitoEngineInner<Store> {
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<Store: StorageEngine> MitoEngineInner<Store> {
.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));

View File

@@ -15,3 +15,4 @@ datatypes = { path = "../datatypes" }
futures = "0.3"
serde = "1.0.136"
snafu = { version = "0.7", features = ["backtraces"] }
derive_builder = "0.11"

View File

@@ -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<String, String>,
#[builder(default)]
pub options: HashMap<String, String>,
#[builder(default = "Utc::now()")]
pub created_on: DateTime<Utc>,
}
#[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<String>,
pub meta: TableMeta,
#[builder(default = "TableType::Base")]
pub table_type: TableType,
}
impl TableInfoBuilder {
pub fn new<S: Into<String>>(name: S, meta: TableMeta) -> Self {
Self {
name: Some(name.into()),
meta: Some(meta),
..Default::default()
}
}
pub fn table_id(mut self, id: impl Into<TableId>) -> 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<TableVersion>) -> 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<String, String>,
options: HashMap<String, String>,
}
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<String>) -> 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<String>,
meta: TableMeta,
table_type: TableType,
}
impl TableInfoBuilder {
pub fn new(name: impl Into<String>, 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<TableId>) -> Self {
self.ident.table_id = id.into();
self
}
pub fn table_version(mut self, version: impl Into<TableVersion>) -> 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<String>) -> 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<TableId> for TableIdent {
fn from(table_id: TableId) -> Self {
Self::new(table_id)
}
}