github.com/acoshift/pgsql@v0.15.3/pgstmt/cond.go (about)

     1  package pgstmt
     2  
     3  // Cond is the condition builder
     4  type Cond interface {
     5  	Op(field any, op string, value any)
     6  	OpRaw(field any, op string, rawValue any)
     7  	Eq(field, value any)
     8  	EqRaw(field, rawValue any)
     9  	Ne(field, value any)
    10  	NeRaw(field, rawValue any)
    11  	Lt(field, value any)
    12  	LtRaw(field, rawValue any)
    13  	Le(field, value any)
    14  	LeRaw(field, rawValue any)
    15  	Gt(field, value any)
    16  	GtRaw(field, rawValue any)
    17  	Ge(field, value any)
    18  	GeRaw(field, rawValue any)
    19  	Like(field, value any)
    20  	LikeRaw(field, rawValue any)
    21  	ILike(field, value any)
    22  	ILikeRaw(field, rawValue any)
    23  	In(field any, value ...any)
    24  	InRaw(field any, value ...any)
    25  	InSelect(field any, f func(b SelectStatement))
    26  	NotIn(field any, value ...any)
    27  	NotInRaw(field any, value ...any)
    28  	IsNull(field any)
    29  	IsNotNull(field any)
    30  
    31  	Field(field any) CondOp
    32  	Value(value any) CondOp
    33  
    34  	Raw(sql string)
    35  	Not(f func(b Cond))
    36  	And(f func(b Cond))
    37  	Or(f func(b Cond))
    38  	Mode() CondMode
    39  }
    40  
    41  type CondMode interface {
    42  	And()
    43  	Or()
    44  }
    45  
    46  type CondOp interface {
    47  	Op(op string) CondValue
    48  	OpValues(op string) CondValues
    49  	Eq() CondValue
    50  	Ne() CondValue
    51  	Lt() CondValue
    52  	Le() CondValue
    53  	Gt() CondValue
    54  	Ge() CondValue
    55  	Like() CondValue
    56  	ILike() CondValue
    57  	In() CondValues
    58  	NotIn() CondValues
    59  	IsNull()
    60  	IsNotNull()
    61  }
    62  
    63  type CondValue interface {
    64  	Value(value any)
    65  	Raw(rawValue any)
    66  	Field(field any)
    67  }
    68  
    69  type CondValues interface {
    70  	Value(values ...any)
    71  	Raw(rawValues ...any)
    72  	Field(field any)
    73  	Select(f func(b SelectStatement))
    74  }
    75  
    76  type cond struct {
    77  	ops    parenGroup
    78  	chain  buffer
    79  	nested bool
    80  }
    81  
    82  func (st *cond) Op(field any, op string, value any) {
    83  	var x group
    84  	x.sep = " "
    85  	x.push(field, op, Arg(value))
    86  	st.ops.push(&x)
    87  }
    88  
    89  func (st *cond) OpRaw(field any, op string, rawValue any) {
    90  	var x group
    91  	x.sep = " "
    92  	x.push(field, op, Raw(rawValue))
    93  	st.ops.push(&x)
    94  }
    95  
    96  func (st *cond) Eq(field, value any) {
    97  	st.Op(field, "=", value)
    98  }
    99  
   100  func (st *cond) EqRaw(field, rawValue any) {
   101  	st.OpRaw(field, "=", rawValue)
   102  }
   103  
   104  func (st *cond) Ne(field, value any) {
   105  	st.Op(field, "!=", value)
   106  }
   107  
   108  func (st *cond) NeRaw(field, rawValue any) {
   109  	st.OpRaw(field, "!=", rawValue)
   110  }
   111  
   112  func (st *cond) Lt(field, value any) {
   113  	st.Op(field, "<", value)
   114  }
   115  
   116  func (st *cond) LtRaw(field, rawValue any) {
   117  	st.OpRaw(field, "<", rawValue)
   118  }
   119  
   120  func (st *cond) Le(field, value any) {
   121  	st.Op(field, "<=", value)
   122  }
   123  
   124  func (st *cond) LeRaw(field, rawValue any) {
   125  	st.OpRaw(field, "<=", rawValue)
   126  }
   127  
   128  func (st *cond) Gt(field, value any) {
   129  	st.Op(field, ">", value)
   130  }
   131  
   132  func (st *cond) GtRaw(field, rawValue any) {
   133  	st.OpRaw(field, ">", rawValue)
   134  }
   135  
   136  func (st *cond) Ge(field, value any) {
   137  	st.Op(field, ">=", value)
   138  }
   139  
   140  func (st *cond) GeRaw(field, rawValue any) {
   141  	st.OpRaw(field, ">=", rawValue)
   142  }
   143  
   144  func (st *cond) Like(field, value any) {
   145  	st.Op(field, "like", value)
   146  }
   147  
   148  func (st *cond) LikeRaw(field, rawValue any) {
   149  	st.OpRaw(field, "like", rawValue)
   150  }
   151  
   152  func (st *cond) ILike(field, value any) {
   153  	st.Op(field, "ilike", value)
   154  }
   155  
   156  func (st *cond) ILikeRaw(field, rawValue any) {
   157  	st.OpRaw(field, "ilike", rawValue)
   158  }
   159  
   160  func (st *cond) In(field any, value ...any) {
   161  	var p group
   162  	for _, v := range value {
   163  		p.push(Arg(v))
   164  	}
   165  
   166  	var x group
   167  	x.sep = " "
   168  	x.push(field, "in", paren(&p))
   169  	st.ops.push(&x)
   170  }
   171  
   172  func (st *cond) InRaw(field any, value ...any) {
   173  	var p group
   174  	p.push(value...)
   175  
   176  	var x group
   177  	x.sep = " "
   178  	x.push(field, "in", paren(&p))
   179  	st.ops.push(&x)
   180  }
   181  
   182  func (st *cond) InSelect(field any, f func(b SelectStatement)) {
   183  	var x selectStmt
   184  	f(&x)
   185  
   186  	var p group
   187  	p.sep = " "
   188  	p.push(field, "in", paren(x.make()))
   189  	st.ops.push(&p)
   190  }
   191  
   192  func (st *cond) NotIn(field any, value ...any) {
   193  	var p group
   194  	for _, v := range value {
   195  		p.push(Arg(v))
   196  	}
   197  
   198  	var x group
   199  	x.sep = " "
   200  	x.push(field, "not in", paren(&p))
   201  	st.ops.push(&x)
   202  }
   203  
   204  func (st *cond) NotInRaw(field any, value ...any) {
   205  	var p group
   206  	p.push(value...)
   207  
   208  	var x group
   209  	x.sep = " "
   210  	x.push(field, "not in", paren(&p))
   211  	st.ops.push(&x)
   212  }
   213  
   214  func (st *cond) IsNull(field any) {
   215  	var x group
   216  	x.sep = " "
   217  	x.push(field, "is null")
   218  	st.ops.push(&x)
   219  }
   220  
   221  func (st *cond) IsNotNull(field any) {
   222  	var x group
   223  	x.sep = " "
   224  	x.push(field, "is not null")
   225  	st.ops.push(&x)
   226  }
   227  
   228  func (st *cond) Field(field any) CondOp {
   229  	var x condOp
   230  	x.field = field
   231  	st.ops.push(&x)
   232  	return &x
   233  }
   234  
   235  func (st *cond) Value(value any) CondOp {
   236  	var x condOp
   237  	x.field = Arg(value)
   238  	st.ops.push(&x)
   239  	return &x
   240  }
   241  
   242  func (st *cond) Raw(sql string) {
   243  	st.ops.push(sql)
   244  }
   245  
   246  func (st *cond) Not(b func(b Cond)) {
   247  	var x cond
   248  	x.ops.sep = " and "
   249  	x.nested = true
   250  	b(&x)
   251  
   252  	if !x.empty() {
   253  		st.ops.push(withParen(" ", "not", &x))
   254  	}
   255  }
   256  
   257  func (st *cond) And(f func(b Cond)) {
   258  	var x cond
   259  	x.ops.sep = " and "
   260  	x.nested = true
   261  	f(&x)
   262  
   263  	if !x.empty() {
   264  		st.chain.push("and")
   265  		st.chain.push(&x)
   266  	}
   267  }
   268  
   269  func (st *cond) Or(f func(b Cond)) {
   270  	var x cond
   271  	x.ops.sep = " and "
   272  	x.nested = true
   273  	f(&x)
   274  
   275  	if !x.empty() {
   276  		st.chain.push("or")
   277  		st.chain.push(&x)
   278  	}
   279  }
   280  
   281  func (st *cond) Mode() CondMode {
   282  	return &condMode{st}
   283  }
   284  
   285  func (st *cond) empty() bool {
   286  	return st.ops.empty() && st.chain.empty()
   287  }
   288  
   289  func (st *cond) build() []any {
   290  	if st.empty() {
   291  		return nil
   292  	}
   293  
   294  	if st.ops.empty() {
   295  		st.chain.popFront()
   296  
   297  		if len(st.chain.q) > 1 {
   298  			var b parenGroup
   299  			b.sep = " "
   300  			b.push(st.chain.q...)
   301  			return []any{&b}
   302  		}
   303  
   304  		return st.chain.q
   305  	}
   306  
   307  	if st.ops.sep == "" {
   308  		st.ops.sep = " and "
   309  	}
   310  
   311  	if st.nested && !st.chain.empty() {
   312  		var b parenGroup
   313  		b.sep = " "
   314  		b.push(&st.ops)
   315  		b.push(st.chain.q...)
   316  		return []any{&b}
   317  	}
   318  
   319  	var b buffer
   320  	b.push(&st.ops)
   321  	b.push(st.chain.q...)
   322  	return b.q
   323  }
   324  
   325  type condMode struct {
   326  	cond *cond
   327  }
   328  
   329  func (mode *condMode) And() {
   330  	mode.cond.ops.sep = " and "
   331  }
   332  
   333  func (mode *condMode) Or() {
   334  	mode.cond.ops.sep = " or "
   335  }
   336  
   337  type condOp struct {
   338  	field  any
   339  	op     string
   340  	value  *condValue
   341  	values *condValues
   342  }
   343  
   344  func (op *condOp) build() []any {
   345  	var b buffer
   346  
   347  	var x group
   348  	x.sep = " "
   349  	x.push(op.field, op.op)
   350  	if op.value != nil {
   351  		x.push(op.value.value)
   352  	} else if op.values != nil {
   353  		x.push(&op.values.b)
   354  	}
   355  
   356  	b.push(&x)
   357  
   358  	return b.build()
   359  }
   360  
   361  func (op *condOp) Op(s string) CondValue {
   362  	op.op = s
   363  	op.value = &condValue{}
   364  	return op.value
   365  }
   366  
   367  func (op *condOp) OpValues(s string) CondValues {
   368  	op.op = s
   369  	op.values = &condValues{}
   370  	return op.values
   371  }
   372  
   373  func (op *condOp) Eq() CondValue {
   374  	return op.Op("=")
   375  }
   376  
   377  func (op *condOp) Ne() CondValue {
   378  	return op.Op("!=")
   379  }
   380  
   381  func (op *condOp) Lt() CondValue {
   382  	return op.Op("<")
   383  }
   384  
   385  func (op *condOp) Le() CondValue {
   386  	return op.Op("<=")
   387  }
   388  
   389  func (op *condOp) Gt() CondValue {
   390  	return op.Op(">")
   391  }
   392  
   393  func (op *condOp) Ge() CondValue {
   394  	return op.Op(">=")
   395  }
   396  
   397  func (op *condOp) Like() CondValue {
   398  	return op.Op("like")
   399  }
   400  
   401  func (op *condOp) ILike() CondValue {
   402  	return op.Op("ilike")
   403  }
   404  
   405  func (op *condOp) In() CondValues {
   406  	return op.OpValues("in")
   407  }
   408  
   409  func (op *condOp) NotIn() CondValues {
   410  	return op.OpValues("not in")
   411  }
   412  
   413  func (op *condOp) IsNull() {
   414  	op.op = "is null"
   415  }
   416  
   417  func (op *condOp) IsNotNull() {
   418  	op.op = "is not null"
   419  }
   420  
   421  type condValue struct {
   422  	value any
   423  }
   424  
   425  func (v *condValue) make() *buffer {
   426  	var b buffer
   427  	b.push(v.value)
   428  	return &b
   429  }
   430  
   431  func (v *condValue) Value(value any) {
   432  	v.value = Arg(value)
   433  }
   434  
   435  func (v *condValue) Raw(rawValue any) {
   436  	v.value = Raw(rawValue)
   437  }
   438  
   439  func (v *condValue) Field(field any) {
   440  	v.value = Raw(field)
   441  }
   442  
   443  type condValues struct {
   444  	b buffer
   445  }
   446  
   447  func (v *condValues) Value(value ...any) {
   448  	var p group
   449  	for _, x := range value {
   450  		p.push(Arg(x))
   451  	}
   452  	v.b.push(paren(&p))
   453  }
   454  
   455  func (v *condValues) Raw(rawValue ...any) {
   456  	var p group
   457  	p.push(rawValue...)
   458  	v.b.push(paren(&p))
   459  }
   460  
   461  func (v *condValues) Field(field any) {
   462  	v.b.push(Raw(field))
   463  }
   464  
   465  func (v *condValues) Select(f func(b SelectStatement)) {
   466  	var x selectStmt
   467  	f(&x)
   468  
   469  	v.b.push(paren(x.make()))
   470  }