github.com/RevenueMonster/sqlike@v1.0.6/sql/select.go (about)

     1  package sql
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/RevenueMonster/sqlike/reflext"
     7  	"github.com/RevenueMonster/sqlike/sql/expr"
     8  	"github.com/RevenueMonster/sqlike/sqlike/primitive"
     9  )
    10  
    11  // SelectStmt :
    12  type SelectStmt struct {
    13  	DistinctOn  bool
    14  	Tables      []interface{}
    15  	Projections []interface{}
    16  	Joins       []interface{}
    17  	IndexHints  string
    18  	Conditions  primitive.Group
    19  	Havings     primitive.Group
    20  	Groups      []interface{}
    21  	Sorts       []interface{}
    22  	Max         uint
    23  	Skip        uint
    24  }
    25  
    26  // Select :
    27  func Select(fields ...interface{}) *SelectStmt {
    28  	stmt := new(SelectStmt)
    29  	return stmt.Select(fields...)
    30  }
    31  
    32  // Select :
    33  func (stmt *SelectStmt) Select(fields ...interface{}) *SelectStmt {
    34  	if len(fields) == 1 {
    35  		switch fields[0].(type) {
    36  		case primitive.As, *SelectStmt:
    37  			grp := primitive.Group{}
    38  			grp.Values = append(grp.Values, primitive.Raw{Value: "("})
    39  			grp.Values = append(grp.Values, fields...)
    40  			grp.Values = append(grp.Values, primitive.Raw{Value: ")"})
    41  			stmt.Projections = append(stmt.Projections, grp)
    42  		default:
    43  			stmt.Projections = append(stmt.Projections, fields...)
    44  		}
    45  		return stmt
    46  	}
    47  	stmt.Projections = fields
    48  	return stmt
    49  }
    50  
    51  // From :
    52  func (stmt *SelectStmt) From(values ...interface{}) *SelectStmt {
    53  	length := len(values)
    54  	if length == 0 {
    55  		panic("empty table name")
    56  	}
    57  	switch length {
    58  	case 1:
    59  		stmt.Tables = append(stmt.Tables, values[0])
    60  	case 2:
    61  		stmt.Tables = append(stmt.Tables,
    62  			primitive.Column{
    63  				Table: mustString(values[0]),
    64  				Name:  mustString(values[1]),
    65  			},
    66  		)
    67  	case 3:
    68  		stmt.Tables = append(stmt.Tables,
    69  			primitive.Column{
    70  				Table: mustString(values[0]),
    71  				Name:  mustString(values[1]),
    72  			},
    73  			values[2],
    74  		)
    75  	default:
    76  		panic("invalid length of arguments")
    77  	}
    78  	return stmt
    79  }
    80  
    81  // Distinct :
    82  func (stmt *SelectStmt) Distinct() *SelectStmt {
    83  	stmt.DistinctOn = true
    84  	return stmt
    85  }
    86  
    87  // Where :
    88  func (stmt *SelectStmt) Where(fields ...interface{}) *SelectStmt {
    89  	stmt.Conditions = expr.And(fields...)
    90  	return stmt
    91  }
    92  
    93  // Having :
    94  func (stmt *SelectStmt) Having(fields ...interface{}) *SelectStmt {
    95  	stmt.Havings = expr.And(fields...)
    96  	return stmt
    97  }
    98  
    99  // OrderBy :
   100  func (stmt *SelectStmt) OrderBy(fields ...interface{}) *SelectStmt {
   101  	stmt.Sorts = fields
   102  	return stmt
   103  }
   104  
   105  // GroupBy :
   106  func (stmt *SelectStmt) GroupBy(fields ...interface{}) *SelectStmt {
   107  	stmt.Groups = fields
   108  	return stmt
   109  }
   110  
   111  // Limit :
   112  func (stmt *SelectStmt) Limit(num uint) *SelectStmt {
   113  	if num > 0 {
   114  		stmt.Max = num
   115  	}
   116  	return stmt
   117  }
   118  
   119  // Offset :
   120  func (stmt *SelectStmt) Offset(num uint) *SelectStmt {
   121  	if num > 0 {
   122  		stmt.Skip = num
   123  	}
   124  	return stmt
   125  }
   126  
   127  func mustString(it interface{}) string {
   128  	v := reflext.Indirect(reflext.ValueOf(it))
   129  	if v.Kind() != reflect.String {
   130  		panic("unsupported data type")
   131  	}
   132  	return v.String()
   133  }