Skip to content

Commit 39175ae

Browse files
feat(webserver, db): refactor gitlab and github integrations into unified integration / third party repository services (TabbyML#2088)
* draft: begin implementing integration / third party repository service * Progress on refactor * [autofix.ci] apply automated fixes * Use join instead of adding kind as a field of repositories * Update schema * [autofix.ci] apply automated fixes * Implement sync_repositories * Make access_token field required * [autofix.ci] apply automated fixes * Implement IntegrationService * Implement service layer * [autofix.ci] apply automated fixes * Switch graphQL endpoints to use new service * [autofix.ci] apply automated fixes * Fix queries * Fully working * Rebase * Update submodules * Cleanup imports * [autofix.ci] apply automated fixes * Apply suggestions * [autofix.ci] apply automated fixes * Add back updated_at --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 8ab9b56 commit 39175ae

24 files changed

+1065
-98
lines changed

.gitmodules

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
[submodule "crates/llama-cpp-bindings/llama.cpp"]
1+
[submodule "crates/llama-cpp-server/llama.cpp"]
22
path = crates/llama-cpp-server/llama.cpp
33
url = https://github.com/ggerganov/llama.cpp

ee/tabby-db-macros/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pub fn query_paged_as(input: TokenStream) -> TokenStream {
109109
let backwards = input.backwards;
110110
quote! {
111111
sqlx::query_as(&crate::make_pagination_query_with_condition({
112-
let _ = sqlx::query_as!(#typ, "SELECT " + #columns + " FROM " + #table_name);
112+
let _ = sqlx::query_as!(#typ, "SELECT " + #columns + " FROM (SELECT * FROM " + #table_name + ")");
113113
&#table_name
114114
}, &[ #(#column_args),* ], #limit, #skip_id, #backwards, #condition))
115115
}

ee/tabby-db/migrations/0029_merged-provider-tables.up.sql

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ CREATE TABLE integration_access_tokens(
22
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
33
kind TEXT NOT NULL,
44
display_name TEXT NOT NULL,
5-
access_token TEXT,
5+
access_token TEXT NOT NULL,
66
error TEXT,
77
created_at TIMESTAMP NOT NULL DEFAULT (DATETIME('now')),
8-
updated_at TIMESTAMP NOT NULL DEFAULT (DATETIME('now'))
8+
updated_at TIMESTAMP NOT NULL DEFAULT (DATETIME('now')),
9+
synced_at TIMESTAMP NOT NULL DEFAULT (DATETIME('now'))
910
);
1011

1112
CREATE TABLE provided_repositories(
@@ -20,3 +21,9 @@ CREATE TABLE provided_repositories(
2021
FOREIGN KEY (integration_access_token_id) REFERENCES integration_access_tokens(id) ON DELETE CASCADE,
2122
CONSTRAINT idx_unique_provider_id_vendor_id UNIQUE (integration_access_token_id, vendor_id)
2223
);
24+
25+
INSERT INTO integration_access_tokens(kind, display_name, access_token)
26+
SELECT 'github', display_name, access_token FROM github_repository_provider WHERE access_token IS NOT NULL;
27+
28+
INSERT INTO integration_access_tokens(kind, display_name, access_token)
29+
SELECT 'gitlab', display_name, access_token FROM gitlab_repository_provider WHERE access_token IS NOT NULL;

ee/tabby-db/schema.sqlite

0 Bytes
Binary file not shown.

ee/tabby-db/schema/schema.sql

+3-2
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,11 @@ CREATE TABLE integration_access_tokens(
176176
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
177177
kind TEXT NOT NULL,
178178
display_name TEXT NOT NULL,
179-
access_token TEXT,
179+
access_token TEXT NOT NULL,
180180
error TEXT,
181181
created_at TIMESTAMP NOT NULL DEFAULT(DATETIME('now')),
182-
updated_at TIMESTAMP NOT NULL DEFAULT(DATETIME('now'))
182+
updated_at TIMESTAMP NOT NULL DEFAULT(DATETIME('now')),
183+
synced_at TIMESTAMP NOT NULL DEFAULT(DATETIME('now'))
183184
);
184185
CREATE TABLE provided_repositories(
185186
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,

ee/tabby-db/schema/schema.svg

+4
Loading

ee/tabby-db/src/integration_access_tokens.rs

+26-17
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@ pub struct IntegrationAccessTokenDAO {
1010
pub kind: String,
1111
pub error: Option<String>,
1212
pub display_name: String,
13-
pub access_token: Option<String>,
13+
pub access_token: String,
1414
pub created_at: DateTimeUtc,
1515
pub updated_at: DateTimeUtc,
16+
pub synced_at: DateTimeUtc,
1617
}
1718

1819
impl DbConn {
1920
pub async fn create_integration_access_token(
2021
&self,
21-
kind: &str,
22-
name: &str,
23-
access_token: &str,
22+
kind: String,
23+
name: String,
24+
access_token: String,
2425
) -> Result<i64> {
2526
let res = query!(
2627
"INSERT INTO integration_access_tokens(kind, display_name, access_token) VALUES (?, ?, ?);",
@@ -42,8 +43,9 @@ impl DbConn {
4243
error,
4344
display_name,
4445
access_token,
45-
created_at AS "created_at: DateTimeUtc",
46-
updated_at AS "updated_at: DateTimeUtc"
46+
updated_at,
47+
created_at,
48+
synced_at
4749
FROM integration_access_tokens WHERE id = ?;"#,
4850
id
4951
)
@@ -52,10 +54,14 @@ impl DbConn {
5254
Ok(provider)
5355
}
5456

55-
pub async fn delete_integration_access_token(&self, id: i64) -> Result<()> {
56-
let res = query!("DELETE FROM integration_access_tokens WHERE id = ?;", id)
57-
.execute(&self.pool)
58-
.await?;
57+
pub async fn delete_integration_access_token(&self, id: i64, kind: &str) -> Result<()> {
58+
let res = query!(
59+
"DELETE FROM integration_access_tokens WHERE id = ? AND kind = ?;",
60+
id,
61+
kind
62+
)
63+
.execute(&self.pool)
64+
.await?;
5965
if res.rows_affected() != 1 {
6066
return Err(anyhow!("No integration access token to delete"));
6167
}
@@ -65,19 +71,21 @@ impl DbConn {
6571
pub async fn update_integration_access_token(
6672
&self,
6773
id: i64,
74+
kind: &str,
6875
display_name: String,
6976
access_token: Option<String>,
7077
) -> Result<()> {
7178
let access_token = match access_token {
72-
Some(access_token) => Some(access_token),
79+
Some(access_token) => access_token,
7380
None => self.get_integration_access_token(id).await?.access_token,
7481
};
7582

7683
let res = query!(
77-
"UPDATE integration_access_tokens SET display_name = ?, access_token=? WHERE id = ?;",
84+
"UPDATE integration_access_tokens SET display_name = ?, access_token = ?, updated_at = DATETIME('now') WHERE id = ? AND kind = ?;",
7885
display_name,
7986
access_token,
80-
id
87+
id,
88+
kind
8189
)
8290
.execute(&self.pool)
8391
.await?;
@@ -97,7 +105,7 @@ impl DbConn {
97105
error: Option<String>,
98106
) -> Result<()> {
99107
query!(
100-
"UPDATE integration_access_tokens SET updated_at = DATETIME('now'), error = ? WHERE id = ?",
108+
"UPDATE integration_access_tokens SET synced_at = DATETIME('now'), error = ? WHERE id = ?",
101109
error,
102110
id
103111
)
@@ -126,7 +134,7 @@ impl DbConn {
126134
});
127135
conditions.extend(id_condition);
128136

129-
let kind_condition = kind.map(|kind| format!("kind = {kind}"));
137+
let kind_condition = kind.map(|kind| format!("kind = '{kind}'"));
130138
conditions.extend(kind_condition);
131139

132140
let condition = (!conditions.is_empty()).then(|| conditions.join(" AND "));
@@ -140,8 +148,9 @@ impl DbConn {
140148
"error",
141149
"display_name",
142150
"access_token",
143-
"created_at" as "created_at: DateTimeUtc",
144-
"updated_at" as "updated_at: DateTimeUtc"
151+
"created_at",
152+
"updated_at",
153+
"synced_at"
145154
],
146155
limit,
147156
skip_id,

ee/tabby-db/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ use chrono::{DateTime, Duration, NaiveDateTime, Utc};
1212
pub use email_setting::EmailSettingDAO;
1313
pub use github_repository_provider::{GithubProvidedRepositoryDAO, GithubRepositoryProviderDAO};
1414
pub use gitlab_repository_provider::{GitlabProvidedRepositoryDAO, GitlabRepositoryProviderDAO};
15+
pub use integration_access_tokens::IntegrationAccessTokenDAO;
1516
pub use invitations::InvitationDAO;
1617
pub use job_runs::JobRunDAO;
1718
pub use oauth_credential::OAuthCredentialDAO;
19+
pub use provided_repositories::ProvidedRepositoryDAO;
1820
pub use repositories::RepositoryDAO;
1921
pub use server_setting::ServerSettingDAO;
2022
use sqlx::{

ee/tabby-db/src/provided_repositories.rs

+23-8
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl DbConn {
6161

6262
pub async fn list_provided_repositories(
6363
&self,
64-
provider_ids: Vec<i64>,
64+
integration_ids: Vec<i64>,
6565
kind: Option<String>,
6666
active: Option<bool>,
6767
limit: Option<usize>,
@@ -70,35 +70,37 @@ impl DbConn {
7070
) -> Result<Vec<ProvidedRepositoryDAO>> {
7171
let mut conditions = vec![];
7272

73-
let provider_ids = provider_ids
73+
let integration_ids = integration_ids
7474
.into_iter()
7575
.map(|id| id.to_string())
7676
.collect::<Vec<_>>()
7777
.join(", ");
78-
if !provider_ids.is_empty() {
79-
conditions.push(format!("access_token_provider_id IN ({provider_ids})"));
78+
if !integration_ids.is_empty() {
79+
conditions.push(format!(
80+
"integration_access_token_id IN ({integration_ids})"
81+
));
8082
}
8183

8284
let active_filter = active.map(|active| format!("active = {active}"));
8385
conditions.extend(active_filter);
8486

85-
let kind_filter = kind.map(|kind| format!("kind = {kind}"));
87+
let kind_filter = kind.map(|kind| format!("kind = '{kind}'"));
8688
conditions.extend(kind_filter);
8789

8890
let condition = (!conditions.is_empty()).then(|| conditions.join(" AND "));
8991

9092
let repos = query_paged_as!(
9193
ProvidedRepositoryDAO,
92-
"provided_repositories",
94+
"provided_repositories JOIN integration_access_tokens ON integration_access_token_id = integration_access_tokens.id",
9395
[
9496
"id",
9597
"vendor_id",
9698
"name",
9799
"git_url",
98100
"active",
99101
"integration_access_token_id",
100-
"created_at" as "created_at: DateTimeUtc",
101-
"updated_at" as "updated_at: DateTimeUtc"
102+
"created_at",
103+
"updated_at"
102104
],
103105
limit,
104106
skip_id,
@@ -128,3 +130,16 @@ impl DbConn {
128130
Ok(())
129131
}
130132
}
133+
134+
#[cfg(test)]
135+
mod tests {
136+
use crate::DbConn;
137+
138+
#[tokio::test]
139+
async fn test_list_provided_repositories() {
140+
let db = DbConn::new_in_memory().await.unwrap();
141+
db.list_github_provided_repositories(vec![], None, None, None, false)
142+
.await
143+
.unwrap();
144+
}
145+
}

0 commit comments

Comments
 (0)