func New(config Config) (Service, error) {
	// Dependencies.
	if config.VaultClient == nil {
		return nil, microerror.Maskf(invalidConfigError, "Vault client must not be empty")
	}

	if config.PKIMountpoint == "" {
		return nil, microerror.Maskf(invalidConfigError, "PKIMountpoint must not be empty")
	}

	service := &service{
		vaultClient:   config.VaultClient,
		pkiMountpoint: config.PKIMountpoint,
	}

	return service, nil
}

func
New
(
config
Config
)
(
Service
,
error
)
{
// Dependencies.
if
config
.
VaultClient
==
{
return
,
microerror
.
Maskf
(
invalidConfigError
,
"
"
)
}
if
config
.
PKIMountpoint
==
"
"
{
return
,
microerror
.
Maskf
(
invalidConfigError
,
"
"
)
}
service
:=
&
service
{
vaultClient
:
config
.
VaultClient
,
pkiMountpoint
:
config
.
PKIMountpoint
,
}
return
service
,
}

// New takes a configuration and returns a configured service.

New takes a configuration and returns a configured service .


func (s *service) Create(params CreateParams) error {
	logicalStore := s.vaultClient.Logical()

	data := map[string]interface{}{
		"allowed_domains":    params.AllowedDomains,
		"allow_subdomains":   params.AllowSubdomains,
		"ttl":                params.TTL,
		"allow_bare_domains": params.AllowBareDomains,
		"organization":       params.Organizations,
	}

	_, err := logicalStore.Write(fmt.Sprintf("%s/roles/%s", s.pkiMountpoint, params.Name), data)
	if err != nil {
		return microerror.Mask(err)
	}
	return nil
}

func ( s * service ) Create ( params CreateParams ) error { logicalStore := s . vaultClient . Logical ( ) data := map [ string ] interface { } { " " : params . AllowedDomains , " " : params . AllowSubdomains , " " : params . TTL , " " : params . AllowBareDomains , " " : params . Organizations , } _ , err := logicalStore . Write ( fmt . Sprintf ( " " , s . pkiMountpoint , params . Name ) , data ) if err != nil { return microerror . Mask ( err ) } return nil }

// Create creates a role if it doesn't exist yet. Creating roles is idempotent
// in the vault api, so no need to check if it already exists.

Create creates a role if it doesn t exist yet . Creating roles is idempotent in the vault api so no need to check if it already exists .


func CreateJob() Config {
	return Config{
		LockProvider:               nil,
		RuntimeProcessor:           nil,
		ResultProcessor:            nil,
		RuntimeProcessingFrequency: 200 * time.Millisecond,
		SummaryBuffer:              1,
	}
}

func CreateJob ( ) Config { return Config { LockProvider : nil , RuntimeProcessor : nil , ResultProcessor : nil , RuntimeProcessingFrequency : 200 * time . Millisecond , SummaryBuffer : 1 , } }

// CreateJob creates a basic empty configuration with some defaults.

CreateJob creates a basic empty configuration with some defaults .


func (config *Config) Run() {
	err := config.ensureLock()
	if err != nil {
		panic(err)
	}
	err = config.runWorker()
	if err != nil {
		panic(err)
	}
}

func ( config * Config ) Run ( ) { err := config . ensureLock ( ) if err != nil { panic ( err ) } err = config . runWorker ( ) if err != nil { panic ( err ) } }


func newWatcher(dir_notify bool, initpaths ...string) (w *Watcher) {
	w = new(Watcher)
	w.auto_watch = dir_notify
	w.paths = make(map[string]*watchItem, 0)

	var paths []string
	for _, path := range initpaths {
		matches, err := filepath.Glob(path)
		if err != nil {
			continue
		}
		paths = append(paths, matches...)
	}
	if dir_notify {
		w.syncAddPaths(paths...)
	} else {
		for _, path := range paths {
			w.paths[path] = watchPath(path)
		}
	}
	return
}

func newWatcher ( dir_notify bool , initpaths ... string ) ( w * Watcher ) { w = new ( Watcher ) w . auto_watch = dir_notify w . paths = make ( map [ string ] * watchItem , 0 ) var paths [ ] string for _ , path := range initpaths { matches , err := filepath . Glob ( path ) if err != nil { continue } paths = append ( paths , matches ... ) } if dir_notify { w . syncAddPaths ( paths ... ) } else { for _ , path := range paths { w . paths [ path ] = watchPath ( path ) } } return }

// newWatcher is the internal function for properly setting up a new watcher.

newWatcher is the internal function for properly setting up a new watcher .


func (w *Watcher) Start() <-chan *Notification {
	if w.notify_chan != nil {
		return w.notify_chan
	}
	if w.auto_watch {
		w.add_chan = make(chan *watchItem, NotificationBufLen)
		go w.watchItemListener()
	}
	w.notify_chan = make(chan *Notification, NotificationBufLen)
	go w.watch(w.notify_chan)
	return w.notify_chan
}

func ( w * Watcher ) Start ( ) <- chan * Notification { if w . notify_chan != nil { return w . notify_chan } if w . auto_watch { w . add_chan = make ( chan * watchItem , NotificationBufLen ) go w . watchItemListener ( ) } w . notify_chan = make ( chan * Notification , NotificationBufLen ) go w . watch ( w . notify_chan ) return w . notify_chan }

// Start begins watching the files, sending notifications when files change.
// It returns a channel that notifications are sent on.

Start begins watching the files sending notifications when files change . It returns a channel that notifications are sent on .


func (w *Watcher) Stop() {
	if w.notify_chan != nil {
		close(w.notify_chan)
	}

	if w.add_chan != nil {
		close(w.add_chan)
	}
}

func ( w * Watcher ) Stop ( ) { if w . notify_chan != nil { close ( w . notify_chan ) } if w . add_chan != nil { close ( w . add_chan ) } }

// Stop listening for changes to the files.

Stop listening for changes to the files .


func (w *Watcher) Active() bool {
	return w.paths != nil && len(w.paths) > 0
}

func ( w * Watcher ) Active ( ) bool { return w . paths != nil && len ( w . paths ) > 0 }

// Returns true if the Watcher is actively looking for changes.

Returns true if the Watcher is actively looking for changes .


func (w *Watcher) Add(inpaths ...string) {
	var paths []string
	for _, path := range inpaths {
		matches, err := filepath.Glob(path)
		if err != nil {
			continue
		}
		paths = append(paths, matches...)
	}
	if w.auto_watch && w.notify_chan != nil {
		for _, path := range paths {
			wi := watchPath(path)
			w.addPaths(wi)
		}
	} else if w.auto_watch {
		w.syncAddPaths(paths...)
	} else {
		for _, path := range paths {
			w.paths[path] = watchPath(path)
		}
	}
}

func ( w * Watcher ) Add ( inpaths ... string ) { var paths [ ] string for _ , path := range inpaths { matches , err := filepath . Glob ( path ) if err != nil { continue } paths = append ( paths , matches ... ) } if w . auto_watch && w . notify_chan != nil { for _ , path := range paths { wi := watchPath ( path ) w . addPaths ( wi ) } } else if w . auto_watch { w . syncAddPaths ( paths ... ) } else { for _ , path := range paths { w . paths [ path ] = watchPath ( path ) } } }

// The Add method takes a variable number of string arguments and adds those
// files to the watch list, returning the number of files added.

The Add method takes a variable number of string arguments and adds those files to the watch list returning the number of files added .


func (w *Watcher) watch(sndch chan<- *Notification) {
	defer func() {
		recover()
	}()
	for {
		<-time.After(WatchDelay)
		for _, wi := range w.paths {
			if wi.Update() && w.shouldNotify(wi) {
				sndch <- wi.Notification()
			}

			if wi.LastEvent == NOEXIST && w.auto_watch {
				delete(w.paths, wi.Path)
			}

			if len(w.paths) == 0 {
				w.Stop()
			}
		}
	}
}

func ( w * Watcher ) watch ( sndch chan <- * Notification ) { defer func ( ) { recover ( ) } ( ) for { <- time . After ( WatchDelay ) for _ , wi := range w . paths { if wi . Update ( ) && w . shouldNotify ( wi ) { sndch <- wi . Notification ( ) } if wi . LastEvent == NOEXIST && w . auto_watch { delete ( w . paths , wi . Path ) } if len ( w . paths ) == 0 { w . Stop ( ) } } } }

// goroutine that cycles through the list of paths and checks for updates.

goroutine that cycles through the list of paths and checks for updates .


func (w *Watcher) Watching() (paths []string) {
	paths = make([]string, 0)
	for path, _ := range w.paths {
		paths = append(paths, path)
	}
	return
}

func ( w * Watcher ) Watching ( ) ( paths [ ] string ) { paths = make ( [ ] string , 0 ) for path , _ := range w . paths { paths = append ( paths , path ) } return }

// Watching returns a list of the files being watched.

Watching returns a list of the files being watched .


func (w *Watcher) State() (state []Notification) {
	state = make([]Notification, 0)
	if w.paths == nil {
		return
	}
	for _, wi := range w.paths {
		state = append(state, *wi.Notification())
	}
	return
}

func ( w * Watcher ) State ( ) ( state [ ] Notification ) { state = make ( [ ] Notification , 0 ) if w . paths == nil { return } for _ , wi := range w . paths { state = append ( state , * wi . Notification ( ) ) } return }

// State returns a slice of Notifications representing the files being watched
// and their last event.

State returns a slice of Notifications representing the files being watched and their last event .


func Store(r *http.Request, err error) {
	errptr, ok := r.Context().Value(errorKey).(*error)
	if !ok {
		panic("hatpear: request not configured to store errors")
	}
	// check err after checking context to fail fast if unconfigured
	if err != nil {
		*errptr = err
	}
}

// Store stores an error into the request's context. It panics if the request
// was not configured to store errors.

Store stores an error into the request s context . It panics if the request was not configured to store errors .


func Get(r *http.Request) error {
	errptr, ok := r.Context().Value(errorKey).(*error)
	if !ok {
		return nil
	}
	return *errptr
}

func Get ( r * http . Request ) error { errptr , ok := r . Context ( ) . Value ( errorKey ) . ( * error ) if ! ok { return nil } return * errptr }

// Get retrieves an error from the request's context. It returns nil if the
// request was not configured to store errors.

Get retrieves an error from the request s context . It returns nil if the request was not configured to store errors .


func Catch(h func(w http.ResponseWriter, r *http.Request, err error)) Middleware {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			var err error
			ctx := context.WithValue(r.Context(), errorKey, &err)

			next.ServeHTTP(w, r.WithContext(ctx))
			if err != nil {
				h(w, r, err)
			}
		})
	}
}

func Catch ( h func ( w http . ResponseWriter , r * http . Request , err error ) ) Middleware { return func ( next http . Handler ) http . Handler { return http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) { var err error ctx := context . WithValue ( r . Context ( ) , errorKey , & err ) next . ServeHTTP ( w , r . WithContext ( ctx ) ) if err != nil { h ( w , r , err ) } } ) } }

// Catch creates middleware that processes errors stored while serving a
// request. Errors are passed to the callback, which should write them to the
// response in an appropriate format. This is usually the outermost middleware
// in a chain.

Catch creates middleware that processes errors stored while serving a request . Errors are passed to the callback which should write them to the response in an appropriate format . This is usually the outermost middleware in a chain .


func Try(h Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		err := h.ServeHTTP(w, r)
		Store(r, err)
	})
}

func Try ( h Handler ) http . Handler { return http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) { err := h . ServeHTTP ( w , r ) Store ( r , err ) } ) }

// Try converts a handler to a standard http.Handler, storing any error in the
// request's context.

Try converts a handler to a standard http . Handler storing any error in the request s context .


func Recover() Middleware {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			defer func() {
				if v := recover(); v != nil {
					Store(r, PanicError{
						value: v,
						stack: stack(1),
					})
				}
			}()
			next.ServeHTTP(w, r)
		})
	}
}

func Recover ( ) Middleware { return func ( next http . Handler ) http . Handler { return http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) { defer func ( ) { if v := recover ( ) ; v != nil { Store ( r , PanicError { value : v , stack : stack ( 1 ) , } ) } } ( ) next . ServeHTTP ( w , r ) } ) } }

// Recover creates middleware that can recover from a panic in a handler,
// storing a PanicError for future handling.

Recover creates middleware that can recover from a panic in a handler storing a PanicError for future handling .


func main() {
	req, _ := http.NewRequest("GET", "http://localhost:7070/sync", nil)
	req.Header.Set("Accept", "text/event-stream")
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalf("request: %s", err)
	}
	r := resp.Body

	i := 0
	buff := make([]byte, 32*1024)
	for {
		n, err := r.Read(buff)
		if err != nil {
			break
		}
		i++
		log.Printf("#%d: %s", i, sizestr.ToString(int64(n)))
	}

	r.Close()
	log.Printf("closed")
}

