Declare a new GSI on a collection field. Enforces the max 4 GSIs per collection limit.
(
&self,
tenant_id: u64,
collection: &str,
index_name: &str,
field: &str,
payload_fields: Vec<String>,
)
| 94 | /// |
| 95 | /// Enforces the max 4 GSIs per collection limit. |
| 96 | pub fn create_index( |
| 97 | &self, |
| 98 | tenant_id: u64, |
| 99 | collection: &str, |
| 100 | index_name: &str, |
| 101 | field: &str, |
| 102 | payload_fields: Vec<String>, |
| 103 | ) -> crate::Result<()> { |
| 104 | // Check limit. |
| 105 | let existing = self.list_indexes(tenant_id, collection)?; |
| 106 | if existing.len() >= self.max_gsis { |
| 107 | return Err(crate::Error::Storage { |
| 108 | engine: "gsi".into(), |
| 109 | detail: format!( |
| 110 | "collection '{collection}' already has {} GSIs (max)", |
| 111 | self.max_gsis |
| 112 | ), |
| 113 | }); |
| 114 | } |
| 115 | |
| 116 | let meta = GsiMeta { |
| 117 | index_name: index_name.to_string(), |
| 118 | collection: collection.to_string(), |
| 119 | field: field.to_string(), |
| 120 | payload_fields, |
| 121 | tenant_id, |
| 122 | }; |
| 123 | let meta_key = format!("{tenant_id}:{collection}:{index_name}"); |
| 124 | let meta_bytes = |
| 125 | zerompk::to_msgpack_vec(&meta).map_err(|e| crate::Error::Serialization { |
| 126 | format: "msgpack".into(), |
| 127 | detail: format!("gsi meta: {e}"), |
| 128 | })?; |
| 129 | |
| 130 | let write_txn = self.db.begin_write().map_err(|e| crate::Error::Storage { |
| 131 | engine: "gsi".into(), |
| 132 | detail: format!("write: {e}"), |
| 133 | })?; |
| 134 | { |
| 135 | let mut table = write_txn |
| 136 | .open_table(GSI_META) |
| 137 | .map_err(|e| crate::Error::Storage { |
| 138 | engine: "gsi".into(), |
| 139 | detail: format!("open meta: {e}"), |
| 140 | })?; |
| 141 | table |
| 142 | .insert(meta_key.as_str(), meta_bytes.as_slice()) |
| 143 | .map_err(|e| crate::Error::Storage { |
| 144 | engine: "gsi".into(), |
| 145 | detail: format!("insert meta: {e}"), |
| 146 | })?; |
| 147 | } |
| 148 | write_txn.commit().map_err(|e| crate::Error::Storage { |
| 149 | engine: "gsi".into(), |
| 150 | detail: format!("commit: {e}"), |
| 151 | })?; |
| 152 | |
| 153 | debug!(tenant_id, collection, index_name, field, "GSI created"); |