mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
update lib/pq (#9788)
This commit is contained in:
parent
b65ea57f97
commit
f8698dc49b
1
vendor/github.com/lib/pq/README.md
generated
vendored
1
vendor/github.com/lib/pq/README.md
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
# pq - A pure Go postgres driver for Go's database/sql package
|
# pq - A pure Go postgres driver for Go's database/sql package
|
||||||
|
|
||||||
|
[](https://godoc.org/github.com/lib/pq)
|
||||||
[](https://travis-ci.org/lib/pq)
|
[](https://travis-ci.org/lib/pq)
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
26
vendor/github.com/lib/pq/conn.go
generated
vendored
26
vendor/github.com/lib/pq/conn.go
generated
vendored
@ -35,8 +35,12 @@ var (
|
|||||||
errNoLastInsertID = errors.New("no LastInsertId available after the empty statement")
|
errNoLastInsertID = errors.New("no LastInsertId available after the empty statement")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Driver is the Postgres database driver.
|
||||||
type Driver struct{}
|
type Driver struct{}
|
||||||
|
|
||||||
|
// Open opens a new connection to the database. name is a connection string.
|
||||||
|
// Most users should only use it through database/sql package from the standard
|
||||||
|
// library.
|
||||||
func (d *Driver) Open(name string) (driver.Conn, error) {
|
func (d *Driver) Open(name string) (driver.Conn, error) {
|
||||||
return Open(name)
|
return Open(name)
|
||||||
}
|
}
|
||||||
@ -78,6 +82,8 @@ func (s transactionStatus) String() string {
|
|||||||
panic("not reached")
|
panic("not reached")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dialer is the dialer interface. It can be used to obtain more control over
|
||||||
|
// how pq creates network connections.
|
||||||
type Dialer interface {
|
type Dialer interface {
|
||||||
Dial(network, address string) (net.Conn, error)
|
Dial(network, address string) (net.Conn, error)
|
||||||
DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
|
DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
|
||||||
@ -149,11 +155,7 @@ func (cn *conn) handleDriverSettings(o values) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = boolSetting("binary_parameters", &cn.binaryParameters)
|
return boolSetting("binary_parameters", &cn.binaryParameters)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cn *conn) handlePgpass(o values) {
|
func (cn *conn) handlePgpass(o values) {
|
||||||
@ -165,11 +167,16 @@ func (cn *conn) handlePgpass(o values) {
|
|||||||
if filename == "" {
|
if filename == "" {
|
||||||
// XXX this code doesn't work on Windows where the default filename is
|
// XXX this code doesn't work on Windows where the default filename is
|
||||||
// XXX %APPDATA%\postgresql\pgpass.conf
|
// XXX %APPDATA%\postgresql\pgpass.conf
|
||||||
|
// Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470
|
||||||
|
userHome := os.Getenv("HOME")
|
||||||
|
if userHome == "" {
|
||||||
user, err := user.Current()
|
user, err := user.Current()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
filename = filepath.Join(user.HomeDir, ".pgpass")
|
userHome = user.HomeDir
|
||||||
|
}
|
||||||
|
filename = filepath.Join(userHome, ".pgpass")
|
||||||
}
|
}
|
||||||
fileinfo, err := os.Stat(filename)
|
fileinfo, err := os.Stat(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -237,10 +244,14 @@ func (cn *conn) writeBuf(b byte) *writeBuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open opens a new connection to the database. name is a connection string.
|
||||||
|
// Most users should only use it through database/sql package from the standard
|
||||||
|
// library.
|
||||||
func Open(name string) (_ driver.Conn, err error) {
|
func Open(name string) (_ driver.Conn, err error) {
|
||||||
return DialOpen(defaultDialer{}, name)
|
return DialOpen(defaultDialer{}, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DialOpen opens a new connection to the database using a dialer.
|
||||||
func DialOpen(d Dialer, name string) (_ driver.Conn, err error) {
|
func DialOpen(d Dialer, name string) (_ driver.Conn, err error) {
|
||||||
// Handle any panics during connection initialization. Note that we
|
// Handle any panics during connection initialization. Note that we
|
||||||
// specifically do *not* want to use errRecover(), as that would turn any
|
// specifically do *not* want to use errRecover(), as that would turn any
|
||||||
@ -1431,7 +1442,8 @@ func (rs *rows) NextResultSet() error {
|
|||||||
//
|
//
|
||||||
// tblname := "my_table"
|
// tblname := "my_table"
|
||||||
// data := "my_data"
|
// data := "my_data"
|
||||||
// err = db.Exec(fmt.Sprintf("INSERT INTO %s VALUES ($1)", pq.QuoteIdentifier(tblname)), data)
|
// quoted := pq.QuoteIdentifier(tblname)
|
||||||
|
// err := db.Exec(fmt.Sprintf("INSERT INTO %s VALUES ($1)", quoted), data)
|
||||||
//
|
//
|
||||||
// Any double quotes in name will be escaped. The quoted identifier will be
|
// Any double quotes in name will be escaped. The quoted identifier will be
|
||||||
// case sensitive when used in a query. If the input string contains a zero
|
// case sensitive when used in a query. If the input string contains a zero
|
||||||
|
32
vendor/github.com/lib/pq/doc.go
generated
vendored
32
vendor/github.com/lib/pq/doc.go
generated
vendored
@ -11,7 +11,8 @@ using this package directly. For example:
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
db, err := sql.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")
|
connStr := "user=pqgotest dbname=pqgotest sslmode=verify-full"
|
||||||
|
db, err := sql.Open("postgres", connStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -23,7 +24,8 @@ using this package directly. For example:
|
|||||||
|
|
||||||
You can also connect to a database using a URL. For example:
|
You can also connect to a database using a URL. For example:
|
||||||
|
|
||||||
db, err := sql.Open("postgres", "postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full")
|
connStr := "postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full"
|
||||||
|
db, err := sql.Open("postgres", connStr)
|
||||||
|
|
||||||
|
|
||||||
Connection String Parameters
|
Connection String Parameters
|
||||||
@ -43,21 +45,28 @@ supported:
|
|||||||
* dbname - The name of the database to connect to
|
* dbname - The name of the database to connect to
|
||||||
* user - The user to sign in as
|
* user - The user to sign in as
|
||||||
* password - The user's password
|
* password - The user's password
|
||||||
* host - The host to connect to. Values that start with / are for unix domain sockets. (default is localhost)
|
* host - The host to connect to. Values that start with / are for unix
|
||||||
|
domain sockets. (default is localhost)
|
||||||
* port - The port to bind to. (default is 5432)
|
* port - The port to bind to. (default is 5432)
|
||||||
* sslmode - Whether or not to use SSL (default is require, this is not the default for libpq)
|
* sslmode - Whether or not to use SSL (default is require, this is not
|
||||||
|
the default for libpq)
|
||||||
* fallback_application_name - An application_name to fall back to if one isn't provided.
|
* fallback_application_name - An application_name to fall back to if one isn't provided.
|
||||||
* connect_timeout - Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely.
|
* connect_timeout - Maximum wait for connection, in seconds. Zero or
|
||||||
|
not specified means wait indefinitely.
|
||||||
* sslcert - Cert file location. The file must contain PEM encoded data.
|
* sslcert - Cert file location. The file must contain PEM encoded data.
|
||||||
* sslkey - Key file location. The file must contain PEM encoded data.
|
* sslkey - Key file location. The file must contain PEM encoded data.
|
||||||
* sslrootcert - The location of the root certificate file. The file must contain PEM encoded data.
|
* sslrootcert - The location of the root certificate file. The file
|
||||||
|
must contain PEM encoded data.
|
||||||
|
|
||||||
Valid values for sslmode are:
|
Valid values for sslmode are:
|
||||||
|
|
||||||
* disable - No SSL
|
* disable - No SSL
|
||||||
* require - Always SSL (skip verification)
|
* require - Always SSL (skip verification)
|
||||||
* verify-ca - Always SSL (verify that the certificate presented by the server was signed by a trusted CA)
|
* verify-ca - Always SSL (verify that the certificate presented by the
|
||||||
* verify-full - Always SSL (verify that the certification presented by the server was signed by a trusted CA and the server host name matches the one in the certificate)
|
server was signed by a trusted CA)
|
||||||
|
* verify-full - Always SSL (verify that the certification presented by
|
||||||
|
the server was signed by a trusted CA and the server host name
|
||||||
|
matches the one in the certificate)
|
||||||
|
|
||||||
See http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
|
See http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
|
||||||
for more information about connection string parameters.
|
for more information about connection string parameters.
|
||||||
@ -68,7 +77,7 @@ Use single quotes for values that contain whitespace:
|
|||||||
|
|
||||||
A backslash will escape the next character in values:
|
A backslash will escape the next character in values:
|
||||||
|
|
||||||
"user=space\ man password='it\'s valid'
|
"user=space\ man password='it\'s valid'"
|
||||||
|
|
||||||
Note that the connection parameter client_encoding (which sets the
|
Note that the connection parameter client_encoding (which sets the
|
||||||
text encoding for the connection) may be set but must be "UTF8",
|
text encoding for the connection) may be set but must be "UTF8",
|
||||||
@ -129,7 +138,8 @@ This package returns the following types for values from the PostgreSQL backend:
|
|||||||
- integer types smallint, integer, and bigint are returned as int64
|
- integer types smallint, integer, and bigint are returned as int64
|
||||||
- floating-point types real and double precision are returned as float64
|
- floating-point types real and double precision are returned as float64
|
||||||
- character types char, varchar, and text are returned as string
|
- character types char, varchar, and text are returned as string
|
||||||
- temporal types date, time, timetz, timestamp, and timestamptz are returned as time.Time
|
- temporal types date, time, timetz, timestamp, and timestamptz are
|
||||||
|
returned as time.Time
|
||||||
- the boolean type is returned as bool
|
- the boolean type is returned as bool
|
||||||
- the bytea type is returned as []byte
|
- the bytea type is returned as []byte
|
||||||
|
|
||||||
@ -229,7 +239,7 @@ for more information). Note that the channel name will be truncated to 63
|
|||||||
bytes by the PostgreSQL server.
|
bytes by the PostgreSQL server.
|
||||||
|
|
||||||
You can find a complete, working example of Listener usage at
|
You can find a complete, working example of Listener usage at
|
||||||
http://godoc.org/github.com/lib/pq/listen_example.
|
http://godoc.org/github.com/lib/pq/examples/listen.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package pq
|
package pq
|
||||||
|
12
vendor/github.com/lib/pq/encode.go
generated
vendored
12
vendor/github.com/lib/pq/encode.go
generated
vendored
@ -367,8 +367,15 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
|
|||||||
timeSep := daySep + 3
|
timeSep := daySep + 3
|
||||||
day := p.mustAtoi(str, daySep+1, timeSep)
|
day := p.mustAtoi(str, daySep+1, timeSep)
|
||||||
|
|
||||||
|
minLen := monSep + len("01-01") + 1
|
||||||
|
|
||||||
|
isBC := strings.HasSuffix(str, " BC")
|
||||||
|
if isBC {
|
||||||
|
minLen += 3
|
||||||
|
}
|
||||||
|
|
||||||
var hour, minute, second int
|
var hour, minute, second int
|
||||||
if len(str) > monSep+len("01-01")+1 {
|
if len(str) > minLen {
|
||||||
p.expect(str, ' ', timeSep)
|
p.expect(str, ' ', timeSep)
|
||||||
minSep := timeSep + 3
|
minSep := timeSep + 3
|
||||||
p.expect(str, ':', minSep)
|
p.expect(str, ':', minSep)
|
||||||
@ -424,7 +431,8 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
|
|||||||
tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec)
|
tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec)
|
||||||
}
|
}
|
||||||
var isoYear int
|
var isoYear int
|
||||||
if remainderIdx+3 <= len(str) && str[remainderIdx:remainderIdx+3] == " BC" {
|
|
||||||
|
if isBC {
|
||||||
isoYear = 1 - year
|
isoYear = 1 - year
|
||||||
remainderIdx += 3
|
remainderIdx += 3
|
||||||
} else {
|
} else {
|
||||||
|
56
vendor/github.com/lib/pq/notify.go
generated
vendored
56
vendor/github.com/lib/pq/notify.go
generated
vendored
@ -60,7 +60,7 @@ type ListenerConn struct {
|
|||||||
replyChan chan message
|
replyChan chan message
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new ListenerConn. Use NewListener instead.
|
// NewListenerConn creates a new ListenerConn. Use NewListener instead.
|
||||||
func NewListenerConn(name string, notificationChan chan<- *Notification) (*ListenerConn, error) {
|
func NewListenerConn(name string, notificationChan chan<- *Notification) (*ListenerConn, error) {
|
||||||
return newDialListenerConn(defaultDialer{}, name, notificationChan)
|
return newDialListenerConn(defaultDialer{}, name, notificationChan)
|
||||||
}
|
}
|
||||||
@ -214,17 +214,17 @@ func (l *ListenerConn) listenerConnMain() {
|
|||||||
// this ListenerConn is done
|
// this ListenerConn is done
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a LISTEN query to the server. See ExecSimpleQuery.
|
// Listen sends a LISTEN query to the server. See ExecSimpleQuery.
|
||||||
func (l *ListenerConn) Listen(channel string) (bool, error) {
|
func (l *ListenerConn) Listen(channel string) (bool, error) {
|
||||||
return l.ExecSimpleQuery("LISTEN " + QuoteIdentifier(channel))
|
return l.ExecSimpleQuery("LISTEN " + QuoteIdentifier(channel))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send an UNLISTEN query to the server. See ExecSimpleQuery.
|
// Unlisten sends an UNLISTEN query to the server. See ExecSimpleQuery.
|
||||||
func (l *ListenerConn) Unlisten(channel string) (bool, error) {
|
func (l *ListenerConn) Unlisten(channel string) (bool, error) {
|
||||||
return l.ExecSimpleQuery("UNLISTEN " + QuoteIdentifier(channel))
|
return l.ExecSimpleQuery("UNLISTEN " + QuoteIdentifier(channel))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send `UNLISTEN *` to the server. See ExecSimpleQuery.
|
// UnlistenAll sends an `UNLISTEN *` query to the server. See ExecSimpleQuery.
|
||||||
func (l *ListenerConn) UnlistenAll() (bool, error) {
|
func (l *ListenerConn) UnlistenAll() (bool, error) {
|
||||||
return l.ExecSimpleQuery("UNLISTEN *")
|
return l.ExecSimpleQuery("UNLISTEN *")
|
||||||
}
|
}
|
||||||
@ -267,8 +267,8 @@ func (l *ListenerConn) sendSimpleQuery(q string) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute a "simple query" (i.e. one with no bindable parameters) on the
|
// ExecSimpleQuery executes a "simple query" (i.e. one with no bindable
|
||||||
// connection. The possible return values are:
|
// parameters) on the connection. The possible return values are:
|
||||||
// 1) "executed" is true; the query was executed to completion on the
|
// 1) "executed" is true; the query was executed to completion on the
|
||||||
// database server. If the query failed, err will be set to the error
|
// database server. If the query failed, err will be set to the error
|
||||||
// returned by the database, otherwise err will be nil.
|
// returned by the database, otherwise err will be nil.
|
||||||
@ -333,6 +333,7 @@ func (l *ListenerConn) ExecSimpleQuery(q string) (executed bool, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close closes the connection.
|
||||||
func (l *ListenerConn) Close() error {
|
func (l *ListenerConn) Close() error {
|
||||||
l.connectionLock.Lock()
|
l.connectionLock.Lock()
|
||||||
if l.err != nil {
|
if l.err != nil {
|
||||||
@ -346,7 +347,7 @@ func (l *ListenerConn) Close() error {
|
|||||||
return l.cn.c.Close()
|
return l.cn.c.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Err() returns the reason the connection was closed. It is not safe to call
|
// Err returns the reason the connection was closed. It is not safe to call
|
||||||
// this function until l.Notify has been closed.
|
// this function until l.Notify has been closed.
|
||||||
func (l *ListenerConn) Err() error {
|
func (l *ListenerConn) Err() error {
|
||||||
return l.err
|
return l.err
|
||||||
@ -354,32 +355,43 @@ func (l *ListenerConn) Err() error {
|
|||||||
|
|
||||||
var errListenerClosed = errors.New("pq: Listener has been closed")
|
var errListenerClosed = errors.New("pq: Listener has been closed")
|
||||||
|
|
||||||
|
// ErrChannelAlreadyOpen is returned from Listen when a channel is already
|
||||||
|
// open.
|
||||||
var ErrChannelAlreadyOpen = errors.New("pq: channel is already open")
|
var ErrChannelAlreadyOpen = errors.New("pq: channel is already open")
|
||||||
|
|
||||||
|
// ErrChannelNotOpen is returned from Unlisten when a channel is not open.
|
||||||
var ErrChannelNotOpen = errors.New("pq: channel is not open")
|
var ErrChannelNotOpen = errors.New("pq: channel is not open")
|
||||||
|
|
||||||
|
// ListenerEventType is an enumeration of listener event types.
|
||||||
type ListenerEventType int
|
type ListenerEventType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Emitted only when the database connection has been initially
|
// ListenerEventConnected is emitted only when the database connection
|
||||||
// initialized. err will always be nil.
|
// has been initially initialized. The err argument of the callback
|
||||||
|
// will always be nil.
|
||||||
ListenerEventConnected ListenerEventType = iota
|
ListenerEventConnected ListenerEventType = iota
|
||||||
|
|
||||||
// Emitted after a database connection has been lost, either because of an
|
// ListenerEventDisconnected is emitted after a database connection has
|
||||||
// error or because Close has been called. err will be set to the reason
|
// been lost, either because of an error or because Close has been
|
||||||
// the database connection was lost.
|
// called. The err argument will be set to the reason the database
|
||||||
|
// connection was lost.
|
||||||
ListenerEventDisconnected
|
ListenerEventDisconnected
|
||||||
|
|
||||||
// Emitted after a database connection has been re-established after
|
// ListenerEventReconnected is emitted after a database connection has
|
||||||
// connection loss. err will always be nil. After this event has been
|
// been re-established after connection loss. The err argument of the
|
||||||
// emitted, a nil pq.Notification is sent on the Listener.Notify channel.
|
// callback will always be nil. After this event has been emitted, a
|
||||||
|
// nil pq.Notification is sent on the Listener.Notify channel.
|
||||||
ListenerEventReconnected
|
ListenerEventReconnected
|
||||||
|
|
||||||
// Emitted after a connection to the database was attempted, but failed.
|
// ListenerEventConnectionAttemptFailed is emitted after a connection
|
||||||
// err will be set to an error describing why the connection attempt did
|
// to the database was attempted, but failed. The err argument will be
|
||||||
// not succeed.
|
// set to an error describing why the connection attempt did not
|
||||||
|
// succeed.
|
||||||
ListenerEventConnectionAttemptFailed
|
ListenerEventConnectionAttemptFailed
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// EventCallbackType is the event callback type. See also ListenerEventType
|
||||||
|
// constants' documentation.
|
||||||
type EventCallbackType func(event ListenerEventType, err error)
|
type EventCallbackType func(event ListenerEventType, err error)
|
||||||
|
|
||||||
// Listener provides an interface for listening to notifications from a
|
// Listener provides an interface for listening to notifications from a
|
||||||
@ -454,9 +466,9 @@ func NewDialListener(d Dialer,
|
|||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the notification channel for this listener. This is the same
|
// NotificationChannel returns the notification channel for this listener.
|
||||||
// channel as Notify, and will not be recreated during the life time of the
|
// This is the same channel as Notify, and will not be recreated during the
|
||||||
// Listener.
|
// life time of the Listener.
|
||||||
func (l *Listener) NotificationChannel() <-chan *Notification {
|
func (l *Listener) NotificationChannel() <-chan *Notification {
|
||||||
return l.Notify
|
return l.Notify
|
||||||
}
|
}
|
||||||
@ -639,7 +651,7 @@ func (l *Listener) resync(cn *ListenerConn, notificationChan <-chan *Notificatio
|
|||||||
// close and then return the error message from the connection, as
|
// close and then return the error message from the connection, as
|
||||||
// per ListenerConn's interface.
|
// per ListenerConn's interface.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
for _ = range notificationChan {
|
for range notificationChan {
|
||||||
}
|
}
|
||||||
doneChan <- cn.Err()
|
doneChan <- cn.Err()
|
||||||
return
|
return
|
||||||
|
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
@ -461,10 +461,10 @@
|
|||||||
"revisionTime": "2017-02-10T14:05:23Z"
|
"revisionTime": "2017-02-10T14:05:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "RYMOEINLFNWIJk8aKNifSlPhg9U=",
|
"checksumSHA1": "3HVfwgLpCDH8JX211UWdrSi/GU4=",
|
||||||
"path": "github.com/lib/pq",
|
"path": "github.com/lib/pq",
|
||||||
"revision": "23da1db4f16d9658a86ae9b717c245fc078f10f1",
|
"revision": "b609790bd85edf8e9ab7e0f8912750a786177bcf",
|
||||||
"revisionTime": "2017-09-18T17:50:43Z"
|
"revisionTime": "2017-10-22T19:20:43Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "jaCQF1par6Jl8g+V2Cgp0n/0wSc=",
|
"checksumSHA1": "jaCQF1par6Jl8g+V2Cgp0n/0wSc=",
|
||||||
|
Loading…
Reference in New Issue
Block a user