Skip to content

Commit fcab560

Browse files
committed
Overhaul schema metadata handling in preparation for geometry columns.
1 parent 530f4ab commit fcab560

27 files changed

+614
-545
lines changed

crates/core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ ed25519-dalek = { version = "2.1.1", features = ["pkcs8", "pem", "rand_core"] }
4848
fallible-iterator = "0.3.0"
4949
form_urlencoded = "1.2.1"
5050
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
51+
# geos = { version = "10.0.0", default-features = false, features = ["geo", "json"] }
5152
http-body-util = "0.1.3"
5253
hyper = "1.6.0"
5354
hyper-util = "0.1.7"

crates/core/src/admin/logs/list_logs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub async fn list_logs_handler(
5555
&[table],
5656
)?;
5757

58-
build_filter_where_clause(TABLE_ALIAS, &table_metadata.schema.columns, filter_params)?
58+
build_filter_where_clause(TABLE_ALIAS, &table_metadata.column_metadata, filter_params)?
5959
};
6060

6161
let total_row_count: i64 = conn

crates/core/src/admin/logs/stats.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub async fn fetch_stats_handler(
5252
&[table],
5353
)?;
5454

55-
build_filter_where_clause(TABLE_ALIAS, &table_metadata.schema.columns, filter_params)?
55+
build_filter_where_clause(TABLE_ALIAS, &table_metadata.column_metadata, filter_params)?
5656
};
5757

5858
let now = Utc::now();

crates/core/src/admin/rows/delete_rows.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use axum::{
55
response::{IntoResponse, Response},
66
};
77
use serde::{Deserialize, Serialize};
8-
use trailbase_schema::{QualifiedName, QualifiedNameEscaped};
8+
use trailbase_schema::{QualifiedName, QualifiedNameEscaped, metadata::find_file_column_indexes};
99
use trailbase_sqlvalue::SqlValue;
1010
use ts_rs::TS;
1111

@@ -54,21 +54,24 @@ pub(crate) async fn delete_row(
5454
)));
5555
};
5656

