2021-01-02 05:07:43 +03:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2021-01-02 05:07:43 +03:00
2021-09-19 14:49:59 +03:00
package db
2021-01-02 05:07:43 +03:00
import (
"database/sql"
"database/sql/driver"
"sync"
"code.gitea.io/gitea/modules/setting"
"github.com/lib/pq"
"xorm.io/xorm/dialects"
)
var registerOnce sync . Once
func registerPostgresSchemaDriver ( ) {
registerOnce . Do ( func ( ) {
sql . Register ( "postgresschema" , & postgresSchemaDriver { } )
dialects . RegisterDriver ( "postgresschema" , dialects . QueryDriver ( "postgres" ) )
} )
}
type postgresSchemaDriver struct {
pq . Driver
}
// Open opens a new connection to the database. name is a connection string.
// This function opens the postgres connection in the default manner but immediately
// runs set_config to set the search_path appropriately
func ( d * postgresSchemaDriver ) Open ( name string ) ( driver . Conn , error ) {
conn , err := d . Driver . Open ( name )
if err != nil {
return conn , err
}
schemaValue , _ := driver . String . ConvertValue ( setting . Database . Schema )
2023-02-12 00:44:53 +03:00
// golangci lint is incorrect here - there is no benefit to using driver.ExecerContext here
// and in any case pq does not implement it
if execer , ok := conn . ( driver . Execer ) ; ok { //nolint
2021-01-02 05:07:43 +03:00
_ , err := execer . Exec ( ` SELECT set_config (
' search_path ' ,
$ 1 || ',' || current_setting ( ' search_path ' ) ,
2022-06-20 13:02:49 +03:00
false ) ` , [ ] driver . Value { schemaValue } )
2021-01-02 05:07:43 +03:00
if err != nil {
_ = conn . Close ( )
return nil , err
}
return conn , nil
}
stmt , err := conn . Prepare ( ` SELECT set_config (
' search_path ' ,
$ 1 || ',' || current_setting ( ' search_path ' ) ,
false ) ` )
if err != nil {
_ = conn . Close ( )
return nil , err
}
defer stmt . Close ( )
// driver.String.ConvertValue will never return err for string
2023-02-12 00:44:53 +03:00
// golangci lint is incorrect here - there is no benefit to using stmt.ExecWithContext here
_ , err = stmt . Exec ( [ ] driver . Value { schemaValue } ) //nolint
2021-01-02 05:07:43 +03:00
if err != nil {
_ = conn . Close ( )
return nil , err
}
return conn , nil
}