func main ( ) { req , _ := http . NewRequest ( " " , " " , nil ) req . Header . Set ( " " , " " ) resp , err := http . DefaultClient . Do ( req ) if err != nil { log . Fatalf ( " " , err ) } r := resp . Body i := 0 buff := make ( [ ] byte , 32 * 1024 ) for { n , err := r . Read ( buff ) if err != nil { break } i ++ log . Printf ( " " , i , sizestr . ToString ( int64 ( n ) ) ) } r . Close ( ) log . Printf ( " " ) }


func SyncHandler(gostruct interface{}) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if conn, err := Sync(gostruct, w, r); err != nil {
			log.Printf("[velox] sync handler error: %s", err)
		} else {
			conn.Wait()
		}
	})
}

func SyncHandler ( gostruct interface { } ) http . Handler { return http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) { if conn , err := Sync ( gostruct , w , r ) ; err != nil { log . Printf ( " " , err ) } else { conn . Wait ( ) } } ) }

//SyncHandler is a small wrapper around Sync which simply synchronises
//all incoming connections. Use Sync if you wish to implement user authentication
//or any other request-time checks.

SyncHandler is a small wrapper around Sync which simply synchronises all incoming connections . Use Sync if you wish to implement user authentication or any other request - time checks .


func (c *conn) connect(w http.ResponseWriter, r *http.Request) error {
	//choose transport
	if r.Header.Get("Accept") == "text/event-stream" {
		c.transport = &eventSourceTransport{writeTimeout: c.state.WriteTimeout}
	} else if r.Header.Get("Upgrade") == "websocket" {
		c.transport = &websocketsTransport{writeTimeout: c.state.WriteTimeout}
	} else {
		return fmt.Errorf("Invalid sync request")
	}
	//non-blocking connect to client over set transport
	if err := c.transport.connect(w, r); err != nil {
		return err
	}
	//initial ping
	if err := c.send(&update{Ping: true}); err != nil {
		return fmt.Errorf("Failed to send initial event")
	}
	//successfully connected
	c.connected = true
	c.waiter.Add(1)
	//while connected, ping loop (every 25s, browser timesout after 30s)
	go func() {
		for {
			select {
			case <-time.After(c.state.PingInterval):
				if err := c.send(&update{Ping: true}); err != nil {
					goto disconnected
				}
			case <-c.connectedCh:
				goto disconnected
			}
		}
	disconnected:
		c.connected = false
		c.Close()
		//unblock waiters
		c.waiter.Done()
	}()
	//non-blocking wait on connection
	go func() {
		if err := c.transport.wait(); err != nil {
			//log error?
		}
		close(c.connectedCh)
	}()
	//now connected, consumer can connection.Wait()
	return nil
}

//connect using the provided transport
//and block until connection is ready

connect using the provided transport and block until connection is ready


func (c *conn) send(upd *update) error {
	c.sendingMut.Lock()
	defer c.sendingMut.Unlock()
	//send (transports responsiblity to enforce timeouts)
	return c.transport.send(upd)
}

//send to connection, ensure only 1 concurrent sender

send to connection ensure only 1 concurrent sender


func (s *State) NumConnections() int {
	s.connMut.Lock()
	n := len(s.conns)
	s.connMut.Unlock()
	return n
}

func ( s * State ) NumConnections ( ) int { s . connMut . Lock ( ) n := len ( s . conns ) s . connMut . Unlock ( ) return n }


func (s *State) Push() bool {
	//attempt to mark state as 'pushing'
	if atomic.CompareAndSwapUint32(&s.push.ing, 0, 1) {
		go s.gopush()
		return true
	}
	//if already pushing, mark queued
	atomic.StoreUint32(&s.push.queued, 1)
	return false
}

func
(
s
*
State
)
Push
(
)
bool
{
//attempt to mark state as 'pushing'
if
atomic
.
CompareAndSwapUint32
(
&
s
.
push
.
ing
,
0
,
1
)
{
go
s
.
gopush
(
)
return
true
}
//if already pushing, mark queued
atomic
.
StoreUint32
(
&
s
.
push
.
queued
,
1
)
return
false
}

//Push the changes from this object to all connected clients.
//Push is thread-safe and is throttled so it can be called
//with abandon. Returns false if a Push is already in progress.

Push the changes from this object to all connected clients . Push is thread - safe and is throttled so it can be called with abandon . Returns false if a Push is already in progress .


func (s *State) gopush() {
	s.push.mut.Lock()
	t0 := time.Now()
	//queue cleanup
	defer func() {
		//measure time passed, ensure we wait at least Throttle time
		tdelta := time.Now().Sub(t0)
		if t := s.Throttle - tdelta; t > 0 {
			time.Sleep(t)
		}
		//push complete
		s.push.mut.Unlock()
		atomic.StoreUint32(&s.push.ing, 0)
		//if queued, auto-push again
		if atomic.CompareAndSwapUint32(&s.push.queued, 1, 0) {
			s.Push()
		}
	}()
	//calculate new json state
	l, hasLock := s.gostruct.(sync.Locker)
	if hasLock {
		l.Lock()
	}
	newBytes, err := json.Marshal(s.gostruct)
	if hasLock {
		l.Unlock()
	}
	if err != nil {
		log.Printf("velox: marshal failed: %s", err)
		return
	}
	//if changed, then calculate change set
	if !bytes.Equal(s.data.bytes, newBytes) {
		//calculate change set from last version
		ops, _ := jsonpatch.CreatePatch(s.data.bytes, newBytes)
		if len(s.data.bytes) > 0 && len(ops) > 0 {
			//changes! bump version
			s.data.mut.Lock()
			s.data.delta, _ = json.Marshal(ops)
			s.data.bytes = newBytes
			s.data.version++
			s.data.mut.Unlock()
		}
	}
	//send this new change to each subscriber
	s.connMut.Lock()
	for _, c := range s.conns {
		if c.version != s.data.version {
			go c.push()
		}
	}
	s.connMut.Unlock()
	//defered cleanup()
}


func NewOutForward(configServers []*ConfigServer) (*OutForward, error) {
	loggers := make([]*fluent.Fluent, len(configServers))
	for i, server := range configServers {
		logger, err := fluent.New(fluent.Config{Server: server.Address()})
		if err != nil {
			log.Println("[warning]", err)
		} else {
			log.Println("[info] Server", server.Address(), "connected")
		}
		loggers[i] = logger
		logger.Send([]byte{})
	}
	return &OutForward{
		loggers: loggers,
		sent:    0,
	}, nil
}

func NewOutForward ( configServers [ ] * ConfigServer ) ( * OutForward , error ) { loggers := make ( [ ] * fluent . Fluent , len ( configServers ) ) for i , server := range configServers { logger , err := fluent . New ( fluent . Config { Server : server . Address ( ) } ) if err != nil { log . Println ( " " , err ) } else { log . Println ( " " , server . Address ( ) , " " ) } loggers [ i ] = logger logger . Send ( [ ] byte { } ) } return & OutForward { loggers : loggers , sent : 0 , } , nil }

// OutForward ... recieve FluentRecordSet from channel, and send it to passed loggers until success.

OutForward ... recieve FluentRecordSet from channel and send it to passed loggers until success .


func (t *InTail) Run(c *Context) {
	c.InputProcess.Add(1)
	defer c.InputProcess.Done()

	t.messageCh = c.MessageCh
	t.monitorCh = c.MonitorCh

	c.StartProcess.Done()

	if t.eventCh == nil {
		err := t.TailStdin(c)
		if err != nil {
			if _, ok := err.(Signal); ok {
				log.Println("[info]", err)
			} else {
				log.Println("[error]", err)
			}
			return
		}
	}

	log.Println("[info] Trying trail file", t.filename)
	f, err := t.newTrailFile(SEEK_TAIL, c)
	if err != nil {
		if _, ok := err.(Signal); ok {
			log.Println("[info]", err)
		} else {
			log.Println("[error]", err)
		}
		return
	}
	for {
		for {
			err := t.watchFileEvent(f, c)
			if err != nil {
				if _, ok := err.(Signal); ok {
					log.Println("[info]", err)
					return
				} else {
					log.Println("[warning]", err)
					break
				}
			}
		}
		// re open file
		var err error
		f, err = t.newTrailFile(SEEK_HEAD, c)
		if err != nil {
			if _, ok := err.(Signal); ok {
				log.Println("[info]", err)
			} else {
				log.Println("[error]", err)
			}
			return
		}
	}
}

func
(
t
*
InTail
)
Run
(
c
*
Context
)
{
c
.
InputProcess
.
Add
(
1
)
defer
c
.
InputProcess
.
Done
(
)
t
.
messageCh
=
c
.
MessageCh
t
.
monitorCh
=
c
.
MonitorCh
c
.
StartProcess
.
Done
(
)
if
t
.
eventCh
==
{
err
:=
t
.
TailStdin
(
c
)
if
err
!=
{
if
_
,
ok
:=
err
.
(
Signal
)
;
ok
{
log
.
Println
(
"
"
,
err
)
}
else
{
log
.
Println
(
"
"
,
err
)
}
return
}
}
log
.
Println
(
"
"
,
t
.
filename
)
f
,
err
:=
t
.
newTrailFile
(
SEEK_TAIL
,
c
)
if
err
!=
{
if
_
,
ok
:=
err
.
(
Signal
)
;
ok
{
log
.
Println
(
"
"
,
err
)
}
else
{
log
.
Println
(
"
"
,
err
)
}
return
}
for
{
for
{
err
:=
t
.
watchFileEvent
(
f
,
c
)
if
err
!=
{
if
_
,
ok
:=
err
.
(
Signal
)
;
ok
{
log
.
Println
(
"
"
,
err
)
return
}
else
{
log
.
Println
(
"
"
,
err
)
break
}
}
}
// re open file
var
err
error
f
,
err
=
t
.
newTrailFile
(
SEEK_HEAD
,
c
)
if
err
!=
{
if
_
,
ok
:=
err
.
(
Signal
)
;
ok
{
log
.
Println
(
"
"
,
err
)
}
else
{
log
.
Println
(
"
"
,
err
)
}
return
}
}
}

// InTail follow the tail of file and post BulkMessage to channel.

InTail follow the tail of file and post BulkMessage to channel .


func New(config Config) (f *Fluent, err error) {
	if config.Server == "" {
		config.Server = defaultServer
	}
	if config.Timeout == 0 {
		config.Timeout = defaultTimeout
	}
	if config.RetryWait == 0 {
		config.RetryWait = defaultRetryWait
	}
	if config.MaxRetry == 0 {
		config.MaxRetry = defaultMaxRetry
	}
	f = &Fluent{
		Config:          config,
		reconnecting:    false,
		cancelReconnect: make(chan bool),
	}
	err = f.connect()
	return
}

func New ( config Config ) ( f * Fluent , err error ) { if config . Server == " " { config . Server = defaultServer } if config . Timeout == 0 { config . Timeout = defaultTimeout } if config . RetryWait == 0 { config . RetryWait = defaultRetryWait } if config . MaxRetry == 0 { config . MaxRetry = defaultMaxRetry } f = & Fluent { Config : config , reconnecting : false , cancelReconnect : make ( chan bool ) , } err = f . connect ( ) return }


func (f *Fluent) Close() (err error) {
	if f.conn != nil {
		f.mu.Lock()
		defer f.mu.Unlock()
	} else {
		return
	}
	if f.conn != nil {
		f.conn.Close()
		f.conn = nil
	}
	return
}

func ( f * Fluent ) Close ( ) ( err error ) { if f . conn != nil { f . mu . Lock ( ) defer f . mu . Unlock ( ) } else { return } if f . conn != nil { f . conn . Close ( ) f . conn = nil } return }


func (f *Fluent) IsReconnecting() bool {
	f.mu.Lock()
	defer f.mu.Unlock()
	return f.reconnecting
}

func ( f * Fluent ) IsReconnecting ( ) bool { f . mu . Lock ( ) defer f . mu . Unlock ( ) return f . reconnecting }

// IsReconnecting return true if a reconnecting process in progress.

IsReconnecting return true if a reconnecting process in progress .


func (f *Fluent) connect() (err error) {
	host, port, err := net.SplitHostPort(f.Server)
	if err != nil {
		return err
	}
	addrs, err := net.LookupHost(host)
	if err != nil || len(addrs) == 0 {
		return err
	}
	// for DNS round robin
	n := Rand.Intn(len(addrs))
	addr := addrs[n]
	var format string
	if strings.Contains(addr, ":") {
		// v6
		format = "[%s]:%s"
	} else {
		// v4
		format = "%s:%s"
	}
	resolved := fmt.Sprintf(format, addr, port)
	log.Printf("[info] Connect to %s (%s)", f.Server, resolved)
	f.conn, err = net.DialTimeout("tcp", resolved, f.Config.Timeout)
	f.recordError(err)
	return
}

