This file is indexed.

/usr/share/gocode/src/github.com/ctdk/goiardi/datastore/db.go is in golang-github-ctdk-goiardi-dev 0.11.2-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * Copyright (c) 2013-2016, Jeremy Bingham (<jeremy@goiardi.gl>)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// General functions for goiardi database connections, if running in that mode.
// Database engine specific functions are in their respective source files.

package datastore

import (
	"bytes"
	"database/sql"
	//"encoding/gob"
	"encoding/json"
	"fmt"
	"github.com/ctdk/goiardi/config"
	// just want the side effects
	_ "github.com/go-sql-driver/mysql"
	// just want the side effects
	_ "github.com/lib/pq"
	"strings"
)

// Dbh is the database handle, shared around.
var Dbh *sql.DB

// Format to use for dates and times for MySQL.
const MySQLTimeFormat = "2006-01-02 15:04:05"

// Dbhandle is an interface for db handle types that can execute queries.
type Dbhandle interface {
	Prepare(query string) (*sql.Stmt, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	Query(query string, args ...interface{}) (*sql.Rows, error)
	Exec(query string, args ...interface{}) (sql.Result, error)
}

// ResRow is an interface for rows returned by Query, or a single row returned by
// QueryRow. Used for passing in a db handle or a transaction to a function.
type ResRow interface {
	Scan(dest ...interface{}) error
}

// ConnectDB connects to a database with the database name and a map of
// connection options. Currently supports MySQL and PostgreSQL.
func ConnectDB(dbEngine string, params interface{}) (*sql.DB, error) {
	switch strings.ToLower(dbEngine) {
	case "mysql", "postgres":
		var connectStr string
		var cerr error
		switch strings.ToLower(dbEngine) {
		case "mysql":
			connectStr, cerr = formatMysqlConStr(params)
		case "postgres":
			// no error needed at this step with
			// postgres
			connectStr = formatPostgresqlConStr(params)
		}
		if cerr != nil {
			return nil, cerr
		}
		db, err := sql.Open(strings.ToLower(dbEngine), connectStr)
		if err != nil {
			return nil, err
		}
		if err = db.Ping(); err != nil {
			return nil, err
		}
		db.SetMaxIdleConns(config.Config.DbPoolSize)
		db.SetMaxOpenConns(config.Config.MaxConn)
		return db, nil
	default:
		err := fmt.Errorf("cannot connect to database: unsupported database type %s", dbEngine)
		return nil, err
	}
}

// EncodeToJSON encodes an object to a JSON string.
func EncodeToJSON(obj interface{}) (string, error) {
	buf := new(bytes.Buffer)
	enc := json.NewEncoder(buf)
	var err error
	defer func() {
		if x := recover(); x != nil {
			err = fmt.Errorf("Something went wrong with encoding an object to a JSON string for storing.")
		}
	}()
	err = enc.Encode(obj)
	if err != nil {
		return "", err
	}
	return buf.String(), nil
}

// EncodeBlob encodes a slice or map of goiardi object data to save in the
// database. Pass the object to be encoded in like
// datastore.EncodeBlob(&foo.Thing).
func EncodeBlob(obj interface{}) ([]byte, error) {
	buf := new(bytes.Buffer)
	enc := json.NewEncoder(buf)
	var err error
	defer func() {
		if x := recover(); x != nil {
			err = fmt.Errorf("Something went wrong encoding an object for storing in the database with Gob")
		}
	}()
	err = enc.Encode(obj)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// DecodeBlob decodes the data encoded with EncodeBlob that was stored in the
// database so it can be loaded back into a goiardi object. The 'obj' in the
// arguments *must* be the address of the object receiving the blob of data (e.g.
// datastore.DecodeBlob(data, &obj).
func DecodeBlob(data []byte, obj interface{}) error {
	// hmmm
	dbuf := bytes.NewBuffer(data)
	dec := json.NewDecoder(dbuf)
	dec.UseNumber()
	err := dec.Decode(obj)
	if err != nil {
		return err
	}
	return nil
}

// CheckForOne object of the given type identified by the given name. For this
// function to work, the underlying table MUST have its primary text identifier
// be called "name".
func CheckForOne(dbhandle Dbhandle, kind string, name string) (int32, error) {
	var objID int32
	var prepStatement string
	if config.Config.UseMySQL {
		prepStatement = fmt.Sprintf("SELECT id FROM %s WHERE name = ?", kind)
	} else if config.Config.UsePostgreSQL {
		prepStatement = fmt.Sprintf("SELECT id FROM goiardi.%s WHERE name = $1", kind)
	}
	stmt, err := dbhandle.Prepare(prepStatement)
	if err != nil {
		return 0, err
	}
	defer stmt.Close()

	err = stmt.QueryRow(name).Scan(&objID)
	return objID, err
}