/// Internal Create builder for {{ model_name }} — use `{{ delegate_name }}::create(data)` instead.
pub(crate) struct {{ create_name }}<E: crate::Executor> {
    client: crate::Client<E>,
{%- for field in create_fields %}
    {{ field.name }}: Option<{{ field.rust_type }}>,
{%- endfor %}
}

impl<E> {{ create_name }}<E>
where
    E: crate::Executor,
    for<'a> E::Row<'a>: Into<crate::Row>,
{
    pub(crate) fn new(client: crate::Client<E>) -> Self {
        {{ create_name }} {
            client,
{%- for field in create_fields %}
            {{ field.name }}: None,
{%- endfor %}
        }
    }

{%- for field in create_fields %}
    /// Set {{ field.name }}.
    #[must_use]
    pub(crate) fn {{ field.name }}(mut self, value: impl Into<{{ field.rust_type }}>) -> Self {
        self.{{ field.name }} = Some(value.into());
        self
    }

{%- endfor %}
    /// Execute the create query.
    pub(crate) async fn exec(self) -> nautilus_core::Result<{{ model_name }}> {
        use nautilus_core::*;
        use std::convert::Into;

        let mut columns = Vec::with_capacity({{ create_fields | length }});
        let mut values = Vec::with_capacity({{ create_fields | length }});

{%- for field in create_fields %}
        if let Some(value) = self.{{ field.name }} {
            columns.push(ColumnMarker::from_static("{{ table_name }}", "{{ field.db_name }}"));
            values.push(Value::from(value));
        }
{%- endfor %}

        let mut builder = Insert::into_table("{{ table_name }}")
            .columns(columns)
            .values(values);

        let supports_returning = self.client.dialect().supports_returning();
        if supports_returning {
            let returning_cols = vec![
{%- for field in all_scalar_fields %}
                ColumnMarker::from_static("{{ table_name }}", "{{ field.db_name }}"),
{%- endfor %}
            ];
            builder = builder.returning(returning_cols);
        }

        let insert = builder.build()?;
        let sql = self.client.dialect().render_insert_owned(insert)?;

        let row: Row = crate::execute_one(self.client.executor(), &sql)
            .await
            .map_err(|e| Error::Other(e.to_string()))?
            .into();

        decode_model_row_with_hints(row, all_scalar_decode_slots(), all_scalar_value_hints())
    }
}