func
(
f
*
Fluent
)
connect
(
)
(
err
error
)
{
host
,
port
,
err
:=
net
.
SplitHostPort
(
f
.
Server
)
if
err
!=
{
return
err
}
addrs
,
err
:=
net
.
LookupHost
(
host
)
if
err
!=
||
len
(
addrs
)
==
0
{
return
err
}
// for DNS round robin
n
:=
Rand
.
Intn
(
len
(
addrs
)
)
addr
:=
addrs
[
n
]
var
format
string
if
strings
.
Contains
(
addr
,
"
"
)
{
// v6
format
=
"
"
}
else
{
// v4
format
=
"
"
}
resolved
:=
fmt
.
Sprintf
(
format
,
addr
,
port
)
log
.
Printf
(
"
"
,
f
.
Server
,
resolved
)
f
.
conn
,
err
=
net
.
DialTimeout
(
"
"
,
resolved
,
f
.
Config
.
Timeout
)
f
.
recordError
(
err
)
return
}

// connect establishes a new connection using the specified transport.

connect establishes a new connection using the specified transport .


func Notification(title, message string) GNotifier {
	config := &Config{title, message, 5000, ""}
	n := &notifier{Config: config}
	return n
}

func Notification ( title , message string ) GNotifier { config := & Config { title , message , 5000 , " " } n := & notifier { Config : config } return n }


func NullNotification(title, message string) GNotifier {
	config := &Config{title, message, 5000, ""}
	n := &nullNotifier{Config: config}
	return n
}

func NullNotification ( title , message string ) GNotifier { config := & Config { title , message , 5000 , " " } n := & nullNotifier { Config : config } return n }

// NullNotification is the builder for tests where no side effects are desired


func New(opts ...Option) *Identity {
	c := &configuration{}

	for _, opt := range opts {
		option(opt)(c)
	}

	return c.generate()
}

func New ( opts ... Option ) * Identity { c := & configuration { } for _ , opt := range opts { option ( opt ) ( c ) } return c . generate ( ) }


func (id *Identity) Issue(opts ...Option) *Identity {
	opts = append(opts, Issuer(id))
	return New(opts...)
}

func ( id * Identity ) Issue ( opts ... Option ) * Identity { opts = append ( opts , Issuer ( id ) ) return New ( opts ... ) }

// Issue issues a new Identity with this one as its parent.

Issue issues a new Identity with this one as its parent .


func Subject(value pkix.Name) Option {
	return func(c *configuration) {
		c.subject = &value
	}
}

func Subject ( value pkix . Name ) Option { return func ( c * configuration ) { c . subject = & value } }

// Subject is an Option that sets a identity's subject field.

Subject is an Option that sets a identity s subject field .


func PrivateKey(value crypto.Signer) Option {
	return func(c *configuration) {
		c.priv = &value
	}
}

func PrivateKey ( value crypto . Signer ) Option { return func ( c * configuration ) { c . priv = & value } }

// PrivateKey is an Option for setting the identity's private key.

PrivateKey is an Option for setting the identity s private key .


func NotBefore(value time.Time) Option {
	return func(c *configuration) {
		c.notBefore = &value
	}
}

func NotBefore ( value time . Time ) Option { return func ( c * configuration ) { c . notBefore = & value } }

// NotBefore is an Option for setting the identity's certificate's NotBefore.

NotBefore is an Option for setting the identity s certificate s NotBefore .


func NotAfter(value time.Time) Option {
	return func(c *configuration) {
		c.notAfter = &value
	}
}

func NotAfter ( value time . Time ) Option { return func ( c * configuration ) { c . notAfter = & value } }

// NotAfter is an Option for setting the identity's certificate's NotAfter.

NotAfter is an Option for setting the identity s certificate s NotAfter .


func IssuingCertificateURL(value ...string) Option {
	return func(c *configuration) {
		c.issuingCertificateURL = append(c.issuingCertificateURL, value...)
	}
}

func IssuingCertificateURL ( value ... string ) Option { return func ( c * configuration ) { c . issuingCertificateURL = append ( c . issuingCertificateURL , value ... ) } }

// IssuingCertificateURL is an Option for setting the identity's certificate's
// IssuingCertificateURL.

IssuingCertificateURL is an Option for setting the identity s certificate s IssuingCertificateURL .


func OCSPServer(value ...string) Option {
	return func(c *configuration) {
		c.ocspServer = append(c.ocspServer, value...)
	}
}

func OCSPServer ( value ... string ) Option { return func ( c * configuration ) { c . ocspServer = append ( c . ocspServer , value ... ) } }

// OCSPServer is an Option for setting the identity's certificate's OCSPServer.

OCSPServer is an Option for setting the identity s certificate s OCSPServer .


func New(apiKey string) (*TelegramBotAPI, error) {
	toReturn := TelegramBotAPI{
		Updates:  make(chan BotUpdate),
		baseURIs: createEndpoints(fmt.Sprintf(apiBaseURI, apiKey)),
		closed:   make(chan struct{}),
		c:        newClient(fmt.Sprintf(apiBaseURI, apiKey)),
		updateC:  newClient(fmt.Sprintf(apiBaseURI, apiKey)),
	}
	user, err := toReturn.GetMe()
	if err != nil {
		return nil, err
	}
	toReturn.ID = user.User.ID
	toReturn.Name = user.User.FirstName
	toReturn.Username = *user.User.Username

	err = toReturn.removeWebhook()
	if err != nil {
		return nil, err
	}

	toReturn.wg.Add(1)
	go toReturn.updateLoop()

	return &toReturn, nil
}

func New ( apiKey string ) ( * TelegramBotAPI , error ) { toReturn := TelegramBotAPI { Updates : make ( chan BotUpdate ) , baseURIs : createEndpoints ( fmt . Sprintf ( apiBaseURI , apiKey ) ) , closed : make ( chan struct { } ) , c : newClient ( fmt . Sprintf ( apiBaseURI , apiKey ) ) , updateC : newClient ( fmt . Sprintf ( apiBaseURI , apiKey ) ) , } user , err := toReturn . GetMe ( ) if err != nil { return nil , err } toReturn . ID = user . User . ID toReturn . Name = user . User . FirstName toReturn . Username = * user . User . Username err = toReturn . removeWebhook ( ) if err != nil { return nil , err } toReturn . wg . Add ( 1 ) go toReturn . updateLoop ( ) return & toReturn , nil }

// New creates a new API Client for a Telegram bot using the apiKey
// provided.
// It will call the GetMe method to retrieve the bots id, name and
// username.
//
// This bot uses long polling to retrieve its updates. If a webhook was set
// for the given apiKey, this will remove it.

New creates a new API Client for a Telegram bot using the apiKey provided . It will call the GetMe method to retrieve the bots id name and username . This bot uses long polling to retrieve its updates . If a webhook was set for the given apiKey this will remove it .


func NewWithWebhook(apiKey, webhookURL, certificate string) (*TelegramBotAPI, http.HandlerFunc, error) {
	toReturn := TelegramBotAPI{
		Updates:  make(chan BotUpdate),
		baseURIs: createEndpoints(fmt.Sprintf(apiBaseURI, apiKey)),
		closed:   make(chan struct{}),
		c:        newClient(fmt.Sprintf(apiBaseURI, apiKey)),
		updateC:  newClient(fmt.Sprintf(apiBaseURI, apiKey)),
	}
	user, err := toReturn.GetMe()
	if err != nil {
		return nil, nil, err
	}
	toReturn.ID = user.User.ID
	toReturn.Name = user.User.FirstName
	toReturn.Username = *user.User.Username

	file, err := os.Open(certificate)
	if err != nil {
		return nil, nil, err
	}

	err = toReturn.setWebhook(webhookURL, certificate, file)
	if err != nil {
		return nil, nil, err
	}

	updateFunc := func(w http.ResponseWriter, r *http.Request) {
		bytes, err := ioutil.ReadAll(r.Body)
		if err != nil {
			toReturn.Updates <- BotUpdate{err: err}
			return
		}

		update := &Update{}
		err = json.Unmarshal(bytes, update)
		if err != nil {
			toReturn.Updates <- BotUpdate{err: err}
			return
		}

		toReturn.Updates <- BotUpdate{update: *update}
	}

	return &toReturn, updateFunc, nil
}

func NewWithWebhook ( apiKey , webhookURL , certificate string ) ( * TelegramBotAPI , http . HandlerFunc , error ) { toReturn := TelegramBotAPI { Updates : make ( chan BotUpdate ) , baseURIs : createEndpoints ( fmt . Sprintf ( apiBaseURI , apiKey ) ) , closed : make ( chan struct { } ) , c : newClient ( fmt . Sprintf ( apiBaseURI , apiKey ) ) , updateC : newClient ( fmt . Sprintf ( apiBaseURI , apiKey ) ) , } user , err := toReturn . GetMe ( ) if err != nil { return nil , nil , err } toReturn . ID = user . User . ID toReturn . Name = user . User . FirstName toReturn . Username = * user . User . Username file , err := os . Open ( certificate ) if err != nil { return nil , nil , err } err = toReturn . setWebhook ( webhookURL , certificate , file ) if err != nil { return nil , nil , err } updateFunc := func ( w http . ResponseWriter , r * http . Request ) { bytes , err := ioutil . ReadAll ( r . Body ) if err != nil { toReturn . Updates <- BotUpdate { err : err } return } update := & Update { } err = json . Unmarshal ( bytes , update ) if err != nil { toReturn . Updates <- BotUpdate { err : err } return } toReturn . Updates <- BotUpdate { update : * update } } return & toReturn , updateFunc , nil }

// NewWithWebhook creates a new API client for a Telegram bot using the apiKey
// provided. It will call the GetMe method to retrieve the bots id, name and
// username.
// In addition to the API client, a http.HandlerFunc will be returned. This
// handler func reacts to webhook requests and will put updates into the
// Updates channel.

NewWithWebhook creates a new API client for a Telegram bot using the apiKey provided . It will call the GetMe method to retrieve the bots id name and username . In addition to the API client a http . HandlerFunc will be returned . This handler func reacts to webhook requests and will put updates into the Updates channel .


func (api *TelegramBotAPI) Close() {
	select {
	case <-api.closed:
		return
	default:
	}
	close(api.closed)
	api.wg.Wait()
}

func ( api * TelegramBotAPI ) Close ( ) { select { case <- api . closed : return default : } close ( api . closed ) api . wg . Wait ( ) }

// Close shuts down this client.
// Until Close returns, new updates and errors will be put into the
// respective channels.
// Note that, if no updates are received, this function may block for up to
// one minute, which is the time interval
// for long polling.

Close shuts down this client . Until Close returns new updates and errors will be put into the respective channels . Note that if no updates are received this function may block for up to one minute which is the time interval for long polling .