57-
let Some((_index, column)) = table_metadata.column_by_name(pk_col) else {
57+
let Some(meta) = table_metadata.column_by_name(pk_col) else {
5858
return Err(Error::Precondition(format!("Missing column: {pk_col}")));
5959
};
6060

61+
let column = &meta.column;
6162
if !column.is_primary() {
6263
return Err(Error::Precondition(format!("Not a primary key: {pk_col}")));
6364
}
6465

66+
let has_file_columns = !find_file_column_indexes(&table_metadata.column_metadata).is_empty();
67+
6568
run_delete_query(
6669
&conn,
6770
state.objectstore(),
6871
&QualifiedNameEscaped::from(&table_metadata.schema.name),
6972
pk_col,
7073
pk_value.try_into()?,
71-
table_metadata.json_metadata.has_file_columns(),
74+
has_file_columns,
7275
)
7376
.await?;
7477

crates/core/src/admin/rows/list_rows.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub async fn list_rows_handler(
9090

9191
let cursor_column = table_or_view.record_pk_column();
9292
let cursor = match (cursor, cursor_column) {
93-
(Some(cursor), Some((_idx, c))) => Some(parse_cursor(&cursor, c)?),
93+
(Some(cursor), Some(meta)) => Some(parse_cursor(&cursor, &meta.column)?),
9494
_ => None,
9595
};
9696
let (rows, columns) = fetch_rows(
@@ -99,7 +99,7 @@ pub async fn list_rows_handler(
9999
filter_where_clause,
100100
&order,
101101
Pagination {
102-
cursor_column: cursor_column.map(|(_idx, c)| c),
102+
cursor_column: cursor_column.map(|meta| &meta.column),
103103
cursor,
104104
offset,
105105
limit: limit_or_default(limit, None).map_err(|err| Error::BadRequest(err.into()))?,
@@ -108,10 +108,10 @@ pub async fn list_rows_handler(
108108
.await?;
109109

110110
let next_cursor = if order.is_none() {
111-
cursor_column.and_then(|(col_idx, _col)| {
111+
cursor_column.and_then(|meta| {
112112
let row = rows.last()?;
113-
assert!(row.len() > col_idx);
114-
match &row[col_idx] {
113+
assert!(row.len() > meta.index);
114+
match &row[meta.index] {
115115
SqlValue::Integer(n) => Some(n.to_string()),
116116
SqlValue::Blob(b) => {
117117
// Should be a base64 encoded [u8; 16] id.
@@ -130,7 +130,10 @@ pub async fn list_rows_handler(
130130
// NOTE: in the view case we don't have a good way of extracting the columns from the "CREATE
131131
// VIEW" query so we fall back to columns constructed from the returned data.
132132
columns: match table_or_view.columns() {
133-
Some(schema_columns) if !schema_columns.is_empty() => schema_columns.to_vec(),
133+
Some(schema_columns) if !schema_columns.is_empty() => schema_columns
134+
.iter()
135+
.map(|meta| meta.column.clone())
136+
.collect(),
134137
_ => {
135138
// VIRTUAL TABLE or VIEW case.
136139
debug!("Falling back to inferred cols for view: {table_name:?}");

crates/core/src/admin/rows/read_files.rs

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use axum::{
33
response::Response,
44
};
55
use serde::Deserialize;
6-
use trailbase_schema::metadata::TableOrViewMetadata;
76
use trailbase_schema::{FileUploads, QualifiedName};
87
use ts_rs::TS;
98

@@ -39,45 +38,31 @@ pub async fn read_files_handler(
3938
"Table {table_name:?} not found"
4039
)));
4140
};
42-
let Some((_index, pk_col)) = table_or_view.column_by_name(&query.pk_column) else {
41+
let Some(pk_meta) = table_or_view.column_by_name(&query.pk_column) else {
4342
return Err(Error::Precondition(format!(
4443
"Missing PK column: {}",
4544
query.pk_column
4645
)));
4746
};
4847

48+
let pk_col = &pk_meta.column;
4949
if !pk_col.is_primary() {
5050
return Err(Error::Precondition(format!(
5151
"Not a primary key: {pk_col:?}"
5252
)));
5353
}
5454

55-
let Some((index, file_col_metadata)) = table_or_view.column_by_name(&query.file_column_name)
56-
else {
55+
let Some(file_column_meta) = table_or_view.column_by_name(&query.file_column_name) else {
5756
return Err(Error::Precondition(format!(
5857
"Missing file column: {}",
5958
query.file_column_name
6059
)));
6160
};
6261

63-
let Some(file_col_json_metadata) = (match table_or_view {
64-
TableOrViewMetadata::Table(t) => t.json_metadata.columns[index].as_ref(),
65-
TableOrViewMetadata::View(v) => v
66-
.json_metadata
67-
.as_ref()
68-
.and_then(|j| j.columns[index].as_ref()),
69-
}) else {
70-
return Err(Error::Precondition(format!(
71-
"Not a JSON column: {}",
72-
query.file_column_name
73-
)));
74-
};
75-
7662
let FileUploads(mut file_uploads) = run_get_files_query(
7763
&conn,
7864
&table_name.into(),
79-
file_col_metadata,
80-
file_col_json_metadata,
65+
file_column_meta,
8166
&query.pk_column,
8267
trailbase_schema::json::parse_string_to_sqlite_value(pk_col.data_type, query.pk_value)?,
8368
)

crates/core/src/admin/rows/update_row.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,17 @@ pub async fn update_row_handler(
4646
};
4747

4848
let pk_col = &request.primary_key_column;
49-
let Some((index, column)) = table_metadata.column_by_name(pk_col) else {
49+
let Some(meta) = table_metadata.column_by_name(pk_col) else {
5050
return Err(Error::Precondition(format!("Missing column: {pk_col}")));
5151
};
5252

5353
if let Some(pk_index) = table_metadata.record_pk_column
54-
&& index != pk_index
54+
&& meta.index != pk_index
5555
{
5656
return Err(Error::Precondition(format!("Pk column mismatch: {pk_col}")));
5757
}
5858

59+
let column = &meta.column;
5960
if !column.is_primary() {
6061
return Err(Error::Precondition(format!("Not a primary key: {pk_col}")));
6162
}

crates/core/src/admin/user/list_users.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub async fn list_users_handler(
8181
// Where clause contains column filters and offset depending on what's present in the url query
8282
// string.
8383
let filter_where_clause =
84-
build_filter_where_clause("_ROW_", &table_metadata.schema.columns, filter_params)?;
84+
build_filter_where_clause("_ROW_", &table_metadata.column_metadata, filter_params)?;
8585

8686
let total_row_count: i64 = conn
8787
.read_query_row_f(

crates/core/src/auth/api/avatar.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,14 @@ pub async fn get_avatar_handler(
3939
return Err(AuthError::Internal("missing table".into()));
4040
};
4141

42-
let Some((index, file_column)) = table_metadata.column_by_name("file") else {
42+
let Some(file_column_meta) = table_metadata.column_by_name("file") else {
4343
return Err(AuthError::Internal("missing column".into()));
4444
};
4545

46-
let Some(ref column_json_metadata) = table_metadata.json_metadata.columns[index] else {
47-
return Err(AuthError::Internal("missing metadata".into()));
48-
};
49-
5046
let file_upload = run_get_file_query(
5147
&conn,
5248
&trailbase_schema::QualifiedNameEscaped::new(&AVATAR_TABLE_NAME),
53-
file_column,
54-
column_json_metadata,
49+
file_column_meta,
5550
"user",
5651
rusqlite::types::Value::Blob(user_id.into()),
5752
)

crates/core/src/connection.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,11 @@ fn setup_file_deletion_triggers_sync(
462462
metadata: &ConnectionMetadata,
463463
) -> Result<(), trailbase_sqlite::Error> {
464464
for metadata in metadata.tables.values() {
465-
for idx in metadata.json_metadata.file_column_indexes() {
465+
for column_meta in &metadata.column_metadata {
466+
if !column_meta.is_file {
467+
continue;
468+
}
469+
466470
let table_name = &metadata.schema.name;
467471
let unqualified_name = &metadata.schema.name.name;
468472
let db = metadata
@@ -472,8 +476,7 @@ fn setup_file_deletion_triggers_sync(
472476
.as_deref()
473477
.unwrap_or("main");
474478

475-
let col = &metadata.schema.columns[*idx];
476-
let column_name = &col.name;
479+
let column_name = &column_meta.column.name;
477480

478481
conn.execute_batch(&format!(
479482
"\

0 commit comments

Comments
 (0)