Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ require (
replace (
github.com/argoproj/argo-workflows/v3 v3.5.13 => github.com/devtron-labs/argo-workflows/v3 v3.5.13
github.com/cyphar/filepath-securejoin v0.4.1 => github.com/cyphar/filepath-securejoin v0.3.6 // indirect
github.com/devtron-labs/authenticator => github.com/devtron-labs/devtron-services/authenticator v0.0.0-20250806142853-d5a47198188d
github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250806142853-d5a47198188d
github.com/devtron-labs/authenticator => github.com/devtron-labs/devtron-services/authenticator v0.0.0-20250901093002-1be330be4db3
github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,10 @@ github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzq
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/devtron-labs/argo-workflows/v3 v3.5.13 h1:3pINq0gXOSeTw2z/vYe+j80lRpSN5Rp/8mfQORh8SmU=
github.com/devtron-labs/argo-workflows/v3 v3.5.13/go.mod h1:/vqxcovDPT4zqr4DjR5v7CF8ggpY1l3TSa2CIG3jmjA=
github.com/devtron-labs/devtron-services/authenticator v0.0.0-20250806142853-d5a47198188d h1:+g3SnMSqHWPpKkU2fdp1dTkcPvedXuZ6kVR7S4U4IvU=
github.com/devtron-labs/devtron-services/authenticator v0.0.0-20250806142853-d5a47198188d/go.mod h1:9LCkYfiWaEKIBkmxw9jX1GujvEMyHwmDtVsatffAkeU=
github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250806142853-d5a47198188d h1:PcwklqogA1ppPtC0M2jn2QiFAkoKKeOY2tbNOCjedeI=
github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250806142853-d5a47198188d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA=
github.com/devtron-labs/devtron-services/authenticator v0.0.0-20250901093002-1be330be4db3 h1:7WTBEjb3nhvfAbbYyKYb8oTRRyLQ89mkVCIhKzN7Iu0=
github.com/devtron-labs/devtron-services/authenticator v0.0.0-20250901093002-1be330be4db3/go.mod h1:9LCkYfiWaEKIBkmxw9jX1GujvEMyHwmDtVsatffAkeU=
github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M=
github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA=
github.com/devtron-labs/go-bitbucket v0.9.60-beta h1:VEx1jvDgdtDPS6A1uUFoaEi0l1/oLhbr+90xOwr6sDU=
github.com/devtron-labs/go-bitbucket v0.9.60-beta/go.mod h1:GnuiCesvh8xyHeMCb+twm8lBR/kQzJYSKL28ZfObp1Y=
github.com/devtron-labs/protos v0.0.3-0.20250323220609-ecf8a0f7305e h1:U6UdYbW8a7xn5IzFPd8cywjVVPfutGJCudjePAfL/Hs=
Expand Down
4 changes: 2 additions & 2 deletions internal/sql/repository/AppListingRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ func (impl *AppListingRepositoryImpl) FetchJobsLastSucceededOn(CiPipelineIDs []i
if len(CiPipelineIDs) == 0 {
return lastSucceededTimeArray, nil
}
jobsLastFinishedOnQuery := impl.appListingRepositoryQueryBuilder.JobsLastSucceededOnTimeQuery(CiPipelineIDs)
jobsLastFinishedOnQuery, queryParams := impl.appListingRepositoryQueryBuilder.JobsLastSucceededOnTimeQuery(CiPipelineIDs)
impl.Logger.Debugw("basic app detail query: ", jobsLastFinishedOnQuery)
_, appsErr := impl.dbConnection.Query(&lastSucceededTimeArray, jobsLastFinishedOnQuery)
_, appsErr := impl.dbConnection.Query(&lastSucceededTimeArray, jobsLastFinishedOnQuery, queryParams...)
if appsErr != nil {
impl.Logger.Errorw("error in fetching lastSucceededTimeArray", "error", appsErr, jobsLastFinishedOnQuery)
return lastSucceededTimeArray, appsErr
Expand Down
13 changes: 6 additions & 7 deletions internal/sql/repository/CiArtifactRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package repository
import (
"encoding/json"
"fmt"
"github.com/devtron-labs/devtron/internal/sql/repository/helper"
"github.com/devtron-labs/devtron/pkg/sql"
"github.com/devtron-labs/devtron/util"
"golang.org/x/exp/slices"
Expand Down Expand Up @@ -419,9 +418,9 @@ func (impl CiArtifactRepositoryImpl) GetLatestArtifactTimeByCiPipelineIds(ciPipe
"(SELECT pipeline_id, MAX(created_on) created_on " +
"FROM ci_artifact " +
"GROUP BY pipeline_id) cws " +
"where cws.pipeline_id IN (" + helper.GetCommaSepratedString(ciPipelineIds) + "); "
"where cws.pipeline_id IN (?); "

_, err := impl.dbConnection.Query(&artifacts, query)
_, err := impl.dbConnection.Query(&artifacts, query, pg.In(ciPipelineIds))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -779,8 +778,8 @@ func (impl CiArtifactRepositoryImpl) FindArtifactByListFilter(listingFilterOptio
var ciArtifactsResp []CiArtifactWithExtraData
ciArtifacts := make([]*CiArtifact, 0)
totalCount := 0
finalQuery := BuildQueryForArtifactsForCdStage(*listingFilterOptions)
_, err := impl.dbConnection.Query(&ciArtifactsResp, finalQuery)
finalQuery, queryParams := BuildQueryForArtifactsForCdStage(*listingFilterOptions)
_, err := impl.dbConnection.Query(&ciArtifactsResp, finalQuery, queryParams...)
if err == pg.ErrNoRows || len(ciArtifactsResp) == 0 {
return ciArtifacts, totalCount, nil
}
Expand Down Expand Up @@ -821,8 +820,8 @@ func (impl CiArtifactRepositoryImpl) FindArtifactByListFilter(listingFilterOptio
func (impl CiArtifactRepositoryImpl) FetchArtifactsByCdPipelineIdV2(listingFilterOptions bean.ArtifactsListFilterOptions) ([]CiArtifactWithExtraData, int, error) {
var wfrList []CiArtifactWithExtraData
totalCount := 0
finalQuery := BuildQueryForArtifactsForRollback(listingFilterOptions)
_, err := impl.dbConnection.Query(&wfrList, finalQuery)
finalQuery, queryParams := BuildQueryForArtifactsForRollback(listingFilterOptions)
_, err := impl.dbConnection.Query(&wfrList, finalQuery, queryParams...)
if err != nil && err != pg.ErrNoRows {
impl.logger.Errorw("error in getting Wfrs and ci artifacts by pipelineId", "err", err, "pipelineId", listingFilterOptions.PipelineId)
return nil, totalCount, err
Expand Down
128 changes: 84 additions & 44 deletions internal/sql/repository/CiArtifactsListingQueryBuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package repository
import (
"fmt"
"github.com/devtron-labs/devtron/api/bean"
"github.com/devtron-labs/devtron/internal/sql/repository/helper"
"github.com/go-pg/pg"
)

Expand All @@ -28,7 +27,7 @@ const EmptyLikeRegex = "%%"
func BuildQueryForParentTypeCIOrWebhook(listingFilterOpts bean.ArtifactsListFilterOptions) (string, []interface{}) {
commonPaginatedQueryPart, commonPaginatedQueryParams := " cia.image LIKE ?", []interface{}{listingFilterOpts.SearchString}
orderByClause := " ORDER BY cia.id DESC"
limitOffsetQueryPart, limitOffsetQueryParams := fmt.Sprintf(" LIMIT ? OFFSET ?"), []interface{}{listingFilterOpts.Limit, listingFilterOpts.Offset}
limitOffsetQueryPart, limitOffsetQueryParams := " LIMIT ? OFFSET ?", []interface{}{listingFilterOpts.Limit, listingFilterOpts.Offset}
finalQuery := ""
var finalQueryParams []interface{}
var remainingQueryParams []interface{}
Expand Down Expand Up @@ -71,82 +70,123 @@ func BuildQueryForParentTypeCIOrWebhook(listingFilterOpts bean.ArtifactsListFilt
return finalQuery, finalQueryParams
}

func BuildQueryForArtifactsForCdStage(listingFilterOptions bean.ArtifactsListFilterOptions) string {
func BuildQueryForArtifactsForCdStage(listingFilterOptions bean.ArtifactsListFilterOptions) (string, []interface{}) {
// expected result -> will fetch all successfully deployed artifacts ar parent stage plus its own stage. Along with this it will
// also fetch all artifacts generated by plugin at pre_cd or post_cd process (will use data_source in ci artifact table for this)

if listingFilterOptions.UseCdStageQueryV2 {
return buildQueryForArtifactsForCdStageV2(listingFilterOptions)
}

var queryParams []interface{}

commonQuery := " from ci_artifact LEFT JOIN cd_workflow ON ci_artifact.id = cd_workflow.ci_artifact_id" +
" LEFT JOIN cd_workflow_runner ON cd_workflow_runner.cd_workflow_id=cd_workflow.id " +
" Where (((cd_workflow_runner.id in (select MAX(cd_workflow_runner.id) OVER (PARTITION BY cd_workflow.ci_artifact_id) FROM cd_workflow_runner inner join cd_workflow on cd_workflow.id=cd_workflow_runner.cd_workflow_id))" +
" AND ((cd_workflow.pipeline_id= %v and cd_workflow_runner.workflow_type = '%v' ) OR (cd_workflow.pipeline_id = %v AND cd_workflow_runner.workflow_type = '%v' AND cd_workflow_runner.status IN ('Healthy','Succeeded') )))" +
" OR (ci_artifact.component_id = %v and ci_artifact.data_source= '%v' ))" +
" AND (ci_artifact.image LIKE '%v' )"
" AND ((cd_workflow.pipeline_id = ? and cd_workflow_runner.workflow_type = ?) OR (cd_workflow.pipeline_id = ? AND cd_workflow_runner.workflow_type = ? AND cd_workflow_runner.status IN ('Healthy','Succeeded') )))" +
" OR (ci_artifact.component_id = ? and ci_artifact.data_source = ?))" +
" AND (ci_artifact.image LIKE ?)"

queryParams = append(queryParams,
listingFilterOptions.PipelineId,
listingFilterOptions.StageType,
listingFilterOptions.ParentId,
listingFilterOptions.ParentStageType,
listingFilterOptions.ParentId,
listingFilterOptions.PluginStage,
listingFilterOptions.SearchString)

commonQuery = fmt.Sprintf(commonQuery, listingFilterOptions.PipelineId, listingFilterOptions.StageType, listingFilterOptions.ParentId, listingFilterOptions.ParentStageType, listingFilterOptions.ParentId, listingFilterOptions.PluginStage, listingFilterOptions.SearchString)
if len(listingFilterOptions.ExcludeArtifactIds) > 0 {
commonQuery = commonQuery + fmt.Sprintf(" AND ( ci_artifact.id NOT IN (%v))", helper.GetCommaSepratedString(listingFilterOptions.ExcludeArtifactIds))
commonQuery += " AND ci_artifact.id NOT IN (?)"
queryParams = append(queryParams, pg.In(listingFilterOptions.ExcludeArtifactIds))
}

totalCountQuery := "SELECT COUNT(DISTINCT ci_artifact.id) as total_count " + commonQuery
selectQuery := fmt.Sprintf("SELECT DISTINCT(ci_artifact.id) , (%v) ", totalCountQuery)
//GroupByQuery := " GROUP BY cia.id "
limitOffSetQuery := fmt.Sprintf(" order by ci_artifact.id desc LIMIT %v OFFSET %v", listingFilterOptions.Limit, listingFilterOptions.Offset)
selectQuery := "SELECT DISTINCT(ci_artifact.id), (" + totalCountQuery + ") "
limitOffSetQuery := " order by ci_artifact.id desc LIMIT ? OFFSET ?"

// Duplicate queryParams for the subquery
finalQueryParams := append(queryParams, queryParams...)
finalQueryParams = append(finalQueryParams, listingFilterOptions.Limit, listingFilterOptions.Offset)

//finalQuery := selectQuery + commonQuery + GroupByQuery + limitOffSetQuery
finalQuery := selectQuery + commonQuery + limitOffSetQuery
return finalQuery
return finalQuery, finalQueryParams
}

func buildQueryForArtifactsForCdStageV2(listingFilterOptions bean.ArtifactsListFilterOptions) string {
whereCondition := fmt.Sprintf(" WHERE (id IN ("+
" SELECT DISTINCT(cd_workflow.ci_artifact_id) as ci_artifact_id "+
" FROM cd_workflow_runner"+
" INNER JOIN cd_workflow ON cd_workflow.id = cd_workflow_runner.cd_workflow_id "+
" AND (cd_workflow.pipeline_id = %d OR cd_workflow.pipeline_id = %d)"+
" WHERE ("+
" (cd_workflow.pipeline_id = %d AND cd_workflow_runner.workflow_type = '%s')"+
" OR"+
" (cd_workflow.pipeline_id = %d"+
" AND cd_workflow_runner.workflow_type = '%s'"+
" AND cd_workflow_runner.status IN ('Healthy','Succeeded')"+
" )"+
" ) ) ", listingFilterOptions.PipelineId, listingFilterOptions.ParentId, listingFilterOptions.PipelineId, listingFilterOptions.StageType, listingFilterOptions.ParentId, listingFilterOptions.ParentStageType)

whereCondition = fmt.Sprintf(" %s OR (ci_artifact.component_id = %d AND ci_artifact.data_source= '%s' ))", whereCondition, listingFilterOptions.ParentId, listingFilterOptions.PluginStage)
func buildQueryForArtifactsForCdStageV2(listingFilterOptions bean.ArtifactsListFilterOptions) (string, []interface{}) {
var queryParams []interface{}

whereCondition := " WHERE (id IN (" +
" SELECT DISTINCT(cd_workflow.ci_artifact_id) as ci_artifact_id " +
" FROM cd_workflow_runner" +
" INNER JOIN cd_workflow ON cd_workflow.id = cd_workflow_runner.cd_workflow_id " +
" AND (cd_workflow.pipeline_id = ? OR cd_workflow.pipeline_id = ?)" +
" WHERE (" +
" (cd_workflow.pipeline_id = ? AND cd_workflow_runner.workflow_type = ?)" +
" OR" +
" (cd_workflow.pipeline_id = ?" +
" AND cd_workflow_runner.workflow_type = ?" +
" AND cd_workflow_runner.status IN ('Healthy','Succeeded')" +
" )" +
" ) ) "

queryParams = append(queryParams,
listingFilterOptions.PipelineId,
listingFilterOptions.ParentId,
listingFilterOptions.PipelineId,
listingFilterOptions.StageType,
listingFilterOptions.ParentId,
listingFilterOptions.ParentStageType)

whereCondition += " OR (ci_artifact.component_id = ? AND ci_artifact.data_source = ?))"
queryParams = append(queryParams, listingFilterOptions.ParentId, listingFilterOptions.PluginStage)

if listingFilterOptions.SearchString != EmptyLikeRegex {
whereCondition = whereCondition + fmt.Sprintf(" AND ci_artifact.image LIKE '%s' ", listingFilterOptions.SearchString)
whereCondition += " AND ci_artifact.image LIKE ?"
queryParams = append(queryParams, listingFilterOptions.SearchString)
}

if len(listingFilterOptions.ExcludeArtifactIds) > 0 {
whereCondition = whereCondition + fmt.Sprintf(" AND ( ci_artifact.id NOT IN (%s))", helper.GetCommaSepratedString(listingFilterOptions.ExcludeArtifactIds))
whereCondition += " AND ci_artifact.id NOT IN (?)"
queryParams = append(queryParams, pg.In(listingFilterOptions.ExcludeArtifactIds))
}

selectQuery := fmt.Sprintf(" SELECT ci_artifact.* ,COUNT(id) OVER() AS total_count " +
" FROM ci_artifact")
ordeyByAndPaginated := fmt.Sprintf(" ORDER BY id DESC LIMIT %d OFFSET %d ", listingFilterOptions.Limit, listingFilterOptions.Offset)
finalQuery := selectQuery + whereCondition + ordeyByAndPaginated
return finalQuery
selectQuery := " SELECT ci_artifact.*, COUNT(id) OVER() AS total_count FROM ci_artifact"
orderByAndPaginated := " ORDER BY id DESC LIMIT ? OFFSET ?"
queryParams = append(queryParams, listingFilterOptions.Limit, listingFilterOptions.Offset)

finalQuery := selectQuery + whereCondition + orderByAndPaginated
return finalQuery, queryParams
}

func BuildQueryForArtifactsForRollback(listingFilterOptions bean.ArtifactsListFilterOptions) string {
func BuildQueryForArtifactsForRollback(listingFilterOptions bean.ArtifactsListFilterOptions) (string, []interface{}) {
var queryParams []interface{}

commonQuery := " FROM cd_workflow_runner cdwr " +
" INNER JOIN cd_workflow cdw ON cdw.id=cdwr.cd_workflow_id " +
" INNER JOIN ci_artifact cia ON cia.id=cdw.ci_artifact_id " +
" WHERE cdw.pipeline_id=%v AND cdwr.workflow_type = '%v' "
" WHERE cdw.pipeline_id = ? AND cdwr.workflow_type = ?"

queryParams = append(queryParams, listingFilterOptions.PipelineId, listingFilterOptions.StageType)

commonQuery = fmt.Sprintf(commonQuery, listingFilterOptions.PipelineId, listingFilterOptions.StageType)
if listingFilterOptions.SearchString != EmptyLikeRegex {
commonQuery += fmt.Sprintf(" AND cia.image LIKE '%v' ", listingFilterOptions.SearchString)
commonQuery += " AND cia.image LIKE ?"
queryParams = append(queryParams, listingFilterOptions.SearchString)
}

if len(listingFilterOptions.ExcludeWfrIds) > 0 {
commonQuery = fmt.Sprintf(" %s AND cdwr.id NOT IN (%s)", commonQuery, helper.GetCommaSepratedString(listingFilterOptions.ExcludeWfrIds))
commonQuery += " AND cdwr.id NOT IN (?)"
queryParams = append(queryParams, pg.In(listingFilterOptions.ExcludeWfrIds))
}

totalCountQuery := " SELECT COUNT(cia.id) as total_count " + commonQuery
orderByQuery := " ORDER BY cdwr.id DESC "
limitOffsetQuery := fmt.Sprintf("LIMIT %v OFFSET %v", listingFilterOptions.Limit, listingFilterOptions.Offset)
finalQuery := fmt.Sprintf(" SELECT cdwr.id as cd_workflow_runner_id,cdwr.triggered_by,cdwr.started_on,cia.*,(%s) ", totalCountQuery) + commonQuery + orderByQuery + limitOffsetQuery
return finalQuery
limitOffsetQuery := " LIMIT ? OFFSET ?"

// Duplicate queryParams for the subquery
finalQueryParams := append(queryParams, queryParams...)
finalQueryParams = append(finalQueryParams, listingFilterOptions.Limit, listingFilterOptions.Offset)

finalQuery := " SELECT cdwr.id as cd_workflow_runner_id,cdwr.triggered_by,cdwr.started_on,cia.*,(" + totalCountQuery + ") " + commonQuery + orderByQuery + limitOffsetQuery
return finalQuery, finalQueryParams
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,16 @@ func (impl AppListingRepositoryQueryBuilder) OverviewCiPipelineQuery() string {
}

// use this query with atleast 1 cipipeline id
func (impl AppListingRepositoryQueryBuilder) JobsLastSucceededOnTimeQuery(ciPipelineIDs []int) string {
func (impl AppListingRepositoryQueryBuilder) JobsLastSucceededOnTimeQuery(ciPipelineIDs []int) (string, []interface{}) {
// use this query with atleast 1 cipipeline id
query := "select cw.ci_pipeline_id,cw.finished_on " +
"as last_succeeded_on from ci_workflow cw inner join " +
"(SELECT ci_pipeline_id, MAX(finished_on) finished_on " +
"FROM ci_workflow WHERE ci_workflow.status = 'Succeeded'" +
"GROUP BY ci_pipeline_id) cws on cw.ci_pipeline_id = cws.ci_pipeline_id and cw.finished_on = cws.finished_on " +
"where cw.ci_pipeline_id IN (" + GetCommaSepratedString(ciPipelineIDs) + "); "
"where cw.ci_pipeline_id IN (?); "

return query
return query, []interface{}{pg.In(ciPipelineIDs)}
}

func getAppListingCommonQueryString() string {
Expand Down
13 changes: 8 additions & 5 deletions pkg/auth/user/repository/DefaultAuthPolicyRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,18 @@ func (impl DefaultAuthPolicyRepositoryImpl) UpdatePolicyByRoleType(policy string

func (impl DefaultAuthPolicyRepositoryImpl) GetPolicyByRoleTypeAndEntity(roleType bean.RoleType, accessType string, entity string) (policy string, err error) {
var model DefaultAuthPolicy
query := "SELECT * FROM default_auth_policy WHERE role_type = ? "
query += " and entity = '" + entity + "' "
var queryParams []interface{}
query := "SELECT * FROM default_auth_policy WHERE role_type = ? AND entity = ? "
queryParams = append(queryParams, roleType, entity)

if accessType == "" {
query += "and access_type IS NULL ;"
query += "AND access_type IS NULL ;"
} else {
query += "and access_type ='" + accessType + "' ;"
query += "AND access_type = ? ;"
queryParams = append(queryParams, accessType)
}

_, err = impl.dbConnection.Query(&model, query, roleType)
_, err = impl.dbConnection.Query(&model, query, queryParams...)
if err != nil {
impl.logger.Error("error in getting policy by roleType", "err", err, "roleType", roleType, "entity", entity)
return "", err
Expand Down
23 changes: 20 additions & 3 deletions pkg/auth/user/repository/helper/UserRepositoryQueryBuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package helper

import (
"fmt"

bean2 "github.com/devtron-labs/devtron/pkg/auth/user/bean"
"github.com/devtron-labs/devtron/util"
)
Expand Down Expand Up @@ -83,11 +84,27 @@ func GetQueryForGroupListingWithFilters(req *bean2.ListingRequest) (string, []in

orderCondition := ""
if len(req.SortBy) > 0 && !req.CountCheck {
orderCondition += " order by "
// Validate SortBy to prevent SQL injection - only allow safe column names
var sortColumn string
switch req.SortBy {
case bean2.GroupName:
sortColumn = "name"
case "id":
sortColumn = "id"
case "created_on":
sortColumn = "created_on"
case "updated_on":
sortColumn = "updated_on"
default:
// Default to name if invalid sort field provided
sortColumn = "name"
}

orderCondition += " order by " + sortColumn
if req.SortOrder == bean2.Desc {
orderCondition += fmt.Sprintf(" %s %s ", req.SortBy, bean2.Desc)
orderCondition += " DESC"
} else {
orderCondition += fmt.Sprintf(" %s ", req.SortBy)
orderCondition += " ASC"
}
}
if req.Size > 0 && !req.CountCheck && !req.ShowAll {
Expand Down
Loading
Loading