use string builder pool for mysql query strings
get more mysql queries to use string builders use consts instead of vars for growth hint variables
This commit is contained in:
parent
c8d021d70b
commit
ad4763a883
|
@ -336,19 +336,27 @@ func (a *MysqlAdapter) AddForeignKey(name, table, column, ftable, fcolumn string
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var silen1 = len("INSERT INTO ``() VALUES () ")
|
const silen1 = len("INSERT INTO ``() VALUES () ")
|
||||||
|
|
||||||
func (a *MysqlAdapter) SimpleInsert(name, table, columns, fields string) (string, error) {
|
func (a *MysqlAdapter) SimpleInsert(name, table, columns, fields string) (string, error) {
|
||||||
if table == "" {
|
if table == "" {
|
||||||
return "", errors.New("You need a name for this table")
|
return "", errors.New("You need a name for this table")
|
||||||
}
|
}
|
||||||
|
|
||||||
var sb strings.Builder
|
var sb *strings.Builder
|
||||||
|
ii := queryStrPool.Get()
|
||||||
|
if ii == nil {
|
||||||
|
sb = &strings.Builder{}
|
||||||
|
} else {
|
||||||
|
sb = ii.(*strings.Builder)
|
||||||
|
sb.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
sb.Grow(silen1 + len(table))
|
sb.Grow(silen1 + len(table))
|
||||||
sb.WriteString("INSERT INTO `")
|
sb.WriteString("INSERT INTO `")
|
||||||
sb.WriteString(table)
|
sb.WriteString(table)
|
||||||
sb.WriteString("`(")
|
|
||||||
if columns != "" {
|
if columns != "" {
|
||||||
|
sb.WriteString("`(")
|
||||||
sb.WriteString(a.buildColumns(columns))
|
sb.WriteString(a.buildColumns(columns))
|
||||||
sb.WriteString(") VALUES (")
|
sb.WriteString(") VALUES (")
|
||||||
fs := processFields(fields)
|
fs := processFields(fields)
|
||||||
|
@ -359,20 +367,25 @@ func (a *MysqlAdapter) SimpleInsert(name, table, columns, fields string) (string
|
||||||
}
|
}
|
||||||
nameLen := len(field.Name)
|
nameLen := len(field.Name)
|
||||||
if field.Name[0] == '"' && field.Name[nameLen-1] == '"' && nameLen >= 3 {
|
if field.Name[0] == '"' && field.Name[nameLen-1] == '"' && nameLen >= 3 {
|
||||||
field.Name = "'" + field.Name[1:nameLen-1] + "'"
|
sb.WriteRune('\'')
|
||||||
|
sb.WriteString(field.Name[1 : nameLen-1])
|
||||||
|
sb.WriteRune('\'')
|
||||||
|
} else if field.Name[0] == '\'' && field.Name[nameLen-1] == '\'' && nameLen >= 3 {
|
||||||
|
sb.WriteRune('\'')
|
||||||
|
sb.WriteString(strings.Replace(field.Name[1:nameLen-1], "'", "''", -1))
|
||||||
|
sb.WriteRune('\'')
|
||||||
|
} else {
|
||||||
|
sb.WriteString(field.Name)
|
||||||
}
|
}
|
||||||
if field.Name[0] == '\'' && field.Name[nameLen-1] == '\'' && nameLen >= 3 {
|
|
||||||
field.Name = "'" + strings.Replace(field.Name[1:nameLen-1], "'", "''", -1) + "'"
|
|
||||||
}
|
|
||||||
sb.WriteString(field.Name)
|
|
||||||
}
|
}
|
||||||
sb.WriteString(")")
|
sb.WriteString(")")
|
||||||
} else {
|
} else {
|
||||||
sb.WriteString(") VALUES ()")
|
sb.WriteString("`() VALUES ()")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Shunt the table name logic and associated stmt list up to the a higher layer to reduce the amount of unnecessary overhead in the builder / accumulator
|
// TODO: Shunt the table name logic and associated stmt list up to the a higher layer to reduce the amount of unnecessary overhead in the builder / accumulator
|
||||||
q := sb.String()
|
q := sb.String()
|
||||||
|
queryStrPool.Put(sb)
|
||||||
a.pushStatement(name, "insert", q)
|
a.pushStatement(name, "insert", q)
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
@ -382,12 +395,19 @@ func (a *MysqlAdapter) SimpleBulkInsert(name, table, columns string, fieldSet []
|
||||||
return "", errors.New("You need a name for this table")
|
return "", errors.New("You need a name for this table")
|
||||||
}
|
}
|
||||||
|
|
||||||
var sb strings.Builder
|
var sb *strings.Builder
|
||||||
|
ii := queryStrPool.Get()
|
||||||
|
if ii == nil {
|
||||||
|
sb = &strings.Builder{}
|
||||||
|
} else {
|
||||||
|
sb = ii.(*strings.Builder)
|
||||||
|
sb.Reset()
|
||||||
|
}
|
||||||
sb.Grow(silen1 + len(table))
|
sb.Grow(silen1 + len(table))
|
||||||
sb.WriteString("INSERT INTO `")
|
sb.WriteString("INSERT INTO `")
|
||||||
sb.WriteString(table)
|
sb.WriteString(table)
|
||||||
sb.WriteString("`(")
|
|
||||||
if columns != "" {
|
if columns != "" {
|
||||||
|
sb.WriteString("`(")
|
||||||
sb.WriteString(a.buildColumns(columns))
|
sb.WriteString(a.buildColumns(columns))
|
||||||
sb.WriteString(") VALUES (")
|
sb.WriteString(") VALUES (")
|
||||||
for oi, fields := range fieldSet {
|
for oi, fields := range fieldSet {
|
||||||
|
@ -412,11 +432,12 @@ func (a *MysqlAdapter) SimpleBulkInsert(name, table, columns string, fieldSet []
|
||||||
sb.WriteString(")")
|
sb.WriteString(")")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sb.WriteString(") VALUES ()")
|
sb.WriteString("`() VALUES ()")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Shunt the table name logic and associated stmt list up to the a higher layer to reduce the amount of unnecessary overhead in the builder / accumulator
|
// TODO: Shunt the table name logic and associated stmt list up to the a higher layer to reduce the amount of unnecessary overhead in the builder / accumulator
|
||||||
q := sb.String()
|
q := sb.String()
|
||||||
|
queryStrPool.Put(sb)
|
||||||
a.pushStatement(name, "bulk-insert", q)
|
a.pushStatement(name, "bulk-insert", q)
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
@ -503,7 +524,7 @@ func (a *MysqlAdapter) SimpleUpsert(name, table, columns, fields, where string)
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var sulen1 = len("UPDATE `` SET ")
|
const sulen1 = len("UPDATE `` SET ")
|
||||||
|
|
||||||
func (a *MysqlAdapter) SimpleUpdate(up *updatePrebuilder) (string, error) {
|
func (a *MysqlAdapter) SimpleUpdate(up *updatePrebuilder) (string, error) {
|
||||||
if up.table == "" {
|
if up.table == "" {
|
||||||
|
@ -512,7 +533,15 @@ func (a *MysqlAdapter) SimpleUpdate(up *updatePrebuilder) (string, error) {
|
||||||
if up.set == "" {
|
if up.set == "" {
|
||||||
return "", errors.New("You need to set data in this update statement")
|
return "", errors.New("You need to set data in this update statement")
|
||||||
}
|
}
|
||||||
var sb strings.Builder
|
|
||||||
|
var sb *strings.Builder
|
||||||
|
ii := queryStrPool.Get()
|
||||||
|
if ii == nil {
|
||||||
|
sb = &strings.Builder{}
|
||||||
|
} else {
|
||||||
|
sb = ii.(*strings.Builder)
|
||||||
|
sb.Reset()
|
||||||
|
}
|
||||||
sb.Grow(sulen1 + len(up.table))
|
sb.Grow(sulen1 + len(up.table))
|
||||||
sb.WriteString("UPDATE `")
|
sb.WriteString("UPDATE `")
|
||||||
sb.WriteString(up.table)
|
sb.WriteString(up.table)
|
||||||
|
@ -545,18 +574,20 @@ func (a *MysqlAdapter) SimpleUpdate(up *updatePrebuilder) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
whereStr, err := a.buildFlexiWhere(up.where, up.dateCutoff)
|
err := a.buildFlexiWhereSb(sb, up.where, up.dateCutoff)
|
||||||
sb.WriteString(whereStr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sb.String(), err
|
return sb.String(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Shunt the table name logic and associated stmt list up to the a higher layer to reduce the amount of unnecessary overhead in the builder / accumulator
|
// TODO: Shunt the table name logic and associated stmt list up to the a higher layer to reduce the amount of unnecessary overhead in the builder / accumulator
|
||||||
q := sb.String()
|
q := sb.String()
|
||||||
|
queryStrPool.Put(sb)
|
||||||
a.pushStatement(up.name, "update", q)
|
a.pushStatement(up.name, "update", q)
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sdlen1 = len("DELETE FROM `` WHERE")
|
||||||
|
|
||||||
func (a *MysqlAdapter) SimpleDelete(name, table, where string) (string, error) {
|
func (a *MysqlAdapter) SimpleDelete(name, table, where string) (string, error) {
|
||||||
if table == "" {
|
if table == "" {
|
||||||
return "", errors.New("You need a name for this table")
|
return "", errors.New("You need a name for this table")
|
||||||
|
@ -564,31 +595,52 @@ func (a *MysqlAdapter) SimpleDelete(name, table, where string) (string, error) {
|
||||||
if where == "" {
|
if where == "" {
|
||||||
return "", errors.New("You need to specify what data you want to delete")
|
return "", errors.New("You need to specify what data you want to delete")
|
||||||
}
|
}
|
||||||
q := "DELETE FROM `" + table + "` WHERE"
|
var sb *strings.Builder
|
||||||
|
ii := queryStrPool.Get()
|
||||||
|
if ii == nil {
|
||||||
|
sb = &strings.Builder{}
|
||||||
|
} else {
|
||||||
|
sb = ii.(*strings.Builder)
|
||||||
|
sb.Reset()
|
||||||
|
}
|
||||||
|
sb.Grow(sdlen1 + len(table))
|
||||||
|
sb.WriteString("DELETE FROM `")
|
||||||
|
sb.WriteString(table)
|
||||||
|
sb.WriteString("` WHERE")
|
||||||
|
|
||||||
// Add support for BETWEEN x.x
|
// Add support for BETWEEN x.x
|
||||||
for _, loc := range processWhere(where) {
|
for i, loc := range processWhere(where) {
|
||||||
|
if i != 0 {
|
||||||
|
sb.WriteString(" AND")
|
||||||
|
}
|
||||||
for _, token := range loc.Expr {
|
for _, token := range loc.Expr {
|
||||||
switch token.Type {
|
switch token.Type {
|
||||||
case TokenFunc, TokenOp, TokenNumber, TokenSub, TokenOr, TokenNot:
|
case TokenFunc, TokenOp, TokenNumber, TokenSub, TokenOr, TokenNot:
|
||||||
q += " " + token.Contents
|
sb.WriteRune(' ')
|
||||||
|
sb.WriteString(token.Contents)
|
||||||
case TokenColumn:
|
case TokenColumn:
|
||||||
q += " `" + token.Contents + "`"
|
sb.WriteString(" `")
|
||||||
|
sb.WriteString(token.Contents)
|
||||||
|
sb.WriteRune('`')
|
||||||
case TokenString:
|
case TokenString:
|
||||||
q += " '" + token.Contents + "'"
|
sb.WriteString(" '")
|
||||||
|
sb.WriteString(token.Contents)
|
||||||
|
sb.WriteRune('\'')
|
||||||
default:
|
default:
|
||||||
panic("This token doesn't exist o_o")
|
panic("This token doesn't exist o_o")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
q += " AND"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
q = strings.TrimSpace(q[0 : len(q)-4])
|
q := strings.TrimSpace(sb.String())
|
||||||
|
queryStrPool.Put(sb)
|
||||||
// TODO: Shunt the table name logic and associated stmt list up to the a higher layer to reduce the amount of unnecessary overhead in the builder / accumulator
|
// TODO: Shunt the table name logic and associated stmt list up to the a higher layer to reduce the amount of unnecessary overhead in the builder / accumulator
|
||||||
a.pushStatement(name, "delete", q)
|
a.pushStatement(name, "delete", q)
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cdlen1 = len("DELETE FROM ``")
|
||||||
|
|
||||||
func (a *MysqlAdapter) ComplexDelete(b *deletePrebuilder) (string, error) {
|
func (a *MysqlAdapter) ComplexDelete(b *deletePrebuilder) (string, error) {
|
||||||
if b.table == "" {
|
if b.table == "" {
|
||||||
return "", errors.New("You need a name for this table")
|
return "", errors.New("You need a name for this table")
|
||||||
|
@ -596,13 +648,25 @@ func (a *MysqlAdapter) ComplexDelete(b *deletePrebuilder) (string, error) {
|
||||||
if b.where == "" && b.dateCutoff == nil {
|
if b.where == "" && b.dateCutoff == nil {
|
||||||
return "", errors.New("You need to specify what data you want to delete")
|
return "", errors.New("You need to specify what data you want to delete")
|
||||||
}
|
}
|
||||||
q := "DELETE FROM `" + b.table + "`"
|
var sb *strings.Builder
|
||||||
|
ii := queryStrPool.Get()
|
||||||
whereStr, err := a.buildFlexiWhere(b.where, b.dateCutoff)
|
if ii == nil {
|
||||||
if err != nil {
|
sb = &strings.Builder{}
|
||||||
return q, err
|
} else {
|
||||||
|
sb = ii.(*strings.Builder)
|
||||||
|
sb.Reset()
|
||||||
}
|
}
|
||||||
q += whereStr
|
sb.Grow(cdlen1 + len(b.table))
|
||||||
|
sb.WriteString("DELETE FROM `")
|
||||||
|
sb.WriteString(b.table)
|
||||||
|
sb.WriteRune('`')
|
||||||
|
|
||||||
|
err := a.buildFlexiWhereSb(sb, b.where, b.dateCutoff)
|
||||||
|
if err != nil {
|
||||||
|
return sb.String(), err
|
||||||
|
}
|
||||||
|
q := sb.String()
|
||||||
|
queryStrPool.Put(sb)
|
||||||
|
|
||||||
// TODO: Shunt the table name logic and associated stmt list up to the a higher layer to reduce the amount of unnecessary overhead in the builder / accumulator
|
// TODO: Shunt the table name logic and associated stmt list up to the a higher layer to reduce the amount of unnecessary overhead in the builder / accumulator
|
||||||
a.pushStatement(b.name, "delete", q)
|
a.pushStatement(b.name, "delete", q)
|
||||||
|
@ -653,7 +717,7 @@ func (a *MysqlAdapter) buildWhere(where string, sb *strings.Builder) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The new version of buildWhere() currently only used in ComplexSelect for complex OO builder queries
|
// The new version of buildWhere() currently only used in ComplexSelect for complex OO builder queries
|
||||||
const FlexiHint1 = len(` < UTC_TIMESTAMP() - interval ? `)
|
const FlexiHint1 = len(` <UTC_TIMESTAMP()-interval ? `)
|
||||||
|
|
||||||
func (a *MysqlAdapter) buildFlexiWhere(where string, dateCutoff *dateCutoff) (q string, err error) {
|
func (a *MysqlAdapter) buildFlexiWhere(where string, dateCutoff *dateCutoff) (q string, err error) {
|
||||||
if len(where) == 0 && dateCutoff == nil {
|
if len(where) == 0 && dateCutoff == nil {
|
||||||
|
@ -668,16 +732,16 @@ func (a *MysqlAdapter) buildFlexiWhere(where string, dateCutoff *dateCutoff) (q
|
||||||
sb.WriteString(dateCutoff.Column)
|
sb.WriteString(dateCutoff.Column)
|
||||||
switch dateCutoff.Type {
|
switch dateCutoff.Type {
|
||||||
case 0:
|
case 0:
|
||||||
sb.WriteString(" BETWEEN (UTC_TIMESTAMP() - interval ")
|
sb.WriteString(" BETWEEN (UTC_TIMESTAMP()-interval ")
|
||||||
sb.WriteString(strconv.Itoa(dateCutoff.Quantity))
|
sb.WriteString(strconv.Itoa(dateCutoff.Quantity))
|
||||||
sb.WriteString(" ")
|
sb.WriteString(" ")
|
||||||
sb.WriteString(dateCutoff.Unit)
|
sb.WriteString(dateCutoff.Unit)
|
||||||
sb.WriteString(") AND UTC_TIMESTAMP()")
|
sb.WriteString(") AND UTC_TIMESTAMP()")
|
||||||
case 11:
|
case 11:
|
||||||
sb.WriteString(" < UTC_TIMESTAMP() - interval ? ")
|
sb.WriteString("<UTC_TIMESTAMP()-interval ? ")
|
||||||
sb.WriteString(dateCutoff.Unit)
|
sb.WriteString(dateCutoff.Unit)
|
||||||
default:
|
default:
|
||||||
sb.WriteString(" < UTC_TIMESTAMP() - interval ")
|
sb.WriteString("<UTC_TIMESTAMP()-interval ")
|
||||||
sb.WriteString(strconv.Itoa(dateCutoff.Quantity))
|
sb.WriteString(strconv.Itoa(dateCutoff.Quantity))
|
||||||
sb.WriteRune(' ')
|
sb.WriteRune(' ')
|
||||||
sb.WriteString(dateCutoff.Unit)
|
sb.WriteString(dateCutoff.Unit)
|
||||||
|
@ -717,6 +781,67 @@ func (a *MysqlAdapter) buildFlexiWhere(where string, dateCutoff *dateCutoff) (q
|
||||||
return sb.String(), nil
|
return sb.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *MysqlAdapter) buildFlexiWhereSb(sb *strings.Builder, where string, dateCutoff *dateCutoff) (err error) {
|
||||||
|
if len(where) == 0 && dateCutoff == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.WriteString(" WHERE")
|
||||||
|
if dateCutoff != nil {
|
||||||
|
sb.Grow(6 + FlexiHint1)
|
||||||
|
sb.WriteRune(' ')
|
||||||
|
sb.WriteString(dateCutoff.Column)
|
||||||
|
switch dateCutoff.Type {
|
||||||
|
case 0:
|
||||||
|
sb.WriteString(" BETWEEN (UTC_TIMESTAMP()-interval ")
|
||||||
|
sb.WriteString(strconv.Itoa(dateCutoff.Quantity))
|
||||||
|
sb.WriteString(" ")
|
||||||
|
sb.WriteString(dateCutoff.Unit)
|
||||||
|
sb.WriteString(") AND UTC_TIMESTAMP()")
|
||||||
|
case 11:
|
||||||
|
sb.WriteString(" < UTC_TIMESTAMP()-interval ? ")
|
||||||
|
sb.WriteString(dateCutoff.Unit)
|
||||||
|
default:
|
||||||
|
sb.WriteString(" < UTC_TIMESTAMP()-interval ")
|
||||||
|
sb.WriteString(strconv.Itoa(dateCutoff.Quantity))
|
||||||
|
sb.WriteRune(' ')
|
||||||
|
sb.WriteString(dateCutoff.Unit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dateCutoff != nil && len(where) != 0 {
|
||||||
|
sb.WriteString(" AND")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(where) != 0 {
|
||||||
|
wh := processWhere(where)
|
||||||
|
sb.Grow((len(wh) * 8) - 5)
|
||||||
|
for i, loc := range wh {
|
||||||
|
if i != 0 {
|
||||||
|
sb.WriteString(" AND ")
|
||||||
|
}
|
||||||
|
for _, token := range loc.Expr {
|
||||||
|
switch token.Type {
|
||||||
|
case TokenFunc, TokenOp, TokenNumber, TokenSub, TokenOr, TokenNot, TokenLike:
|
||||||
|
sb.WriteString(" ")
|
||||||
|
sb.WriteString(token.Contents)
|
||||||
|
case TokenColumn:
|
||||||
|
sb.WriteString(" `")
|
||||||
|
sb.WriteString(token.Contents)
|
||||||
|
sb.WriteString("`")
|
||||||
|
case TokenString:
|
||||||
|
sb.WriteString(" '")
|
||||||
|
sb.WriteString(token.Contents)
|
||||||
|
sb.WriteString("'")
|
||||||
|
default:
|
||||||
|
return errors.New("This token doesn't exist o_o")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *MysqlAdapter) buildOrderby(orderby string) (q string) {
|
func (a *MysqlAdapter) buildOrderby(orderby string) (q string) {
|
||||||
if len(orderby) != 0 {
|
if len(orderby) != 0 {
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
|
@ -739,43 +864,67 @@ func (a *MysqlAdapter) buildOrderby(orderby string) (q string) {
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *MysqlAdapter) SimpleSelect(name, table, columns, where, orderby, limit string) (string, error) {
|
func (a *MysqlAdapter) SimpleSelect(name, table, cols, where, orderby, limit string) (string, error) {
|
||||||
if table == "" {
|
if table == "" {
|
||||||
return "", errors.New("You need a name for this table")
|
return "", errors.New("You need a name for this table")
|
||||||
}
|
}
|
||||||
if len(columns) == 0 {
|
if len(cols) == 0 {
|
||||||
return "", errors.New("No columns found for SimpleSelect")
|
return "", errors.New("No columns found for SimpleSelect")
|
||||||
}
|
}
|
||||||
q := "SELECT "
|
var sb *strings.Builder
|
||||||
|
ii := queryStrPool.Get()
|
||||||
|
if ii == nil {
|
||||||
|
sb = &strings.Builder{}
|
||||||
|
} else {
|
||||||
|
sb = ii.(*strings.Builder)
|
||||||
|
sb.Reset()
|
||||||
|
}
|
||||||
|
sb.WriteString("SELECT ")
|
||||||
|
|
||||||
// Slice up the user friendly strings into something easier to process
|
// Slice up the user friendly strings into something easier to process
|
||||||
for _, column := range strings.Split(strings.TrimSpace(columns), ",") {
|
for i, col := range strings.Split(strings.TrimSpace(cols), ",") {
|
||||||
q += "`" + strings.TrimSpace(column) + "`,"
|
if i != 0 {
|
||||||
|
sb.WriteString("`,`")
|
||||||
|
} else {
|
||||||
|
sb.WriteRune('`')
|
||||||
|
}
|
||||||
|
sb.WriteString(strings.TrimSpace(col))
|
||||||
}
|
}
|
||||||
q = q[0 : len(q)-1]
|
|
||||||
|
|
||||||
sb := &strings.Builder{}
|
sb.WriteString("` FROM `")
|
||||||
|
sb.WriteString(table)
|
||||||
|
sb.WriteRune('`')
|
||||||
err := a.buildWhere(where, sb)
|
err := a.buildWhere(where, sb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
q += " FROM `" + table + "`" + sb.String() + a.buildOrderby(orderby) + a.buildLimit(limit)
|
sb.WriteString(a.buildOrderby(orderby))
|
||||||
|
sb.WriteString(a.buildLimit(limit))
|
||||||
|
|
||||||
q = strings.TrimSpace(q)
|
q := strings.TrimSpace(sb.String())
|
||||||
|
queryStrPool.Put(sb)
|
||||||
a.pushStatement(name, "select", q)
|
a.pushStatement(name, "select", q)
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *MysqlAdapter) ComplexSelect(preBuilder *selectPrebuilder) (out string, err error) {
|
func (a *MysqlAdapter) ComplexSelect(preBuilder *selectPrebuilder) (out string, err error) {
|
||||||
sb := &strings.Builder{}
|
var sb *strings.Builder
|
||||||
|
ii := queryStrPool.Get()
|
||||||
|
if ii == nil {
|
||||||
|
sb = &strings.Builder{}
|
||||||
|
} else {
|
||||||
|
sb = ii.(*strings.Builder)
|
||||||
|
sb.Reset()
|
||||||
|
}
|
||||||
err = a.complexSelect(preBuilder, sb)
|
err = a.complexSelect(preBuilder, sb)
|
||||||
out = sb.String()
|
out = sb.String()
|
||||||
|
queryStrPool.Put(sb)
|
||||||
a.pushStatement(preBuilder.name, "select", out)
|
a.pushStatement(preBuilder.name, "select", out)
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var cslen1 = len("SELECT FROM ``")
|
const cslen1 = len("SELECT FROM ``")
|
||||||
var cslen2 = len(" WHERE `` IN(")
|
const cslen2 = len(" WHERE `` IN(")
|
||||||
|
|
||||||
func (a *MysqlAdapter) complexSelect(preBuilder *selectPrebuilder, sb *strings.Builder) error {
|
func (a *MysqlAdapter) complexSelect(preBuilder *selectPrebuilder, sb *strings.Builder) error {
|
||||||
if preBuilder.table == "" {
|
if preBuilder.table == "" {
|
||||||
|
@ -805,11 +954,10 @@ func (a *MysqlAdapter) complexSelect(preBuilder *selectPrebuilder, sb *strings.B
|
||||||
}
|
}
|
||||||
sb.WriteRune(')')
|
sb.WriteRune(')')
|
||||||
} else {
|
} else {
|
||||||
whereStr, err := a.buildFlexiWhere(preBuilder.where, preBuilder.dateCutoff)
|
err := a.buildFlexiWhereSb(sb, preBuilder.where, preBuilder.dateCutoff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sb.WriteString(whereStr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
orderby := a.buildOrderby(preBuilder.orderby)
|
orderby := a.buildOrderby(preBuilder.orderby)
|
||||||
|
@ -1038,18 +1186,32 @@ func (a *MysqlAdapter) SimpleInsertInnerJoin(name string, ins DBInsert, sel DBJo
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sclen1 = len("SELECT COUNT(*) FROM ``")
|
||||||
|
|
||||||
func (a *MysqlAdapter) SimpleCount(name, table, where, limit string) (q string, err error) {
|
func (a *MysqlAdapter) SimpleCount(name, table, where, limit string) (q string, err error) {
|
||||||
if table == "" {
|
if table == "" {
|
||||||
return "", errors.New("You need a name for this table")
|
return "", errors.New("You need a name for this table")
|
||||||
}
|
}
|
||||||
sb := &strings.Builder{}
|
var sb *strings.Builder
|
||||||
|
ii := queryStrPool.Get()
|
||||||
|
if ii == nil {
|
||||||
|
sb = &strings.Builder{}
|
||||||
|
} else {
|
||||||
|
sb = ii.(*strings.Builder)
|
||||||
|
sb.Reset()
|
||||||
|
}
|
||||||
|
sb.Grow(sclen1 + len(table))
|
||||||
|
sb.WriteString("SELECT COUNT(*) FROM `")
|
||||||
|
sb.WriteString(table)
|
||||||
|
sb.WriteRune('`')
|
||||||
err = a.buildWhere(where, sb)
|
err = a.buildWhere(where, sb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
sb.WriteString(a.buildLimit(limit))
|
||||||
|
|
||||||
q = "SELECT COUNT(*) FROM `" + table + "`" + sb.String() + a.buildLimit(limit)
|
q = strings.TrimSpace(sb.String())
|
||||||
q = strings.TrimSpace(q)
|
queryStrPool.Put(sb)
|
||||||
a.pushStatement(name, "select", q)
|
a.pushStatement(name, "select", q)
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
@ -1070,7 +1232,7 @@ func (a *MysqlAdapter) Write() error {
|
||||||
stmts += "\t" + name + " *qgen.MySQLUpsertCallback\n"
|
stmts += "\t" + name + " *qgen.MySQLUpsertCallback\n"
|
||||||
body += `
|
body += `
|
||||||
common.DebugLog("Preparing ` + name + ` statement.")
|
common.DebugLog("Preparing ` + name + ` statement.")
|
||||||
stmts.` + name + `, err = qgen.PrepareMySQLUpsertCallback(db, "` + stmt.Contents + `")
|
stmts.` + name + `, err = qgen.PrepareMySQLUpsertCallback(db,"` + stmt.Contents + `")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print("Error in ` + name + ` statement.")
|
log.Print("Error in ` + name + ` statement.")
|
||||||
return err
|
return err
|
||||||
|
@ -1105,6 +1267,7 @@ import "github.com/Azareal/Gosora/common"
|
||||||
type Stmts struct {
|
type Stmts struct {
|
||||||
` + stmts + `
|
` + stmts + `
|
||||||
getActivityFeedByWatcher *sql.Stmt
|
getActivityFeedByWatcher *sql.Stmt
|
||||||
|
//getActivityFeedByWatcherAfter *sql.Stmt
|
||||||
getActivityCountByWatcher *sql.Stmt
|
getActivityCountByWatcher *sql.Stmt
|
||||||
|
|
||||||
Mocks bool
|
Mocks bool
|
||||||
|
|
|
@ -6,10 +6,12 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Registry []Adapter
|
var Registry []Adapter
|
||||||
var ErrNoAdapter = errors.New("This adapter doesn't exist")
|
var ErrNoAdapter = errors.New("This adapter doesn't exist")
|
||||||
|
var queryStrPool = sync.Pool{}
|
||||||
|
|
||||||
type DBTableColumn struct {
|
type DBTableColumn struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
Loading…
Reference in New Issue