func (api *TelegramBotAPI) GetMe() (*UserResponse, error) {
	resp := &UserResponse{}
	_, err := api.c.get(getMe, resp)

	if err != nil {
		return nil, err
	}
	err = check(&resp.baseResponse)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func ( api * TelegramBotAPI ) GetMe ( ) ( * UserResponse , error ) { resp := & UserResponse { } _ , err := api . c . get ( getMe , resp ) if err != nil { return nil , err } err = check ( & resp . baseResponse ) if err != nil { return nil , err } return resp , nil }

// GetMe returns basic information about the bot in form of a UserResponse.

GetMe returns basic information about the bot in form of a UserResponse .


func RunBot(apiKey string, bot BotFunc, name, description string) {
	closing := make(chan struct{})

	fmt.Printf("%s: %s\n", name, description)
	fmt.Println("Starting...")

	api, err := tbotapi.New(apiKey)
	if err != nil {
		log.Fatal(err)
	}

	// Just to show its working.
	fmt.Printf("User ID: %d\n", api.ID)
	fmt.Printf("Bot Name: %s\n", api.Name)
	fmt.Printf("Bot Username: %s\n", api.Username)

	closed := make(chan struct{})
	wg := &sync.WaitGroup{}

	wg.Add(1)
	go func() {
		defer wg.Done()
		for {
			select {
			case <-closed:
				return
			case update := <-api.Updates:
				if update.Error() != nil {
					// TODO handle this properly
					fmt.Printf("Update error: %s\n", update.Error())
					continue
				}

				bot(update.Update(), api)
			}
		}
	}()

	// Ensure a clean shutdown.
	shutdown := make(chan os.Signal)
	signal.Notify(shutdown, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		<-shutdown
		close(closing)
	}()

	fmt.Println("Bot started. Press CTRL-C to close...")

	// Wait for the signal.
	<-closing
	fmt.Println("Closing...")

	// Always close the API first, let it clean up the update loop.
	// This might take a while.
	api.Close()
	close(closed)
	wg.Wait()
}

// RunBot runs a bot.
// It will block until either something very bad happens or closing is closed.

RunBot runs a bot . It will block until either something very bad happens or closing is closed .


func RunBotOnWebhook(apiKey string, bot BotFunc, name, description, webhookHost string, webhookPort uint16, pubkey, privkey string) {
	closing := make(chan struct{})

	fmt.Printf("%s: %s\n", name, description)
	fmt.Println("Starting...")
	u := url.URL{
		Host:   webhookHost + ":" + fmt.Sprint(webhookPort),
		Scheme: "https",
		Path:   apiKey,
	}

	api, handler, err := tbotapi.NewWithWebhook(apiKey, u.String(), pubkey)
	if err != nil {
		log.Fatal(err)
	}

	// Just to show its working.
	fmt.Printf("User ID: %d\n", api.ID)
	fmt.Printf("Bot Name: %s\n", api.Name)
	fmt.Printf("Bot Username: %s\n", api.Username)

	closed := make(chan struct{})
	wg := &sync.WaitGroup{}

	wg.Add(1)
	go func() {
		defer wg.Done()
		for {
			select {
			case <-closed:
				return
			case update := <-api.Updates:
				if update.Error() != nil {
					// TODO handle this properly
					fmt.Printf("Update error: %s\n", update.Error())
					continue
				}

				bot(update.Update(), api)
			}
		}
	}()

	http.HandleFunc("/"+apiKey, handler)

	fmt.Println("Starting webhook...")
	go func() {
		log.Fatal(http.ListenAndServeTLS("0.0.0.0:"+fmt.Sprint(webhookPort), pubkey, privkey, nil))
	}()

	// Ensure a clean shutdown.
	shutdown := make(chan os.Signal)
	signal.Notify(shutdown, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		<-shutdown
		close(closing)
	}()

	fmt.Println("Bot started. Press CTRL-C to close...")

	// Wait for the signal.
	<-closing
	fmt.Println("Closing...")

	// Always close the API first.
	api.Close()
	close(closed)
	wg.Wait()
}

func
RunBotOnWebhook
(
apiKey
string
,
bot
BotFunc
,
name
,
description
,
webhookHost
string
,
webhookPort
uint16
,
pubkey
,
privkey
string
)
{
closing
:=
make
(
chan
struct
{
}
)
fmt
.
Printf
(
"
\n
"
,
name
,
description
)
fmt
.
Println
(
"
"
)
u
:=
url
.
URL
{
Host
:
webhookHost
+
"
"
+
fmt
.
Sprint
(
webhookPort
)
,
Scheme
:
"
"
,
Path
:
apiKey
,
}
api
,
handler
,
err
:=
tbotapi
.
NewWithWebhook
(
apiKey
,
u
.
String
(
)
,
pubkey
)
if
err
!=
{
log
.
Fatal
(
err
)
}
// Just to show its working.
fmt
.
Printf
(
"
\n
"
,
api
.
ID
)
fmt
.
Printf
(
"
\n
"
,
api
.
Name
)
fmt
.
Printf
(
"
\n
"
,
api
.
Username
)
closed
:=
make
(
chan
struct
{
}
)
wg
:=
&
sync
.
WaitGroup
{
}
wg
.
Add
(
1
)
go
func
(
)
{
defer
wg
.
Done
(
)
for
{
select
{
case
<-
closed
:
return
case
update
:=
<-
api
.
Updates
:
if
update
.
Error
(
)
!=
{
// TODO handle this properly
fmt
.
Printf
(
"
\n
"
,
update
.
Error
(
)
)
continue
}
bot
(
update
.
Update
(
)
,
api
)
}
}
}
(
)
http
.
HandleFunc
(
"
"
+
apiKey
,
handler
)
fmt
.
Println
(
"
"
)
go
func
(
)
{
log
.
Fatal
(
http
.
ListenAndServeTLS
(
"
"
+
fmt
.
Sprint
(
webhookPort
)
,
pubkey
,
privkey
,
)
)
}
(
)
// Ensure a clean shutdown.
shutdown
:=
make
(
chan
os
.
Signal
)
signal
.
Notify
(
shutdown
,
syscall
.
SIGINT
,
syscall
.
SIGTERM
)
go
func
(
)
{
<-
shutdown
close
(
closing
)
}
(
)
fmt
.
Println
(
"
"
)
// Wait for the signal.
<-
closing
fmt
.
Println
(
"
"
)
// Always close the API first.
api
.
Close
(
)
close
(
closed
)
wg
.
Wait
(
)
}

// RunBotOnWebhook runs the given BotFunc with a webhook.

RunBotOnWebhook runs the given BotFunc with a webhook .


func (api *TelegramBotAPI) NewOutgoingMessage(recipient Recipient, text string) *OutgoingMessage {
	return &OutgoingMessage{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		Text:      text,
		ParseMode: ModeDefault,
	}
}

func ( api * TelegramBotAPI ) NewOutgoingMessage ( recipient Recipient , text string ) * OutgoingMessage { return & OutgoingMessage { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , Text : text , ParseMode : ModeDefault , } }

// NewOutgoingMessage creates a new outgoing message.

NewOutgoingMessage creates a new outgoing message .


func (api *TelegramBotAPI) NewOutgoingLocation(recipient Recipient, latitude, longitude float32) *OutgoingLocation {
	return &OutgoingLocation{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		Latitude:  latitude,
		Longitude: longitude,
	}
}

func ( api * TelegramBotAPI ) NewOutgoingLocation ( recipient Recipient , latitude , longitude float32 ) * OutgoingLocation { return & OutgoingLocation { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , Latitude : latitude , Longitude : longitude , } }

// NewOutgoingLocation creates a new outgoing location.

NewOutgoingLocation creates a new outgoing location .


func (api *TelegramBotAPI) NewOutgoingVenue(recipient Recipient, latitude, longitude float32, title, address string) *OutgoingVenue {
	return &OutgoingVenue{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		Latitude:  latitude,
		Longitude: longitude,
		Title:     title,
		Address:   address,
	}
}

func ( api * TelegramBotAPI ) NewOutgoingVenue ( recipient Recipient , latitude , longitude float32 , title , address string ) * OutgoingVenue { return & OutgoingVenue { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , Latitude : latitude , Longitude : longitude , Title : title , Address : address , } }

// NewOutgoingVenue creates a new outgoing location.

NewOutgoingVenue creates a new outgoing location .


func (api *TelegramBotAPI) NewOutgoingVideo(recipient Recipient, fileName string, reader io.Reader) *OutgoingVideo {
	return &OutgoingVideo{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileName: fileName,
			r:        reader,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingVideo ( recipient Recipient , fileName string , reader io . Reader ) * OutgoingVideo { return & OutgoingVideo { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileName : fileName , r : reader , } , } }

// NewOutgoingVideo creates a new outgoing video file.

NewOutgoingVideo creates a new outgoing video file .


func (api *TelegramBotAPI) NewOutgoingVideoResend(recipient Recipient, fileID string) *OutgoingVideo {
	return &OutgoingVideo{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileID: fileID,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingVideoResend ( recipient Recipient , fileID string ) * OutgoingVideo { return & OutgoingVideo { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileID : fileID , } , } }

// NewOutgoingVideoResend creates a new outgoing video file for re-sending.

NewOutgoingVideoResend creates a new outgoing video file for re - sending .


func (api *TelegramBotAPI) NewOutgoingPhoto(recipient Recipient, fileName string, reader io.Reader) *OutgoingPhoto {
	return &OutgoingPhoto{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileName: fileName,
			r:        reader,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingPhoto ( recipient Recipient , fileName string , reader io . Reader ) * OutgoingPhoto { return & OutgoingPhoto { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileName : fileName , r : reader , } , } }

// NewOutgoingPhoto creates a new outgoing photo.

NewOutgoingPhoto creates a new outgoing photo .


func (api *TelegramBotAPI) NewOutgoingPhotoResend(recipient Recipient, fileID string) *OutgoingPhoto {
	return &OutgoingPhoto{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileID: fileID,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingPhotoResend ( recipient Recipient , fileID string ) * OutgoingPhoto { return & OutgoingPhoto { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileID : fileID , } , } }

// NewOutgoingPhotoResend creates a new outgoing photo for re-sending.

NewOutgoingPhotoResend creates a new outgoing photo for re - sending .


func (api *TelegramBotAPI) NewOutgoingSticker(recipient Recipient, fileName string, reader io.Reader) *OutgoingSticker {
	return &OutgoingSticker{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileName: fileName,
			r:        reader,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingSticker ( recipient Recipient , fileName string , reader io . Reader ) * OutgoingSticker { return & OutgoingSticker { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileName : fileName , r : reader , } , } }

// NewOutgoingSticker creates a new outgoing sticker message.

NewOutgoingSticker creates a new outgoing sticker message .


func (api *TelegramBotAPI) NewOutgoingStickerResend(recipient Recipient, fileID string) *OutgoingSticker {
	return &OutgoingSticker{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileID: fileID,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingStickerResend ( recipient Recipient , fileID string ) * OutgoingSticker { return & OutgoingSticker { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileID : fileID , } , } }

// NewOutgoingStickerResend creates a new outgoing sticker message for
// re-sending.

NewOutgoingStickerResend creates a new outgoing sticker message for re - sending .


func (api *TelegramBotAPI) NewOutgoingVoice(recipient Recipient, fileName string, reader io.Reader) *OutgoingVoice {
	return &OutgoingVoice{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileName: fileName,
			r:        reader,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingVoice ( recipient Recipient , fileName string , reader io . Reader ) * OutgoingVoice { return & OutgoingVoice { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileName : fileName , r : reader , } , } }

// NewOutgoingVoice creates a new outgoing voice note.

NewOutgoingVoice creates a new outgoing voice note .


func (api *TelegramBotAPI) NewOutgoingVoiceResend(recipient Recipient, fileID string) *OutgoingVoice {
	return &OutgoingVoice{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileID: fileID,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingVoiceResend ( recipient Recipient , fileID string ) * OutgoingVoice { return & OutgoingVoice { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileID : fileID , } , } }

// NewOutgoingVoiceResend creates a new outgoing voice note for re-sending.

NewOutgoingVoiceResend creates a new outgoing voice note for re - sending .


func (api *TelegramBotAPI) NewOutgoingAudio(recipient Recipient, fileName string, reader io.Reader) *OutgoingAudio {
	return &OutgoingAudio{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileName: fileName,
			r:        reader,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingAudio ( recipient Recipient , fileName string , reader io . Reader ) * OutgoingAudio { return & OutgoingAudio { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileName : fileName , r : reader , } , } }

// NewOutgoingAudio creates a new outgoing audio file.

NewOutgoingAudio creates a new outgoing audio file .


func (api *TelegramBotAPI) NewOutgoingAudioResend(recipient Recipient, fileID string) *OutgoingAudio {
	return &OutgoingAudio{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileID: fileID,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingAudioResend ( recipient Recipient , fileID string ) * OutgoingAudio { return & OutgoingAudio { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileID : fileID , } , } }

// NewOutgoingAudioResend creates a new outgoing audio file for re-sending.

NewOutgoingAudioResend creates a new outgoing audio file for re - sending .


func (api *TelegramBotAPI) NewOutgoingDocument(recipient Recipient, fileName string, reader io.Reader) *OutgoingDocument {
	return &OutgoingDocument{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileName: fileName,
			r:        reader,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingDocument ( recipient Recipient , fileName string , reader io . Reader ) * OutgoingDocument { return & OutgoingDocument { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileName : fileName , r : reader , } , } }

// NewOutgoingDocument creates a new outgoing file.

NewOutgoingDocument creates a new outgoing file .


func (api *TelegramBotAPI) NewOutgoingDocumentResend(recipient Recipient, fileID string) *OutgoingDocument {
	return &OutgoingDocument{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		outgoingFileBase: outgoingFileBase{
			fileID: fileID,
		},
	}
}

func ( api * TelegramBotAPI ) NewOutgoingDocumentResend ( recipient Recipient , fileID string ) * OutgoingDocument { return & OutgoingDocument { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , outgoingFileBase : outgoingFileBase { fileID : fileID , } , } }

// NewOutgoingDocumentResend creates a new outgoing file for re-sending.

NewOutgoingDocumentResend creates a new outgoing file for re - sending .


func (api *TelegramBotAPI) NewOutgoingForward(recipient Recipient, origin Chat, messageID int) *OutgoingForward {
	return &OutgoingForward{
		outgoingMessageBase: outgoingMessageBase{
			outgoingBase: outgoingBase{
				api:       api,
				Recipient: recipient,
			},
		},
		FromChatID: NewRecipientFromChat(origin),
		MessageID:  messageID,
	}
}

func ( api * TelegramBotAPI ) NewOutgoingForward ( recipient Recipient , origin Chat , messageID int ) * OutgoingForward { return & OutgoingForward { outgoingMessageBase : outgoingMessageBase { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , } , FromChatID : NewRecipientFromChat ( origin ) , MessageID : messageID , } }

// NewOutgoingForward creates a new outgoing, forwarded message.

NewOutgoingForward creates a new outgoing forwarded message .


func (api *TelegramBotAPI) NewOutgoingChatAction(recipient Recipient, action ChatAction) *OutgoingChatAction {
	return &OutgoingChatAction{
		outgoingBase: outgoingBase{
			api:       api,
			Recipient: recipient,
		},
		Action: action,
	}
}

func ( api * TelegramBotAPI ) NewOutgoingChatAction ( recipient Recipient , action ChatAction ) * OutgoingChatAction { return & OutgoingChatAction { outgoingBase : outgoingBase { api : api , Recipient : recipient , } , Action : action , } }

// NewOutgoingChatAction creates a new outgoing chat action.

NewOutgoingChatAction creates a new outgoing chat action .


func (api *TelegramBotAPI) NewOutgoingUserProfilePhotosRequest(userID int) *OutgoingUserProfilePhotosRequest {
	return &OutgoingUserProfilePhotosRequest{
		api:    api,
		UserID: userID,
	}
}

func ( api * TelegramBotAPI ) NewOutgoingUserProfilePhotosRequest ( userID int ) * OutgoingUserProfilePhotosRequest { return & OutgoingUserProfilePhotosRequest { api : api , UserID : userID , } }

// NewOutgoingUserProfilePhotosRequest creates a new request for a users
// profile photos.

NewOutgoingUserProfilePhotosRequest creates a new request for a users profile photos .


func (api *TelegramBotAPI) NewOutgoingKickChatMember(chat Recipient, userID int) *OutgoingKickChatMember {
	return &OutgoingKickChatMember{
		api:       api,
		Recipient: chat,
		UserID:    userID,
	}
}

func ( api * TelegramBotAPI ) NewOutgoingKickChatMember ( chat Recipient , userID int ) * OutgoingKickChatMember { return & OutgoingKickChatMember { api : api , Recipient : chat , UserID : userID , } }

// NewOutgoingKickChatMember creates a request to kick a member from a
// group chat or channel.

NewOutgoingKickChatMember creates a request to kick a member from a group chat or channel .


func (api *TelegramBotAPI) NewOutgoingUnbanChatMember(chat Recipient, userID int) *OutgoingUnbanChatMember {
	return &OutgoingUnbanChatMember{
		api:       api,
		Recipient: chat,
		UserID:    userID,
	}
}

func ( api * TelegramBotAPI ) NewOutgoingUnbanChatMember ( chat Recipient , userID int ) * OutgoingUnbanChatMember { return & OutgoingUnbanChatMember { api : api , Recipient : chat , UserID : userID , } }

// NewOutgoingUnbanChatMember creates a request to unban a member of a
// group chat or channel.

NewOutgoingUnbanChatMember creates a request to unban a member of a group chat or channel .


func (api *TelegramBotAPI) NewOutgoingCallbackQueryResponse(queryID string) *OutgoingCallbackQueryResponse {
	return &OutgoingCallbackQueryResponse{
		api:             api,
		CallbackQueryID: queryID,
	}
}

func ( api * TelegramBotAPI ) NewOutgoingCallbackQueryResponse ( queryID string ) * OutgoingCallbackQueryResponse { return & OutgoingCallbackQueryResponse { api : api , CallbackQueryID : queryID , } }

// NewOutgoingCallbackQueryResponse creates a response to a callback query.

NewOutgoingCallbackQueryResponse creates a response to a callback query .


func (api *TelegramBotAPI) NewInlineQueryAnswer(queryID string, results []InlineQueryResult) *InlineQueryAnswer {
	return &InlineQueryAnswer{
		api:     api,
		QueryID: queryID,
		Results: results,
	}
}

func ( api * TelegramBotAPI ) NewInlineQueryAnswer ( queryID string , results [ ] InlineQueryResult ) * InlineQueryAnswer { return & InlineQueryAnswer { api : api , QueryID : queryID , Results : results , } }

// NewInlineQueryAnswer creates a new inline query answer.

NewInlineQueryAnswer creates a new inline query answer .


func (m *Message) Type() MessageType {
	if m.Text != nil {
		return TextMessage
	} else if m.Audio != nil {
		return AudioMessage
	} else if m.Document != nil {
		return DocumentMessage
	} else if m.Photo != nil {
		return PhotoMessage
	} else if m.Sticker != nil {
		return StickerMessage
	} else if m.Video != nil {
		return VideoMessage
	} else if m.Voice != nil {
		return VoiceMessage
	} else if m.Contact != nil {
		return ContactMessage
	} else if m.Location != nil {
		return LocationMessage
	} else if m.NewChatMember != nil {
		return NewChatMember
	} else if m.LeftChatMember != nil {
		return LeftChatMember
	} else if m.NewChatTitle != nil {
		return NewChatTitle
	} else if m.NewChatPhoto != nil {
		return NewChatPhoto
	} else if m.DeleteChatPhoto {
		return DeletedChatPhoto
	} else if m.GroupChatCreated {
		return GroupChatCreated
	} else if m.SupergroupChatCreated {
		return SupergroupChatCreated
	} else if m.ChannelChatCreated {
		return ChannelChatCreated
	} else if m.MigrateToChatID != nil {
		return MigrationToSupergroup
	} else if m.MigrateFromChatID != nil {
		return MigrationFromGroup
	} else if m.Venue != nil {
		return VenueMessage
	} else if m.PinnedMessage != nil {
		return PinnedMessage
	}

	return UnknownMessage
}

func ( m * Message ) Type ( ) MessageType { if m . Text != nil { return TextMessage } else if m . Audio != nil { return AudioMessage } else if m . Document != nil { return DocumentMessage } else if m . Photo != nil { return PhotoMessage } else if m . Sticker != nil { return StickerMessage } else if m . Video != nil { return VideoMessage } else if m . Voice != nil { return VoiceMessage } else if m . Contact != nil { return ContactMessage } else if m . Location != nil { return LocationMessage } else if m . NewChatMember != nil { return NewChatMember } else if m . LeftChatMember != nil { return LeftChatMember } else if m . NewChatTitle != nil { return NewChatTitle } else if m . NewChatPhoto != nil { return NewChatPhoto } else if m . DeleteChatPhoto { return DeletedChatPhoto } else if m . GroupChatCreated { return GroupChatCreated } else if m . SupergroupChatCreated { return SupergroupChatCreated } else if m . ChannelChatCreated { return ChannelChatCreated } else if m . MigrateToChatID != nil { return MigrationToSupergroup } else if m . MigrateFromChatID != nil { return MigrationFromGroup } else if m . Venue != nil { return VenueMessage } else if m . PinnedMessage != nil { return PinnedMessage } return UnknownMessage }

// Type determines the type of the message.
// Note that, for all these types, messages can still be replies or
// forwarded.

Type determines the type of the message . Note that for all these types messages can still be replies or forwarded .


func (u *Update) Type() UpdateType {
	if u.Message != nil {
		return MessageUpdate
	} else if u.InlineQuery != nil {
		return InlineQueryUpdate
	} else if u.ChosenInlineResult != nil {
		return ChosenInlineResultUpdate
	}
	return UnknownUpdate
}

func ( u * Update ) Type ( ) UpdateType { if u . Message != nil { return MessageUpdate } else if u . InlineQuery != nil { return InlineQueryUpdate } else if u . ChosenInlineResult != nil { return ChosenInlineResultUpdate } return UnknownUpdate }


func (r Recipient) MarshalJSON() ([]byte, error) {
	toReturn := ""

	if r.isChannel() {
		toReturn = fmt.Sprintf("\"%s\"", *r.ChannelID)
	} else {
		toReturn = fmt.Sprintf("%d", *r.ChatID)
	}

	return []byte(toReturn), nil
}

func ( r Recipient ) MarshalJSON ( ) ( [ ] byte , error ) { toReturn := " " if r . isChannel ( ) { toReturn = fmt . Sprintf ( " \" \" " , * r . ChannelID ) } else { toReturn = fmt . Sprintf ( " " , * r . ChatID ) } return [ ] byte ( toReturn ) , nil }

// MarshalJSON marshals the recipient to JSON.

MarshalJSON marshals the recipient to JSON .


func (ow *outgoingSetWebhook) querystring() querystring {
	toReturn := make(map[string]string)

	if ow.URL != "" {
		toReturn["url"] = ow.URL
	}

	return querystring(toReturn)
}

func ( ow * outgoingSetWebhook ) querystring ( ) querystring { toReturn := make ( map [ string ] string ) if ow . URL != " " { toReturn [ " " ] = ow . URL } return querystring ( toReturn ) }

// querystring implements querystringer to represent the outgoing certificate
// file.

querystring implements querystringer to represent the outgoing certificate file .


func (op *outgoingBase) getBaseQueryString() querystring {
	toReturn := map[string]string{}
	if op.Recipient.isChannel() {
		//Channel
		toReturn["chat_id"] = fmt.Sprint(*op.Recipient.ChannelID)
	} else {
		toReturn["chat_id"] = fmt.Sprint(*op.Recipient.ChatID)
	}

	return querystring(toReturn)
}

func ( op * outgoingBase ) getBaseQueryString ( ) querystring { toReturn := map [ string ] string { } if op . Recipient . isChannel ( ) { //Channel toReturn [ " " ] = fmt . Sprint ( * op . Recipient . ChannelID ) } else { toReturn [ " " ] = fmt . Sprint ( * op . Recipient . ChatID ) } return querystring ( toReturn ) }

// getBaseQueryString gets a Querystring representing this message.

getBaseQueryString gets a Querystring representing this message .


func (op *outgoingMessageBase) getBaseQueryString() querystring {
	toReturn := map[string]string{}
	if op.Recipient.isChannel() {
		//Channel.
		toReturn["chat_id"] = fmt.Sprint(*op.Recipient.ChannelID)
	} else {
		toReturn["chat_id"] = fmt.Sprint(*op.Recipient.ChatID)
	}

	if op.replyToMessageIDSet {
		toReturn["reply_to_message_id"] = fmt.Sprint(op.ReplyToMessageID)
	}

	if op.replyMarkupSet {
		b, err := json.Marshal(op.ReplyMarkup)
		if err != nil {
			panic(err)
		}
		toReturn["reply_markup"] = string(b)
	}

	if op.DisableNotification {
		toReturn["disable_notification"] = fmt.Sprint(op.DisableNotification)
	}

	return querystring(toReturn)
}

func ( op * outgoingMessageBase ) getBaseQueryString ( ) querystring { toReturn := map [ string ] string { } if op . Recipient . isChannel ( ) { //Channel. toReturn [ " " ] = fmt . Sprint ( * op . Recipient . ChannelID ) } else { toReturn [ " " ] = fmt . Sprint ( * op . Recipient . ChatID ) } if op . replyToMessageIDSet { toReturn [ " " ] = fmt . Sprint ( op . ReplyToMessageID ) } if op . replyMarkupSet { b , err := json . Marshal ( op . ReplyMarkup ) if err != nil { panic ( err ) } toReturn [ " " ] = string ( b ) } if op . DisableNotification { toReturn [ " " ] = fmt . Sprint ( op . DisableNotification ) } return querystring ( toReturn ) }

// getMessageBaseQueryString gets a Querystring representing this message.

getMessageBaseQueryString gets a Querystring representing this message .


func (oa *OutgoingAudio) querystring() querystring {
	toReturn := map[string]string(oa.getBaseQueryString())

	if oa.Duration != 0 {
		toReturn["duration"] = fmt.Sprint(oa.Duration)
	}

	if oa.Performer != "" {
		toReturn["performer"] = oa.Performer
	}

	if oa.Title != "" {
		toReturn["title"] = oa.Title
	}

	return querystring(toReturn)
}

func ( oa * OutgoingAudio ) querystring ( ) querystring { toReturn := map [ string ] string ( oa . getBaseQueryString ( ) ) if oa . Duration != 0 { toReturn [ " " ] = fmt . Sprint ( oa . Duration ) } if oa . Performer != " " { toReturn [ " " ] = oa . Performer } if oa . Title != " " { toReturn [ " " ] = oa . Title } return querystring ( toReturn ) }

// querystring implements querystringer to represent the audio file.

querystring implements querystringer to represent the audio file .


func (op *OutgoingPhoto) querystring() querystring {
	toReturn := map[string]string(op.getBaseQueryString())

	if op.Caption != "" {
		toReturn["caption"] = op.Caption
	}

	return querystring(toReturn)
}

func ( op * OutgoingPhoto ) querystring ( ) querystring { toReturn := map [ string ] string ( op . getBaseQueryString ( ) ) if op . Caption != " " { toReturn [ " " ] = op . Caption } return querystring ( toReturn ) }

// querystring implements querystringer to represent the photo.

querystring implements querystringer to represent the photo .


func (op *OutgoingUserProfilePhotosRequest) querystring() querystring {
	toReturn := map[string]string{}
	toReturn["user_id"] = fmt.Sprint(op.UserID)

	if op.Offset != 0 {
		toReturn["offset"] = fmt.Sprint(op.Offset)
	}

	if op.Limit != 0 {
		toReturn["limit"] = fmt.Sprint(op.Limit)
	}

	return querystring(toReturn)
}

func ( op * OutgoingUserProfilePhotosRequest ) querystring ( ) querystring { toReturn := map [ string ] string { } toReturn [ " " ] = fmt . Sprint ( op . UserID ) if op . Offset != 0 { toReturn [ " " ] = fmt . Sprint ( op . Offset ) } if op . Limit != 0 { toReturn [ " " ] = fmt . Sprint ( op . Limit ) } return querystring ( toReturn ) }

// querystring implements querystringer to represent the request.

querystring implements querystringer to represent the request .


func (ov *OutgoingVideo) querystring() querystring {
	toReturn := map[string]string(ov.getBaseQueryString())

	if ov.Caption != "" {
		toReturn["caption"] = ov.Caption
	}

	if ov.Duration != 0 {
		toReturn["duration"] = fmt.Sprint(ov.Duration)
	}

	return querystring(toReturn)
}

func ( ov * OutgoingVideo ) querystring ( ) querystring { toReturn := map [ string ] string ( ov . getBaseQueryString ( ) ) if ov . Caption != " " { toReturn [ " " ] = ov . Caption } if ov . Duration != 0 { toReturn [ " " ] = fmt . Sprint ( ov . Duration ) } return querystring ( toReturn ) }

// querystring implements querystringer to represent the outgoing video
// file.

querystring implements querystringer to represent the outgoing video file .


func (ov *OutgoingVoice) querystring() querystring {
	toReturn := map[string]string(ov.getBaseQueryString())

	if ov.Duration != 0 {
		toReturn["duration"] = fmt.Sprint(ov.Duration)
	}

	return querystring(toReturn)
}

func ( ov * OutgoingVoice ) querystring ( ) querystring { toReturn := map [ string ] string ( ov . getBaseQueryString ( ) ) if ov . Duration != 0 { toReturn [ " " ] = fmt . Sprint ( ov . Duration ) } return querystring ( toReturn ) }

// querystring implements querystringer to represent the outgoing voice
// note.

querystring implements querystringer to represent the outgoing voice note .


func NewInlineQueryResultArticle(id, title, text string) *InlineQueryResultArticle {
	return &InlineQueryResultArticle{
		InlineQueryResultBase: InlineQueryResultBase{
			Type: ArticleResult,
			ID:   id,
		},
		Title: title,
		Text:  text,
	}
}

func NewInlineQueryResultArticle ( id , title , text string ) * InlineQueryResultArticle { return & InlineQueryResultArticle { InlineQueryResultBase : InlineQueryResultBase { Type : ArticleResult , ID : id , } , Title : title , Text : text , } }

// NewInlineQueryResultArticle returns a new InlineQueryResultArticle with
// all mandatory fields set.

NewInlineQueryResultArticle returns a new InlineQueryResultArticle with all mandatory fields set .


func NewInlineQueryResultPhoto(id, photoURL, thumbURL string) *InlineQueryResultPhoto {
	return &InlineQueryResultPhoto{
		InlineQueryResultBase: InlineQueryResultBase{
			Type: PhotoResult,
			ID:   id,
		},
		PhotoURL: photoURL,
		ThumbURL: thumbURL,
	}
}

func NewInlineQueryResultPhoto ( id , photoURL , thumbURL string ) * InlineQueryResultPhoto { return & InlineQueryResultPhoto { InlineQueryResultBase : InlineQueryResultBase { Type : PhotoResult , ID : id , } , PhotoURL : photoURL , ThumbURL : thumbURL , } }

// NewInlineQueryResultPhoto returns a new InlineQueryResultPhoto with all
// mandatory fields set.

NewInlineQueryResultPhoto returns a new InlineQueryResultPhoto with all mandatory fields set .


func NewInlineQueryResultGif(id, gifURL, thumbURL string) *InlineQueryResultGif {
	return &InlineQueryResultGif{
		InlineQueryResultBase: InlineQueryResultBase{
			Type: GifResult,
			ID:   id,
		},
		GifURL:   gifURL,
		ThumbURL: thumbURL,
	}
}

func NewInlineQueryResultGif ( id , gifURL , thumbURL string ) * InlineQueryResultGif { return & InlineQueryResultGif { InlineQueryResultBase : InlineQueryResultBase { Type : GifResult , ID : id , } , GifURL : gifURL , ThumbURL : thumbURL , } }

// NewInlineQueryResultGif returns a new InlineQueryResultGif with all
// mandatory fields set.

NewInlineQueryResultGif returns a new InlineQueryResultGif with all mandatory fields set .


func NewInlineQueryResultMpeg4Gif(id, mpeg4URL, thumbURL string) *InlineQueryResultMpeg4Gif {
	return &InlineQueryResultMpeg4Gif{
		InlineQueryResultBase: InlineQueryResultBase{
			Type: PhotoResult,
			ID:   id,
		},
		Mpeg4URL: mpeg4URL,
		ThumbURL: thumbURL,
	}
}

func NewInlineQueryResultMpeg4Gif ( id , mpeg4URL , thumbURL string ) * InlineQueryResultMpeg4Gif { return & InlineQueryResultMpeg4Gif { InlineQueryResultBase : InlineQueryResultBase { Type : PhotoResult , ID : id , } , Mpeg4URL : mpeg4URL , ThumbURL : thumbURL , } }

// NewInlineQueryResultMpeg4Gif returns a new InlineQueryResultMpeg4Gif
// with all mandatory fields set.

NewInlineQueryResultMpeg4Gif returns a new InlineQueryResultMpeg4Gif with all mandatory fields set .


func NewInlineQueryResultVideo(id, videoURL, thumbURL, title, text string, mimeType MIMEType) *InlineQueryResultVideo {
	return &InlineQueryResultVideo{
		InlineQueryResultBase: InlineQueryResultBase{
			Type: PhotoResult,
			ID:   id,
		},
		VideoURL: videoURL,
		MIMEType: mimeType,
		ThumbURL: thumbURL,
		Title:    title,
		Text:     text,
	}
}

func NewInlineQueryResultVideo ( id , videoURL , thumbURL , title , text string , mimeType MIMEType ) * InlineQueryResultVideo { return & InlineQueryResultVideo { InlineQueryResultBase : InlineQueryResultBase { Type : PhotoResult , ID : id , } , VideoURL : videoURL , MIMEType : mimeType , ThumbURL : thumbURL , Title : title , Text : text , } }

// NewInlineQueryResultVideo returns a new InlineQueryResultVideo with all
// mandatory fields set.

NewInlineQueryResultVideo returns a new InlineQueryResultVideo with all mandatory fields set .


func (op *OutgoingUserProfilePhotosRequest) Send() (*UserProfilePhotosResponse, error) {
	resp := &UserProfilePhotosResponse{}
	_, err := op.api.c.postJSON(getUserProfilePhotos, resp, op)

	if err != nil {
		return nil, err
	}

	err = check(&resp.baseResponse)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func ( op * OutgoingUserProfilePhotosRequest ) Send ( ) ( * UserProfilePhotosResponse , error ) { resp := & UserProfilePhotosResponse { } _ , err := op . api . c . postJSON ( getUserProfilePhotos , resp , op ) if err != nil { return nil , err } err = check ( & resp . baseResponse ) if err != nil { return nil , err } return resp , nil }

// Send sends the request.
// On success, the photos are returned as a UserProfilePhotosResponse.

Send sends the request . On success the photos are returned as a UserProfilePhotosResponse .


func (oc *OutgoingChatAction) Send() error {
	resp := &baseResponse{}
	_, err := oc.api.c.postJSON(sendChatAction, resp, oc)

	if err != nil {
		return err
	}

	return check(resp)
}

func ( oc * OutgoingChatAction ) Send ( ) error { resp := & baseResponse { } _ , err := oc . api . c . postJSON ( sendChatAction , resp , oc ) if err != nil { return err } return check ( resp ) }

// Send sends the chat action.
// On success, nil is returned.

Send sends the chat action . On success nil is returned .


func (ia *InlineQueryAnswer) Send() error {
	resp := &baseResponse{}
	_, err := ia.api.c.postJSON(answerInlineQuery, resp, ia)

	if err != nil {
		return err
	}

	return check(resp)
}

func ( ia * InlineQueryAnswer ) Send ( ) error { resp := & baseResponse { } _ , err := ia . api . c . postJSON ( answerInlineQuery , resp , ia ) if err != nil { return err } return check ( resp ) }

// Send sends the inline query answer.
// On success, nil is returned.

Send sends the inline query answer . On success nil is returned .


func (kr *OutgoingKickChatMember) Send() error {
	resp := &baseResponse{}
	_, err := kr.api.c.postJSON(kickChatMember, resp, kr)

	if err != nil {
		return err
	}

	return check(resp)
}

func ( kr * OutgoingKickChatMember ) Send ( ) error { resp := & baseResponse { } _ , err := kr . api . c . postJSON ( kickChatMember , resp , kr ) if err != nil { return err } return check ( resp ) }


func (ub *OutgoingUnbanChatMember) Send() error {
	resp := &baseResponse{}
	_, err := ub.api.c.postJSON(unbanChatMember, resp, ub)

	if err != nil {
		return err
	}

	return check(resp)
}

func ( ub * OutgoingUnbanChatMember ) Send ( ) error { resp := & baseResponse { } _ , err := ub . api . c . postJSON ( unbanChatMember , resp , ub ) if err != nil { return err } return check ( resp ) }


func (cbr *OutgoingCallbackQueryResponse) Send() error {
	resp := &baseResponse{}
	_, err := cbr.api.c.postJSON(answerCallbackQuery, resp, cbr)

	if err != nil {
		return err
	}

	return check(resp)
}

func ( cbr * OutgoingCallbackQueryResponse ) Send ( ) error { resp := & baseResponse { } _ , err := cbr . api . c . postJSON ( answerCallbackQuery , resp , cbr ) if err != nil { return err } return check ( resp ) }


func NewAPIClient(cfg *Configuration) *APIClient {
	if cfg.HTTPClient == nil {
		cfg.HTTPClient = http.DefaultClient
	}

	c := &APIClient{}
	c.cfg = cfg
	c.common.client = c

	// API Services
	c.ServiceProviderConfigApi = (*ServiceProviderConfigApiService)(&c.common)
	c.UserApi = (*UserApiService)(&c.common)

	return c
}

func
NewAPIClient
(
cfg
*
Configuration
)
*
APIClient
{
if
cfg
.
HTTPClient
==
{
cfg
.
HTTPClient
=
http
.
DefaultClient
}
c
:=
&
APIClient
{
}
c
.
cfg
=
cfg
c
.
common
.
client
=
c
// API Services
c
.
ServiceProviderConfigApi
=
(
*
ServiceProviderConfigApiService
)
(
&
c
.
common
)
c
.
UserApi
=
(
*
UserApiService
)
(
&
c
.
common
)
return
c
}

// NewAPIClient creates a new API client. Requires a userAgent string describing your application.
// optionally a custom http.Client to allow for advanced features such as caching.

NewAPIClient creates a new API client . Requires a userAgent string describing your application . optionally a custom http . Client to allow for advanced features such as caching .


func (ts *TimeStamp) BeforeInsert() error {
	n := now()
	ts.CreatedAt = n
	ts.UpdatedAt = n
	return nil
}

func ( ts * TimeStamp ) BeforeInsert ( ) error { n := now ( ) ts . CreatedAt = n ts . UpdatedAt = n return nil }

// BeforeInsert sets current time to CreatedAt and UpdatedAt field.
// It always returns nil.

BeforeInsert sets current time to CreatedAt and UpdatedAt field . It always returns nil .


func ColumnName(d Dialect, tname, cname string) string {
	if cname != "*" {
		cname = d.Quote(cname)
	}
	if tname == "" {
		return cname
	}
	return fmt.Sprintf("%s.%s", d.Quote(tname), cname)
}

func ColumnName ( d Dialect , tname , cname string ) string { if cname != " " { cname = d . Quote ( cname ) } if tname == " " { return cname } return fmt . Sprintf ( " " , d . Quote ( tname ) , cname ) }

// columnName returns the column name that added the table name with quoted if needed.

columnName returns the column name that added the table name with quoted if needed .


func New(dialect Dialect, dsn string) (*DB, error) {
	db, err := sql.Open(dialect.Name(), dsn)
	if err != nil {
		return nil, err
	}
	return &DB{db: db, dialect: dialect, logger: defaultLogger}, nil
}

func New ( dialect Dialect , dsn string ) ( * DB , error ) { db , err := sql . Open ( dialect . Name ( ) , dsn ) if err != nil { return nil , err } return & DB { db : db , dialect : dialect , logger : defaultLogger } , nil }

// New returns a new DB.
// If any error occurs, it returns nil and error.

New returns a new DB . If any error occurs it returns nil and error .


func (db *DB) From(arg interface{}) *From {
	t := reflect.Indirect(reflect.ValueOf(arg)).Type()
	if t.Kind() != reflect.Struct {
		panic(fmt.Errorf("From: argument must be struct (or that pointer) type, got %v", t))
	}
	return &From{TableName: db.tableName(t)}
}

func ( db * DB ) From ( arg interface { } ) * From { t := reflect . Indirect ( reflect . ValueOf ( arg ) ) . Type ( ) if t . Kind ( ) != reflect . Struct { panic ( fmt . Errorf ( " " , t ) ) } return & From { TableName : db . tableName ( t ) } }

// From returns a "FROM" statement.
// A table name will be determined from name of struct of arg.
// If arg argument is not struct type, it panics.

From returns a FROM statement . A table name will be determined from name of struct of arg . If arg argument is not struct type it panics .


func (db *DB) Where(cond interface{}, args ...interface{}) *Condition {
	return newCondition(db).Where(cond, args...)
}

func ( db * DB ) Where ( cond interface { } , args ... interface { } ) * Condition { return newCondition ( db ) . Where ( cond , args ... ) }

// Where returns a new Condition of "WHERE" clause.

Where returns a new Condition of WHERE clause .


func (db *DB) OrderBy(table interface{}, column interface{}, order ...interface{}) *Condition {
	return newCondition(db).OrderBy(table, column, order...)
}

func ( db * DB ) OrderBy ( table interface { } , column interface { } , order ... interface { } ) * Condition { return newCondition ( db ) . OrderBy ( table , column , order ... ) }

// OrderBy returns a new Condition of "ORDER BY" clause.

OrderBy returns a new Condition of ORDER BY clause .


func (db *DB) Limit(lim int) *Condition {
	return newCondition(db).Limit(lim)
}

func ( db * DB ) Limit ( lim int ) * Condition { return newCondition ( db ) . Limit ( lim ) }

// Limit returns a new Condition of "LIMIT" clause.

Limit returns a new Condition of LIMIT clause .


func (db *DB) Offset(offset int) *Condition {
	return newCondition(db).Offset(offset)
}

func ( db * DB ) Offset ( offset int ) * Condition { return newCondition ( db ) . Offset ( offset ) }

// Offset returns a new Condition of "OFFSET" clause.

Offset returns a new Condition of OFFSET clause .


func (db *DB) Join(table interface{}) *JoinCondition {
	return (&JoinCondition{db: db}).Join(table)
}

func ( db * DB ) Join ( table interface { } ) * JoinCondition { return ( & JoinCondition { db : db } ) . Join ( table ) }

// Join returns a new JoinCondition of "JOIN" clause.

Join returns a new JoinCondition of JOIN clause .


func (db *DB) Count(column ...interface{}) *Function {
	switch len(column) {
	case 0, 1:
		// do nothing.
	default:
		panic(fmt.Errorf("Count: a number of argument must be 0 or 1, got %v", len(column)))
	}
	return &Function{
		Name: "COUNT",
		Args: column,
	}
}

func
(
db
*
DB
)
Count
(
column
...
interface
{
}
)
*
Function
{
switch
len
(
column
)
{
case
0
,
1
:
// do nothing.
default
:
panic
(
fmt
.
Errorf
(
"
"
,
len
(
column
)
)
)
}
return
&
Function
{
Name
:
"
"
,
Args
:
column
,
}
}


func (db *DB) Update(obj interface{}) (affected int64, err error) {
	rv, rtype, tableName, err := db.tableValueOf("Update", obj)
	if err != nil {
		return -1, err
	}
	if hook, ok := obj.(BeforeUpdater); ok {
		if err := hook.BeforeUpdate(); err != nil {
			return -1, err
		}
	}
	fieldIndexes := db.collectFieldIndexes(rtype, nil)
	pkIdx := db.findPKIndex(rtype, nil)
	if len(pkIdx) < 1 {
		return -1, fmt.Errorf(`Update: fields of struct doesn't have primary key: "pk" struct tag must be specified for update`)
	}
	sets := make([]string, len(fieldIndexes))
	var args []interface{}
	for i, index := range fieldIndexes {
		col := db.columnFromTag(rtype.FieldByIndex(index))
		sets[i] = fmt.Sprintf("%s = %s", db.dialect.Quote(col), db.dialect.PlaceHolder(i))
		args = append(args, rv.FieldByIndex(index).Interface())
	}
	query := fmt.Sprintf("UPDATE %s SET %s WHERE %s = %s",
		db.dialect.Quote(tableName),
		strings.Join(sets, ", "),
		db.dialect.Quote(db.columnFromTag(rtype.FieldByIndex(pkIdx))),
		db.dialect.PlaceHolder(len(fieldIndexes)))
	args = append(args, rv.FieldByIndex(pkIdx).Interface())
	stmt, err := db.prepare(query, args...)
	if err != nil {
		return -1, err
	}
	defer stmt.Close()
	result, err := stmt.Exec(args...)
	if err != nil {
		return -1, err
	}
	affected, _ = result.RowsAffected()
	if hook, ok := obj.(AfterUpdater); ok {
		if err := hook.AfterUpdate(); err != nil {
			return affected, err
		}
	}
	return affected, nil
}

// Update updates the one record.
// The obj must be struct, and must have field that specified "pk" struct tag.
// Update will try to update record which searched by value of primary key in obj.
// Update returns the number of rows affected by an update.

Update updates the one record . The obj must be struct and must have field that specified pk struct tag . Update will try to update record which searched by value of primary key in obj . Update returns the number of rows affected by an update .


func (db *DB) Delete(obj interface{}) (affected int64, err error) {
	objs, rtype, tableName, err := db.tableObjs("Delete", obj)
	if err != nil {
		return -1, err
	}
	if len(objs) < 1 {
		return 0, nil
	}
	for _, obj := range objs {
		if hook, ok := obj.(BeforeDeleter); ok {
			if err := hook.BeforeDelete(); err != nil {
				return -1, err
			}
		}
	}
	pkIdx := db.findPKIndex(rtype, nil)
	if len(pkIdx) < 1 {
		return -1, fmt.Errorf(`Delete: fields of struct doesn't have primary key: "pk" struct tag must be specified for delete`)
	}
	var args []interface{}
	for _, obj := range objs {
		rv := reflect.Indirect(reflect.ValueOf(obj))
		args = append(args, rv.FieldByIndex(pkIdx).Interface())
	}
	holders := make([]string, len(args))
	for i := 0; i < len(holders); i++ {
		holders[i] = db.dialect.PlaceHolder(i)
	}
	query := fmt.Sprintf("DELETE FROM %s WHERE %s IN (%s)",
		db.dialect.Quote(tableName),
		db.dialect.Quote(db.columnFromTag(rtype.FieldByIndex(pkIdx))),
		strings.Join(holders, ", "))
	stmt, err := db.prepare(query, args...)
	if err != nil {
		return -1, err
	}
	defer stmt.Close()
	result, err := stmt.Exec(args...)
	if err != nil {
		return -1, err
	}
	affected, _ = result.RowsAffected()
	for _, obj := range objs {
		if hook, ok := obj.(AfterDeleter); ok {
			if err := hook.AfterDelete(); err != nil {
				return affected, err
			}
		}
	}
	return affected, nil
}

// Delete deletes the records from database table.
// The obj must be pointer to struct or slice of struct, and must have field that specified "pk" struct tag.
// Delete will try to delete record which searched by value of primary key in obj.
// Delete returns teh number of rows affected by a delete.

Delete deletes the records from database table . The obj must be pointer to struct or slice of struct and must have field that specified pk struct tag . Delete will try to delete record which searched by value of primary key in obj . Delete returns teh number of rows affected by a delete .


func (db *DB) Begin() error {
	tx, err := db.db.Begin()
	if err != nil {
		return err
	}
	db.m.Lock()
	defer db.m.Unlock()
	db.tx = tx
	return nil
}

func ( db * DB ) Begin ( ) error { tx , err := db . db . Begin ( ) if err != nil { return err } db . m . Lock ( ) defer db . m . Unlock ( ) db . tx = tx return nil }


func (db *DB) Commit() error {
	db.m.Lock()
	defer db.m.Unlock()
	if db.tx == nil {
		return ErrTxDone
	}
	err := db.tx.Commit()
	db.tx = nil
	return err
}

func ( db * DB ) Commit ( ) error { db . m . Lock ( ) defer db . m . Unlock ( ) if db . tx == nil { return ErrTxDone } err := db . tx . Commit ( ) db . tx = nil return err }

// Commit commits the transaction.
// If Begin still not called, or Commit or Rollback already called, Commit returns ErrTxDone.

Commit commits the transaction . If Begin still not called or Commit or Rollback already called Commit returns ErrTxDone .


func (db *DB) Quote(s string) string {
	return db.dialect.Quote(s)
}

func ( db * DB ) Quote ( s string ) string { return db . dialect . Quote ( s ) }

// Quote returns a quoted s.
// It is for a column name, not a value.

Quote returns a quoted s . It is for a column name not a value .


func (db *DB) SetLogOutput(w io.Writer) {
	if w == nil {
		db.logger = defaultLogger
	} else {
		db.logger = &templateLogger{w: w, t: defaultLoggerTemplate}
	}
}

func ( db * DB ) SetLogOutput ( w io . Writer ) { if w == nil { db . logger = defaultLogger } else { db . logger = & templateLogger { w : w , t : defaultLoggerTemplate } } }

// SetLogOutput sets output destination for logging.
// If w is nil, it unsets output of logging.

SetLogOutput sets output destination for logging . If w is nil it unsets output of logging .


func (db *DB) selectToSlice(rows *sql.Rows, t reflect.Type) (reflect.Value, error) {
	columns, err := rows.Columns()
	if err != nil {
		return reflect.Value{}, err
	}
	t = t.Elem()
	ptrN := 0
	for ; t.Kind() == reflect.Ptr; ptrN++ {
		t = t.Elem()
	}
	fieldIndexes := make([][]int, len(columns))
	for i, column := range columns {
		index := db.fieldIndexByName(t, column, nil)
		if len(index) < 1 {
			return reflect.Value{}, fmt.Errorf("`%v` field isn't defined in %v or embedded struct", stringutil.ToUpperCamelCase(column), t)
		}
		fieldIndexes[i] = index
	}
	dest := make([]interface{}, len(columns))
	var result []reflect.Value
	for rows.Next() {
		v := reflect.New(t).Elem()
		for i, index := range fieldIndexes {
			field := v.FieldByIndex(index)
			dest[i] = field.Addr().Interface()
		}
		if err := rows.Scan(dest...); err != nil {
			return reflect.Value{}, err
		}
		result = append(result, v)
	}
	if err := rows.Err(); err != nil {
		return reflect.Value{}, err
	}
	for i := 0; i < ptrN; i++ {
		t = reflect.PtrTo(t)
	}
	slice := reflect.MakeSlice(reflect.SliceOf(t), len(result), len(result))
	for i, v := range result {
		for j := 0; j < ptrN; j++ {
			v = v.Addr()
		}
		slice.Index(i).Set(v)
	}
	return slice, nil
}

func ( db * DB ) selectToSlice ( rows * sql . Rows , t reflect . Type ) ( reflect . Value , error ) { columns , err := rows . Columns ( ) if err != nil { return reflect . Value { } , err } t = t . Elem ( ) ptrN := 0 for ; t . Kind ( ) == reflect . Ptr ; ptrN ++ { t = t . Elem ( ) } fieldIndexes := make ( [ ] [ ] int , len ( columns ) ) for i , column := range columns { index := db . fieldIndexByName ( t , column , nil ) if len ( index ) < 1 { return reflect . Value { } , fmt . Errorf ( " " , stringutil . ToUpperCamelCase ( column ) , t ) } fieldIndexes [ i ] = index } dest := make ( [ ] interface { } , len ( columns ) ) var result [ ] reflect . Value for rows . Next ( ) { v := reflect . New ( t ) . Elem ( ) for i , index := range fieldIndexes { field := v . FieldByIndex ( index ) dest [ i ] = field . Addr ( ) . Interface ( ) } if err := rows . Scan ( dest ... ) ; err != nil { return reflect . Value { } , err } result = append ( result , v ) } if err := rows . Err ( ) ; err != nil { return reflect . Value { } , err } for i := 0 ; i < ptrN ; i ++ { t = reflect . PtrTo ( t ) } slice := reflect . MakeSlice ( reflect . SliceOf ( t ) , len ( result ) , len ( result ) ) for i , v := range result { for j := 0 ; j < ptrN ; j ++ { v = v . Addr ( ) } slice . Index ( i ) . Set ( v ) } return slice , nil }

// selectToSlice returns a slice value fetched from rows.

selectToSlice returns a slice value fetched from rows .


func (db *DB) selectToValue(rows *sql.Rows, t reflect.Type) (reflect.Value, error) {
	ptrN := 0
	for ; t.Kind() == reflect.Ptr; ptrN++ {
		t = t.Elem()
	}
	dest := reflect.New(t).Elem()
	if rows.Next() {
		if err := rows.Scan(dest.Addr().Interface()); err != nil {
			return reflect.Value{}, err
		}
	}
	for i := 0; i < ptrN; i++ {
		dest = dest.Addr()
	}
	return dest, nil
}

func ( db * DB ) selectToValue ( rows * sql . Rows , t reflect . Type ) ( reflect . Value , error ) { ptrN := 0 for ; t . Kind ( ) == reflect . Ptr ; ptrN ++ { t = t . Elem ( ) } dest := reflect . New ( t ) . Elem ( ) if rows . Next ( ) { if err := rows . Scan ( dest . Addr ( ) . Interface ( ) ) ; err != nil { return reflect . Value { } , err } } for i := 0 ; i < ptrN ; i ++ { dest = dest . Addr ( ) } return dest , nil }

// selectToValue returns a single value fetched from rows.

selectToValue returns a single value fetched from rows .


func (db *DB) fieldIndexByName(t reflect.Type, name string, index []int) []int {
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		if candidate := db.columnFromTag(field); candidate == name {
			return append(index, i)
		}
		if field.Anonymous {
			if idx := db.fieldIndexByName(field.Type, name, append(index, i)); len(idx) > 0 {
				return append(index, idx...)
			}
		}
	}
	return nil
}

func ( db * DB ) fieldIndexByName ( t reflect . Type , name string , index [ ] int ) [ ] int { for i := 0 ; i < t . NumField ( ) ; i ++ { field := t . Field ( i ) if candidate := db . columnFromTag ( field ) ; candidate == name { return append ( index , i ) } if field . Anonymous { if idx := db . fieldIndexByName ( field . Type , name , append ( index , i ) ) ; len ( idx ) > 0 { return append ( index , idx ... ) } } } return nil }

// fieldIndexByName returns the nested field corresponding to the index sequence.

fieldIndexByName returns the nested field corresponding to the index sequence .


func (db *DB) columns(tableName string, columns []interface{}) string {
	if len(columns) == 0 {
		return ColumnName(db.dialect, tableName, "*")
	}
	names := make([]string, len(columns))
	for i, col := range columns {
		switch c := col.(type) {
		case Raw:
			names[i] = fmt.Sprint(*c)
		case string:
			names[i] = ColumnName(db.dialect, tableName, c)
		case *Distinct:
			names[i] = fmt.Sprintf("DISTINCT %s", db.columns(tableName, ToInterfaceSlice(c.columns)))
		default:
			panic(fmt.Errorf("column name must be string, Raw or *Distinct, got %T", c))
		}
	}
	return strings.Join(names, ", ")
}

func ( db * DB ) columns ( tableName string , columns [ ] interface { } ) string { if len ( columns ) == 0 { return ColumnName ( db . dialect , tableName , " " ) } names := make ( [ ] string , len ( columns ) ) for i , col := range columns { switch c := col . ( type ) { case Raw : names [ i ] = fmt . Sprint ( * c ) case string : names [ i ] = ColumnName ( db . dialect , tableName , c ) case * Distinct : names [ i ] = fmt . Sprintf ( " " , db . columns ( tableName , ToInterfaceSlice ( c . columns ) ) ) default : panic ( fmt . Errorf ( " " , c ) ) } } return strings . Join ( names , " " ) }

// columns returns the comma-separated column name with quoted.

columns returns the comma - separated column name with quoted .


func (db *DB) tagsFromField(field *reflect.StructField) (options []string) {
	if db.hasSkipTag(field) {
		return nil
	}
	for _, tag := range strings.Split(field.Tag.Get(dbTag), ",") {
		if t := strings.ToLower(strings.TrimSpace(tag)); t != "" {
			options = append(options, t)
		}
	}
	return options
}

func ( db * DB ) tagsFromField ( field * reflect . StructField ) ( options [ ] string ) { if db . hasSkipTag ( field ) { return nil } for _ , tag := range strings . Split ( field . Tag . Get ( dbTag ) , " " ) { if t := strings . ToLower ( strings . TrimSpace ( tag ) ) ; t != " " { options = append ( options , t ) } } return options }

// tagsFromField returns a slice of option strings.

tagsFromField returns a slice of option strings .


func (db *DB) hasSkipTag(field *reflect.StructField) bool {
	if field.Tag.Get(dbTag) == skipTag {
		return true
	}
	return false
}

func ( db * DB ) hasSkipTag ( field * reflect . StructField ) bool { if field . Tag . Get ( dbTag ) == skipTag { return true } return false }

// hasSkipTag returns whether the struct field has the "-" tag.

hasSkipTag returns whether the struct field has the - tag .


func (db *DB) hasPKTag(field *reflect.StructField) bool {
	for _, tag := range db.tagsFromField(field) {
		if tag == "pk" {
			return true
		}
	}
	return false
}

func ( db * DB ) hasPKTag ( field * reflect . StructField ) bool { for _ , tag := range db . tagsFromField ( field ) { if tag == " " { return true } } return false }

// hasPKTag returns whether the struct field has the "pk" tag.

hasPKTag returns whether the struct field has the pk tag .


func (db *DB) isAutoIncrementable(field *reflect.StructField) bool {
	switch field.Type.Kind() {
	case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return true
	}
	return false
}

func ( db * DB ) isAutoIncrementable ( field * reflect . StructField ) bool { switch field . Type . Kind ( ) { case reflect . Int , reflect . Int16 , reflect . Int32 , reflect . Int64 , reflect . Uint , reflect . Uint16 , reflect . Uint32 , reflect . Uint64 : return true } return false }

// isAutoIncrementable returns whether the struct field is integer.

isAutoIncrementable returns whether the struct field is integer .


func (db *DB) collectFieldIndexes(typ reflect.Type, index []int) (indexes [][]int) {
	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		if IsUnexportedField(field) {
			continue
		}
		if !(db.hasSkipTag(&field) || (db.hasPKTag(&field) && db.isAutoIncrementable(&field))) {
			tmp := make([]int, len(index)+1)
			copy(tmp, index)
			tmp[len(tmp)-1] = i
			if field.Anonymous {
				indexes = append(indexes, db.collectFieldIndexes(field.Type, tmp)...)
			} else {
				indexes = append(indexes, tmp)
			}
		}
	}
	return indexes
}

func ( db * DB ) collectFieldIndexes ( typ reflect . Type , index [ ] int ) ( indexes [ ] [ ] int ) { for i := 0 ; i < typ . NumField ( ) ; i ++ { field := typ . Field ( i ) if IsUnexportedField ( field ) { continue } if ! ( db . hasSkipTag ( & field ) || ( db . hasPKTag ( & field ) && db . isAutoIncrementable ( & field ) ) ) { tmp := make ( [ ] int , len ( index ) + 1 ) copy ( tmp , index ) tmp [ len ( tmp ) - 1 ] = i if field . Anonymous { indexes = append ( indexes , db . collectFieldIndexes ( field . Type , tmp ) ... ) } else { indexes = append ( indexes , tmp ) } } } return indexes }

// collectFieldIndexes returns the indexes of field which doesn't have skip tag and pk tag.

collectFieldIndexes returns the indexes of field which doesn t have skip tag and pk tag .


func (db *DB) findPKIndex(typ reflect.Type, index []int) []int {
	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		if IsUnexportedField(field) {
			continue
		}
		if field.Anonymous {
			if idx := db.findPKIndex(field.Type, append(index, i)); idx != nil {
				return append(index, idx...)
			}
			continue
		}
		if db.hasPKTag(&field) {
			return append(index, i)
		}
	}
	return nil
}

func ( db * DB ) findPKIndex ( typ reflect . Type , index [ ] int ) [ ] int { for i := 0 ; i < typ . NumField ( ) ; i ++ { field := typ . Field ( i ) if IsUnexportedField ( field ) { continue } if field . Anonymous { if idx := db . findPKIndex ( field . Type , append ( index , i ) ) ; idx != nil { return append ( index , idx ... ) } continue } if db . hasPKTag ( & field ) { return append ( index , i ) } } return nil }

// findPKIndex returns the nested field corresponding to the index sequence of field of primary key.

findPKIndex returns the nested field corresponding to the index sequence of field of primary key .


func (db *DB) sizeFromTag(field *reflect.StructField) (size uint64, err error) {
	if s := field.Tag.Get(dbSizeTag); s != "" {
		size, err = strconv.ParseUint(s, 10, 64)
	}
	return size, err
}

func ( db * DB ) sizeFromTag ( field * reflect . StructField ) ( size uint64 , err error ) { if s := field . Tag . Get ( dbSizeTag ) ; s != " " { size , err = strconv . ParseUint ( s , 10 , 64 ) } return size , err }

// sizeFromTag returns a size from tag.
// If "size" tag specified to struct field, it will converted to uint64 and returns it.
// If it doesn't specify, it returns 0.
// If value of "size" tag cannot convert to uint64, it returns 0 and error.

sizeFromTag returns a size from tag . If size tag specified to struct field it will converted to uint64 and returns it . If it doesn t specify it returns 0 . If value of size tag cannot convert to uint64 it returns 0 and error .


func (db *DB) columnFromTag(field reflect.StructField) string {
	col := field.Tag.Get(dbColumnTag)
	if col == "" {
		return stringutil.ToSnakeCase(field.Name)
	}
	return col
}

func ( db * DB ) columnFromTag ( field reflect . StructField ) string { col := field . Tag . Get ( dbColumnTag ) if col == " " { return stringutil . ToSnakeCase ( field . Name ) } return col }

// columnFromTag returns the column name.
// If "column" tag specified to struct field, returns it.
// Otherwise, it returns snake-cased field name as column name.

columnFromTag returns the column name . If column tag specified to struct field returns it . Otherwise it returns snake - cased field name as column name .


func (db *DB) defaultFromTag(field *reflect.StructField) (string, error) {
	def := field.Tag.Get(dbDefaultTag)
	if def == "" {
		return "", nil
	}
	switch field.Type.Kind() {
	case reflect.Bool:
		b, err := strconv.ParseBool(def)
		if err != nil {
			return "", err
		}
		return fmt.Sprintf("DEFAULT %v", db.dialect.FormatBool(b)), nil
	}
	return fmt.Sprintf("DEFAULT %v", def), nil
}

func ( db * DB ) defaultFromTag ( field * reflect . StructField ) ( string , error ) { def := field . Tag . Get ( dbDefaultTag ) if def == " " { return " " , nil } switch field . Type . Kind ( ) { case reflect . Bool : b , err := strconv . ParseBool ( def ) if err != nil { return " " , err } return fmt . Sprintf ( " " , db . dialect . FormatBool ( b ) ) , nil } return fmt . Sprintf ( " " , def ) , nil }

// defaultFromTag returns a "DEFAULT ..." keyword.
// If "default" tag specified to struct field, it use as the default value.
// If it doesn't specify, it returns empty string.

defaultFromTag returns a DEFAULT ... keyword . If default tag specified to struct field it use as the default value . If it doesn t specify it returns empty string .


func (c *Condition) Where(cond interface{}, args ...interface{}) *Condition {
	return c.appendQueryByCondOrExpr("Where", 0, Where, cond, args...)
}

func ( c * Condition ) Where ( cond interface { } , args ... interface { } ) * Condition { return c . appendQueryByCondOrExpr ( " " , 0 , Where , cond , args ... ) }

// Where adds "WHERE" clause to the Condition and returns it for method chain.

Where adds WHERE clause to the Condition and returns it for method chain .


func (c *Condition) And(cond interface{}, args ...interface{}) *Condition {
	return c.appendQueryByCondOrExpr("And", 100, And, cond, args...)
}

func ( c * Condition ) And ( cond interface { } , args ... interface { } ) * Condition { return c . appendQueryByCondOrExpr ( " " , 100 , And , cond , args ... ) }

// And adds "AND" operator to the Condition and returns it for method chain.

And adds AND operator to the Condition and returns it for method chain .


func (c *Condition) Or(cond interface{}, args ...interface{}) *Condition {
	return c.appendQueryByCondOrExpr("Or", 100, Or, cond, args...)
}

func ( c * Condition ) Or ( cond interface { } , args ... interface { } ) * Condition { return c . appendQueryByCondOrExpr ( " " , 100 , Or , cond , args ... ) }

// Or adds "OR" operator to the Condition and returns it for method chain.

Or adds OR operator to the Condition and returns it for method chain .


func (c *Condition) Like(arg string) *Condition {
	return c.appendQuery(100, Like, arg)
}

func ( c * Condition ) Like ( arg string ) * Condition { return c . appendQuery ( 100 , Like , arg ) }

// Like adds "LIKE" clause to the Condition and returns it for method chain.

Like adds LIKE clause to the Condition and returns it for method chain .


func (c *Condition) Between(from, to interface{}) *Condition {
	return c.appendQuery(100, Between, &between{from, to})
}

func ( c * Condition ) Between ( from , to interface { } ) * Condition { return c . appendQuery ( 100 , Between , & between { from , to } ) }

// Between adds "BETWEEN ... AND ..." clause to the Condition and returns it for method chain.

Between adds BETWEEN ... AND ... clause to the Condition and returns it for method chain .