Apply schema changes to produce a new schema version. Returns the new schema (metadata-only, no data rewrite).
(
current: &ColumnarSchema,
changes: &[SchemaChange],
)
| 130 | /// Apply schema changes to produce a new schema version. |
| 131 | /// Returns the new schema (metadata-only, no data rewrite). |
| 132 | pub fn apply_schema_changes( |
| 133 | current: &ColumnarSchema, |
| 134 | changes: &[SchemaChange], |
| 135 | ) -> crate::Result<ColumnarSchema> { |
| 136 | let mut columns = current.columns.clone(); |
| 137 | let mut timestamp_idx = current.timestamp_idx; |
| 138 | |
| 139 | for change in changes { |
| 140 | match change { |
| 141 | SchemaChange::AddColumn { name, col_type } => { |
| 142 | if columns.iter().any(|(n, _)| n == name) { |
| 143 | return Err(crate::Error::BadRequest { |
| 144 | detail: format!("column '{name}' already exists"), |
| 145 | }); |
| 146 | } |
| 147 | columns.push((name.clone(), *col_type)); |
| 148 | } |
| 149 | SchemaChange::DropColumn { name } => { |
| 150 | let idx = columns.iter().position(|(n, _)| n == name).ok_or_else(|| { |
| 151 | crate::Error::BadRequest { |
| 152 | detail: format!("column '{name}' not found"), |
| 153 | } |
| 154 | })?; |
| 155 | if idx == timestamp_idx { |
| 156 | return Err(crate::Error::BadRequest { |
| 157 | detail: "cannot drop the designated timestamp column".into(), |
| 158 | }); |
| 159 | } |
| 160 | columns.remove(idx); |
| 161 | if idx < timestamp_idx { |
| 162 | timestamp_idx -= 1; |
| 163 | } |
| 164 | } |
| 165 | SchemaChange::RenameColumn { old_name, new_name } => { |
| 166 | let idx = columns |
| 167 | .iter() |
| 168 | .position(|(n, _)| n == old_name) |
| 169 | .ok_or_else(|| crate::Error::BadRequest { |
| 170 | detail: format!("column '{old_name}' not found"), |
| 171 | })?; |
| 172 | if columns.iter().any(|(n, _)| n == new_name) { |
| 173 | return Err(crate::Error::BadRequest { |
| 174 | detail: format!("column '{new_name}' already exists"), |
| 175 | }); |
| 176 | } |
| 177 | columns[idx].0 = new_name.clone(); |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | Ok(ColumnarSchema { |
| 183 | codecs: vec![nodedb_codec::ColumnCodec::Auto; columns.len()], |
| 184 | columns, |
| 185 | timestamp_idx, |
| 186 | }) |
| 187 | } |
| 188 | |
| 189 | #[cfg(test)] |