Extend extension API to support auto-updating extensions (#9929)
This PR extends the extension API with some additional features to support auto-updating extensions: - The `GET /extensions` endpoint now accepts an optional `ids` parameter that can be used to filter the results down to just the extensions with the specified IDs. - This should be a comma-delimited list of extension IDs (e.g., `wgsl,gleam,tokyo-night`). - A new `GET /extensions/:extension_id` endpoint that returns all of the extension versions for a particular extension. Extracted from #9890, as these changes can be landed and deployed independently. Release Notes: - N/A Co-authored-by: Max <max@zed.dev>
This commit is contained in:
parent
eaf65ab704
commit
50fc54c321
2 changed files with 114 additions and 37 deletions
|
@ -1,4 +1,5 @@
|
|||
use chrono::Utc;
|
||||
use sea_orm::sea_query::IntoCondition;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -10,37 +11,83 @@ impl Database {
|
|||
limit: usize,
|
||||
) -> Result<Vec<ExtensionMetadata>> {
|
||||
self.transaction(|tx| async move {
|
||||
let mut condition = Condition::all().add(
|
||||
extension::Column::LatestVersion
|
||||
.into_expr()
|
||||
.eq(extension_version::Column::Version.into_expr()),
|
||||
);
|
||||
let mut condition = Condition::all()
|
||||
.add(
|
||||
extension::Column::LatestVersion
|
||||
.into_expr()
|
||||
.eq(extension_version::Column::Version.into_expr()),
|
||||
)
|
||||
.add(extension_version::Column::SchemaVersion.lte(max_schema_version));
|
||||
if let Some(filter) = filter {
|
||||
let fuzzy_name_filter = Self::fuzzy_like_string(filter);
|
||||
condition = condition.add(Expr::cust_with_expr("name ILIKE $1", fuzzy_name_filter));
|
||||
}
|
||||
|
||||
let extensions = extension::Entity::find()
|
||||
.inner_join(extension_version::Entity)
|
||||
.select_also(extension_version::Entity)
|
||||
.filter(condition)
|
||||
.filter(extension_version::Column::SchemaVersion.lte(max_schema_version))
|
||||
.order_by_desc(extension::Column::TotalDownloadCount)
|
||||
.order_by_asc(extension::Column::Name)
|
||||
.limit(Some(limit as u64))
|
||||
.all(&*tx)
|
||||
.await?;
|
||||
|
||||
Ok(extensions
|
||||
.into_iter()
|
||||
.filter_map(|(extension, version)| {
|
||||
Some(metadata_from_extension_and_version(extension, version?))
|
||||
})
|
||||
.collect())
|
||||
self.get_extensions_where(condition, Some(limit as u64), &tx)
|
||||
.await
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_extensions_by_ids(
|
||||
&self,
|
||||
ids: &[&str],
|
||||
max_schema_version: i32,
|
||||
) -> Result<Vec<ExtensionMetadata>> {
|
||||
self.transaction(|tx| async move {
|
||||
let condition = Condition::all()
|
||||
.add(
|
||||
extension::Column::LatestVersion
|
||||
.into_expr()
|
||||
.eq(extension_version::Column::Version.into_expr()),
|
||||
)
|
||||
.add(extension::Column::ExternalId.is_in(ids.iter().copied()))
|
||||
.add(extension_version::Column::SchemaVersion.lte(max_schema_version));
|
||||
|
||||
self.get_extensions_where(condition, None, &tx).await
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
/// Returns all of the versions for the extension with the given ID.
|
||||
pub async fn get_extension_versions(
|
||||
&self,
|
||||
extension_id: &str,
|
||||
) -> Result<Vec<ExtensionMetadata>> {
|
||||
self.transaction(|tx| async move {
|
||||
let condition = extension::Column::ExternalId
|
||||
.eq(extension_id)
|
||||
.into_condition();
|
||||
|
||||
self.get_extensions_where(condition, None, &tx).await
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_extensions_where(
|
||||
&self,
|
||||
condition: Condition,
|
||||
limit: Option<u64>,
|
||||
tx: &DatabaseTransaction,
|
||||
) -> Result<Vec<ExtensionMetadata>> {
|
||||
let extensions = extension::Entity::find()
|
||||
.inner_join(extension_version::Entity)
|
||||
.select_also(extension_version::Entity)
|
||||
.filter(condition)
|
||||
.order_by_desc(extension::Column::TotalDownloadCount)
|
||||
.order_by_asc(extension::Column::Name)
|
||||
.limit(limit)
|
||||
.all(tx)
|
||||
.await?;
|
||||
|
||||
Ok(extensions
|
||||
.into_iter()
|
||||
.filter_map(|(extension, version)| {
|
||||
Some(metadata_from_extension_and_version(extension, version?))
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub async fn get_extension(&self, extension_id: &str) -> Result<Option<ExtensionMetadata>> {
|
||||
self.transaction(|tx| async move {
|
||||
let extension = extension::Entity::find()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue