From ee2b8f8491d785c5caf1a7a0810c8036ebab45f1 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Thu, 10 Dec 2020 05:39:34 +0100 Subject: [PATCH 1/3] Add simple search for issues and projects --- openapi/reference/Default.v1.yaml | 164 ++++++++++++++++++----- resources/sql/queries.sql | 32 +++-- src/clj/g2/routes/home.clj | 16 +++ src/clj/g2/services/issues_service.clj | 18 ++- src/clj/g2/services/projects_service.clj | 10 ++ 5 files changed, 195 insertions(+), 45 deletions(-) diff --git a/openapi/reference/Default.v1.yaml b/openapi/reference/Default.v1.yaml index 570ef0d..28fe89e 100644 --- a/openapi/reference/Default.v1.yaml +++ b/openapi/reference/Default.v1.yaml @@ -8,7 +8,7 @@ paths: /projects: get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -67,7 +67,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -118,7 +118,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -130,7 +130,7 @@ paths: $ref: ../models/Repository.v1.yaml operationId: get-projects-id-repositories description: Get a list with repositories for a given project. - parameters: [ ] + parameters: [] '/projects/{id}/issues': parameters: - schema: @@ -142,7 +142,7 @@ paths: description: '' get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -179,7 +179,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -216,7 +216,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -246,7 +246,7 @@ paths: /repositories: get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -267,7 +267,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -313,7 +313,7 @@ paths: /user: get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -334,7 +334,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -355,7 +355,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -376,7 +376,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -391,7 +391,7 @@ paths: /tags: get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -403,7 +403,7 @@ paths: $ref: ../models/Tag.v1.yaml operationId: get-tags description: Get a list with tags. - parameters: [ ] + parameters: [] post: summary: '' operationId: post-tags @@ -446,7 +446,7 @@ paths: application/json: schema: $ref: ../models/Tag.v1.yaml - examples: { } + examples: {} description: Update a given tag by id. requestBody: content: @@ -490,7 +490,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -509,7 +509,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -556,7 +556,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -564,7 +564,7 @@ paths: application/json: schema: $ref: ../models/Pull.v1.yaml - examples: { } + examples: {} operationId: get-pulls-id description: Get a pull request by id. '/pulls/{id}/tags': @@ -576,7 +576,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -623,7 +623,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -642,7 +642,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -689,7 +689,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -730,7 +730,7 @@ paths: /search: get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -755,6 +755,108 @@ paths: type: array items: $ref: ../models/Branch.v1.yaml + examples: + example-1: + value: + issues: + - id: 0 + title: string + timestamp: 0 + status: open + url: 'http://example.com' + author: + name: string + username: string + description: string + url: string + avatar: string + repository: + id: 0 + name: string + description: string + url: string + image: string + newIssueUrl: 'http://example.com' + newPullUrl: 'http://example.com' + labels: + - id: 0 + name: string + color: string + description: string + tags: + - id: 0 + name: string + description: string + color: string + type: string + featured: true + pulls: + - id: 0 + title: string + timestamp: 0 + status: open + url: 'http://example.com' + author: + name: string + username: string + description: string + url: string + avatar: string + repository: + id: 0 + name: string + description: string + url: string + image: string + newIssueUrl: 'http://example.com' + newPullUrl: 'http://example.com' + labels: + - id: 0 + name: string + color: string + description: string + tags: + - id: 0 + name: string + description: string + color: string + type: string + featured: true + projects: + - id: 0 + name: string + description: string + image: string + statistics: + issuesCount: 0 + repositoriesCount: 0 + pullsCount: 0 + tags: + - id: 0 + name: string + description: string + color: string + type: string + featured: true + branches: + - id: 0 + name: string + url: string + repository: + id: 0 + name: string + description: string + url: string + image: string + newIssueUrl: 'http://example.com' + newPullUrl: 'http://example.com' + tags: + - id: 0 + name: string + description: string + color: string + type: string + featured: true operationId: get-search description: Search for specific data using a given query. parameters: @@ -876,7 +978,7 @@ paths: required: true get: summary: Get tags linked to a specific repository - tags: [ ] + tags: [] responses: '200': description: OK @@ -890,11 +992,11 @@ paths: '/oauth/{provider}': get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '307': description: Temporary Redirect - headers: { } + headers: {} operationId: get-oauth-zeus description: |- OAuth endpoint for login with {provider}. @@ -923,7 +1025,7 @@ paths: /oauth/callback: get: summary: Your GET endpoint - tags: [ ] + tags: [] operationId: get-oauth-callback parameters: - schema: @@ -970,7 +1072,7 @@ paths: required: true get: summary: Your GET endpoint - tags: [ ] + tags: [] responses: '200': description: OK @@ -983,4 +1085,4 @@ paths: operationId: get-projects-id-subprojects description: Get a list with subprojects for a given project. components: - schemas: { } + schemas: {} diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index 308d373..032dbc5 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -14,7 +14,7 @@ Autoincrementing primary keys: The standard is pretty bad and verbose. Sqlite au -- :name update-generic! :! :n /* :require [clojure.string :as string] [hugsql.parameters :refer [identifier-param-quote]] */ -UPDATE :i:table +UPDATE :i: table SET /*~ (string/join "," @@ -22,12 +22,12 @@ SET (str (identifier-param-quote (name field) options) " = :v:updates." (name field)))) ~*/ -WHERE tag_id = :id; + WHERE tag_id = :id; -- :name create-generic! :! :n /* :require [clojure.string :as string] [hugsql.parameters :refer [identifier-param-quote]] */ -INSERT INTO :i:table +INSERT INTO :i: table ( /*~ (string/join "," @@ -121,7 +121,7 @@ VALUES (:name, :email, :admin, :last_login); -- :name create-zeus-user! :insert :raw INSERT INTO zeus_users - (zeus_id, username, user_id) + (zeus_id, username, user_id) VALUES (:zeus_id, :username, :user_id); -- :name get-user :? :1 @@ -139,7 +139,7 @@ WHERE zeus_id = :zeus_id; -- :name get-users :? :* SELECT * FROM users; - -- LEFT OUTER JOIN zeus_users using (user_id); +-- LEFT OUTER JOIN zeus_users using (user_id); -- :name delete-user! :! :n DELETE @@ -179,7 +179,8 @@ FROM repository_providers; ( -- The entities directly linked to a project select i.*, t.* from :i:table i - inner join tags t on i.tag_id = t.id + inner join tags t + on i.tag_id = t.id inner join tag_relations tr on tr.child_id = i.tag_id where tr.parent_id = :project_id and featured = true ) @@ -187,7 +188,8 @@ UNION ( -- The entities linked to a project via a repo select i.*, t2.* from :i:table i - inner join tags t2 on i.tag_id = t2.id + inner join tags t2 + on i.tag_id = t2.id inner join repos r on i.repo_id = r.tag_id inner join tag_relations tr on tr.child_id = r.tag_id where tr.parent_id = :project_id and featured = true @@ -262,6 +264,12 @@ DELETE FROM projects WHERE tag_id = :id; +-- :name get-projects-by-name-like :? :* +SELECT p.tag_id as id, p.name, p.description, p.image_url as image +FROM projects p + INNER JOIN tags t on p.tag_id = t.id +WHERE p.name like :q; + /* ---- LABELS ---- */ -- :name create-label! :insert :raw @@ -315,10 +323,18 @@ FROM issues i INNER JOIN tag_relations tr on tr.child_id = r.tag_id WHERE tr.parent_id = :project_id; +-- :name get-issues-by-title-like :? :* +SELECT i.tag_id as id, i.title, i.time as timestamp, i.url, i.repo_id, t.featured, i.status +FROM issues i + INNER JOIN repos r on i.repo_id = r.tag_id + INNER JOIN tag_relations tr on tr.child_id = r.tag_id + INNER JOIN tags t on i.tag_id = t.id +WHERE i.title like :q; + -- :name get-issue :? :1 SELECT * FROM issues -WHERE issue_id = :issue_id; +WHERE tag_id = :issue_id; -- :name update-issue! :! :n UPDATE issues diff --git a/src/clj/g2/routes/home.clj b/src/clj/g2/routes/home.clj index bffefe7..a61d659 100644 --- a/src/clj/g2/routes/home.clj +++ b/src/clj/g2/routes/home.clj @@ -10,6 +10,8 @@ [g2.routes.labels :as labels] [g2.routes.branches :as branches] [g2.routes.namedtags :as namedtags] + [g2.services.issues-service :as issues-service] + [g2.services.projects-service :as projects-service] [ring.util.http-response :as response] [clojure.java.io :as io] [clojure.tools.logging :as log] @@ -26,6 +28,20 @@ (defn home-routes [] [["/" {:get {:handler home-page}}] + ["/search" {:get {:summary "Search for specific data using a given query." + :handler (fn [req] + (print "Query params") + (println (get req :query-params)) + (let [q (get-in req [:query-params "q"]) + limit (get-in req [:query-params "limit"]) + page (get-in req [:query-params "page"]) + result + {:issues (issues-service/get-issues-with q) + :pulls [] + :projects (projects-service/get-projects-with q) + :branches []}] + (println result) + (response/ok result)))}}] ["/user" {:get {:summary "Get the current user data from the session." ; :parameters :responses {200 {:body {:name string? :admin boolean? :avatar string?}} diff --git a/src/clj/g2/services/issues_service.clj b/src/clj/g2/services/issues_service.clj index b8765d5..dbc5663 100644 --- a/src/clj/g2/services/issues_service.clj +++ b/src/clj/g2/services/issues_service.clj @@ -5,6 +5,14 @@ [g2.utils.debugging :refer [log-thread]] [clojure.tools.logging :as log])) +(defn parse-issue [issue] + (-> issue + (assoc :author (author-service/dummy-author)) + (assoc :repository (generic-service/get-entity (:repo_id issue) "repos")) + (assoc :labels []) + (assoc :tags []) + (dissoc :repo_id))) + (defn get-project-issues-count [project_id] (-> (db/get-project-indirect-issues-count {:project_id project_id}) log-thread @@ -14,9 +22,7 @@ (let [issues (db/get-project-indirect-issues {:project_id project_id})] (map (fn [issue] (log/debug (format "Issue<%s>" (str issue))) - (-> issue - (assoc :author (author-service/dummy-author)) - (assoc :repository (generic-service/get-entity (:repo_id issue) "repos")) - (assoc :labels []) - (assoc :tags []) - (dissoc :repo_id))) issues))) + (parse-issue issue)) issues))) + +(defn get-issues-with [q] + (map parse-issue (db/get-issues-by-title-like {:q (format "%%%s%%" q)}))) diff --git a/src/clj/g2/services/projects_service.clj b/src/clj/g2/services/projects_service.clj index 001405b..b398ce5 100644 --- a/src/clj/g2/services/projects_service.clj +++ b/src/clj/g2/services/projects_service.clj @@ -11,6 +11,13 @@ [clojure.tools.logging :as log] [clojure.set :as set])) + +(defn parse-project [project] + (-> project + (assoc :statistics {:issuesCount 0 :repositoriesCount 0 :pullsCount 0}) + (assoc :tags []) + (assoc :featured false))) + (defn flip [f] (fn [x y & args] (apply f y x args))) (defn- construct-project-from-base-bare [{project_id :id :as project}] @@ -47,3 +54,6 @@ (merge new_values) log-thread (db/update-project!))))) + +(defn get-projects-with [q] + (map parse-project (db/get-projects-by-name-like {:q (format "%%%s%%" q)}))) From 720ee55978eb96fc8af88bb3caa3ce146c4583f7 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Thu, 10 Dec 2020 05:53:58 +0100 Subject: [PATCH 2/3] Add project branch lookup --- resources/sql/queries.sql | 14 ++++++++ src/clj/g2/routes/branches.clj | 43 ++++++++++++------------ src/clj/g2/routes/issues.clj | 1 - src/clj/g2/services/branches_service.clj | 20 +++++++++++ src/clj/g2/services/issues_service.clj | 3 +- 5 files changed, 58 insertions(+), 23 deletions(-) create mode 100644 src/clj/g2/services/branches_service.clj diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql index 032dbc5..89f0172 100644 --- a/resources/sql/queries.sql +++ b/resources/sql/queries.sql @@ -355,6 +355,20 @@ VALUES (:tag_id, :commit_sha, :name, :repo_id); SELECT * FROM branches; +-- :name get-project-indirect-branches :? :* +SELECT b.tag_id as id, b.name, b.repo_id +FROM branches b + INNER JOIN repos r on b.repo_id = r.tag_id + INNER JOIN tag_relations tr on tr.child_id = r.tag_id +WHERE tr.parent_id = :project_id; + +-- :name get-project-indirect-branches-count :? :1 +SELECT count(b.tag_id) as count +FROM branches b + INNER JOIN repos r on b.repo_id = r.tag_id + INNER JOIN tag_relations tr on tr.child_id = r.tag_id +WHERE tr.parent_id = :project_id; + -- :name get-branch :? :1 SELECT * FROM branches diff --git a/src/clj/g2/routes/branches.clj b/src/clj/g2/routes/branches.clj index 8c674cb..0b8b5e4 100644 --- a/src/clj/g2/routes/branches.clj +++ b/src/clj/g2/routes/branches.clj @@ -1,20 +1,21 @@ (ns g2.routes.branches (:require [g2.db.core :refer [*db*] :as db] - [g2.git.github :refer [sync-branches]] - [slingshot.slingshot :refer [try+]] - [clojure.tools.logging :as log] - [ring.util.http-response :as response] - [g2.utils.projects :as p-utils] - [g2.routes.tags :as tags] - [g2.utils.entity :as entity])) + [g2.git.github :refer [sync-branches]] + [slingshot.slingshot :refer [try+]] + [clojure.tools.logging :as log] + [ring.util.http-response :as response] + [g2.utils.projects :as p-utils] + [g2.routes.tags :as tags] + [g2.services.branches-service :as branches-service] + [g2.utils.entity :as entity])) -(defn get-project-branches [project_id] +(defn project-branches [project_id] (do (log/debug "Get branches project" project_id) (p-utils/is-project project_id - (response/ok (db/get-project-branches {:project_id project_id}))))) + (response/ok (branches-service/get-project-branches project_id))))) (defn sync-all [_] @@ -51,17 +52,17 @@ #_["/:issue_id" {:get {:parameters {:path {:issue_id int?}} :handler #(get-by-id (get-in % [:path-params :issue_id]))}}] - ["/:id/feature" {:delete {:summary "Unfeature the branch with the given id." - :responses {200 {} - 404 {:description "The branch with the specified id does not exist."}} - :parameters {:path {:id int?}} - :handler #(response/not-implemented)} - :post {:summary "Feature the branch with the given id." - :responses {200 {} - 404 {:description "The branch with the specified id does not exist."}} - :parameters {:path {:id int?}} - :handler #(response/not-implemented)}}]] - ) + ["/:id/feature" {:delete {:summary "Unfeature the branch with the given id." + :responses {200 {} + 404 {:description "The branch with the specified id does not exist."}} + :parameters {:path {:id int?}} + :handler #(response/not-implemented)} + :post {:summary "Feature the branch with the given id." + :responses {200 {} + 404 {:description "The branch with the specified id does not exist."}} + :parameters {:path {:id int?}} + :handler #(response/not-implemented)}}]] + ) (defn route-handler-per-project [] ["/branches" @@ -70,4 +71,4 @@ :responses {200 {} 404 {:description "The project with the specified id does not exist."}} :parameters {:path {:id int?}} - :handler #(get-project-branches (get-in % [:path-params :id]))}}]]) + :handler #(project-branches (get-in % [:path-params :id]))}}]]) diff --git a/src/clj/g2/routes/issues.clj b/src/clj/g2/routes/issues.clj index feec972..a9e0092 100644 --- a/src/clj/g2/routes/issues.clj +++ b/src/clj/g2/routes/issues.clj @@ -12,7 +12,6 @@ [g2.services.generic-service :as generic-service])) - (defn project-issues [project-id?] (do (log/debug (format "Get issues for project<%s>" project-id?)) diff --git a/src/clj/g2/services/branches_service.clj b/src/clj/g2/services/branches_service.clj new file mode 100644 index 0000000..b0ca3fe --- /dev/null +++ b/src/clj/g2/services/branches_service.clj @@ -0,0 +1,20 @@ +(ns g2.services.branches-service + (:require [g2.db.core :refer [*db*] :as db] + [g2.services.generic-service :as generic-service] + [clojure.tools.logging :as log] + )) + + +(defn parse-branch [branch] + (-> branch + (assoc :url "") ;; TODO + (assoc :repository (generic-service/get-entity (:repo_id branch) "repos")) + (assoc :tags []) + (assoc :featured false) + (dissoc :repo_id))) + +(defn get-project-branches [project_id] + (let [branches (db/get-project-indirect-branches {:project_id project_id})] + (map (fn [branch] + (log/debug (format "Branch<%s>" (str branch))) + (parse-branch branch)) branches))) diff --git a/src/clj/g2/services/issues_service.clj b/src/clj/g2/services/issues_service.clj index dbc5663..e01db35 100644 --- a/src/clj/g2/services/issues_service.clj +++ b/src/clj/g2/services/issues_service.clj @@ -3,7 +3,8 @@ [g2.services.generic-service :as generic-service] [g2.services.author-service :as author-service] [g2.utils.debugging :refer [log-thread]] - [clojure.tools.logging :as log])) + [clojure.tools.logging :as log] + )) (defn parse-issue [issue] (-> issue From 3f2bc7a2ef8b0fc5b03492bd25d59d34782c37c7 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Thu, 10 Dec 2020 06:06:07 +0100 Subject: [PATCH 3/3] Use new validator --- src/clj/g2/routes/branches.clj | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/clj/g2/routes/branches.clj b/src/clj/g2/routes/branches.clj index 0b8b5e4..b080159 100644 --- a/src/clj/g2/routes/branches.clj +++ b/src/clj/g2/routes/branches.clj @@ -8,15 +8,16 @@ [g2.utils.projects :as p-utils] [g2.routes.tags :as tags] [g2.services.branches-service :as branches-service] + [g2.services.validator-service :as validator-service] [g2.utils.entity :as entity])) -(defn project-branches [project_id] +(defn project-branches [project-id?] (do - (log/debug "Get branches project" project_id) - (p-utils/is-project - project_id - (response/ok (branches-service/get-project-branches project_id))))) - + (log/debug (format "Get branches for project<%s>" project-id?)) + (if-not [(validator-service/validate-is-project project-id?)] + (response/not-found) + (response/ok + (branches-service/get-project-branches project-id?))))) (defn sync-all [_] (log/debug "Syncing all branches")