Initial Commit

This commit is contained in:
Mario Steele 2026-02-23 18:38:03 -06:00
commit 48a5e71e00
1136 changed files with 64347 additions and 0 deletions

View file

@ -0,0 +1,196 @@
@tool
extends RefCounted
class_name Condition
## A programatically way to define Conditions.
##
## Condition is a way to define SQL Statements to be used with GDataORM. You can create
## full SQL Statements, or Simple conditions to be used when fetching data from the [SQLite]
## database.[br][br]
##
## [b]Example:[/b]
## [codeblock]
## var fetch_like_mar: Condition = Condition.new().select("*").from("my_table").where() \
## .like("name", "Mar%")
## var fetch_gold: Condition = Condition.new().select(["gold"]).from("inventories").where() \
## .greater("gold",0)
## var low_health: Condition = Condition.new().lesser("health",5)
## var mid_health: Condition = Condition.new().between("health",25,75)
## var full_health: Condition = Condition.new().greater_equal("health",100)
## [/codeblock]
enum _CT {
NOT,
EQUAL,
LESS_THAN,
GREATER_THAN,
LESS_THAN_EQUAL,
GREATER_THAN_EQUAL,
AND,
BETWEEN,
IN,
LIKE,
OR,
SELECT,
FROM,
WHERE,
}
var _conditions: Array = []
func _single_op(op: _CT) -> Dictionary:
return {"type": op}
func _param_op(op: _CT, param: Variant) -> Dictionary:
return {"type": op, "param": param}
func _comparison_op(op: _CT, column: Variant, value: Variant) -> Dictionary:
return {"type": op, "column": column, "value": value}
## Binary operator to invert true and false in a statement.
func is_not() -> Condition:
_conditions.append(_single_op(_CT.NOT))
return self
## Evaluates the equality of a [param column] value and the [param value] given.
func equal(column: String, value: Variant) -> Condition:
_conditions.append(_comparison_op(_CT.EQUAL, column, value))
return self
## Evaluates the [param column] value to be lesser than [param value] given.
func lesser(column: String, value: Variant) -> Condition:
_conditions.append(_comparison_op(_CT.LESS_THAN, column, value))
return self
## Evaluates the [param column] value to be greater than [param value] given.
func greater(column: String, value: Variant) -> Condition:
_conditions.append(_comparison_op(_CT.GREATER_THAN, column, value))
return self
## Evaluates the [param column] value to be lesser than or equal to [param value] given.
func lesser_equal(column: String, value: Variant) -> Condition:
_conditions.append(_comparison_op(_CT.LESS_THAN_EQUAL, column, value))
return self
## Evaluates the [param column] value to be greater than or equal to [param value] given.
func greater_equal(column: String, value: Variant) -> Condition:
_conditions.append(_comparison_op(_CT.GREATER_THAN_EQUAL, column, value))
return self
## Binary operator for AND'ing two evaluation values together.
func also() -> Condition:
_conditions.append(_single_op(_CT.AND))
return self
## Evaluates the [param column] value to be between [param lower]'s value and [param upper]'s value.
func between(column: String, lower: Variant, upper: Variant) -> Condition:
_conditions.append(_comparison_op(_CT.BETWEEN, column, [lower, upper]))
return self
## Evaluates the [param column] to see if [param value] is included in it. You can pass an array
## of values to this, or use a [Condition] to fetch data from another table.
func includes(column: String, value: Variant) -> Condition:
_conditions.append(_comparison_op(_CT.IN, column, value))
return self
## Evaluates the [param column] to see if [param value] matches the given string. This utilizes
## [SQLite]'s LIKE statement, which means that you can use wildcard operators '%' and '_' in the
## pattern string.[br][br]
## [b]Wildcard Patterns:[/b][br]
## - '%' match any 1 or more characters in a pattern, EG: "Mar%" will return "Mario", "Mark", "Margin" etc etc.[br]
## - '_' match only 1 wildcard character before moving to the next. EG: "h_nt" will return "hunt", "hint", or
## "__pple" will return "topple", "supple", "tipple"[br]
## [b][color=red]NOTE:[/color][/b] [SQLite]'s engine is case-insensitive, so [code]"A" LIKE "a"[/code] will return true, but
## unicode characters that are not in the ASCII range are case-sensitive, so [code]"Ä" LIKE "ä"[/code] will return false.
func like(column: String, value: Variant) -> Condition:
_conditions.append(_comparison_op(_CT.LIKE, column, value))
return self
## Binary operator for OR'ing two evaluations together.
func otherwise() -> Condition:
_conditions.append(_single_op(_CT.OR))
return self
## Statement, fetches [param columns] from a table during execution. [param columns] can be a string value of "*" or "column1, column2, column3" or an
## array of strings such as ["column1","column2","column3"].
func select(columns: Variant) -> Condition:
_conditions.append(_param_op(_CT.SELECT, columns))
return self
## Statement Modifier, used in conjunction with [method Condition.select] to define which table the data is to be fetched from.
func from(table: String) -> Condition:
_conditions.append(_param_op(_CT.FROM, table))
return self
## Statement Modifier, defines the conditions that must match in order to fetch data from the table.
func where() -> Condition:
_conditions.append(_single_op(_CT.WHERE))
return self
func _to_string() -> String:
var str = ""
var pos := 0
for cond in _conditions:
match cond.type:
#NOTE Single Operation _single_op()
_CT.NOT:
if _conditions[pos+1].type == _CT.BETWEEN:
pos += 1
continue
str += "NOT "
_CT.AND:
str += "AND "
_CT.OR:
str += "OR "
_CT.WHERE:
str += "WHERE "
#NOTE Param Operation _param_op()
_CT.SELECT:
var param = ""
if cond.param is Array:
param = ", ".join(cond.param)
elif cond.param is String:
param = cond.param
else:
assert(false, "SELECT statement only takes a String or Array parameters.")
str += "SELECT %s " % param
_CT.FROM:
str += "FROM %s " % cond.param
#NOTE Comparison Operation _comparison_op()
_CT.EQUAL:
if typeof(cond.value) == TYPE_STRING:
str += "%s = '%s'" % [cond.column, cond.value]
else:
str += "%s = %s " % [cond.column, cond.value]
_CT.LESS_THAN:
str += "%s < %s " % [cond.column, cond.value]
_CT.GREATER_THAN:
str += "%s > %s " % [cond.column, cond.value]
_CT.LESS_THAN_EQUAL:
str += "%s <= %s " % [cond.column, cond.value]
_CT.GREATER_THAN_EQUAL:
str += "%s >= %s " % [cond.column, cond.value]
_CT.BETWEEN:
if _conditions[pos-1].type == _CT.NOT:
str += "%s NOT BETWEEN " % cond.column
else:
str += "%s BETWEEN " % cond.column
str += "%s and %s" % cond.value
_CT.IN:
if _conditions[pos-1].type == _CT.NOT:
str += "%s NOT IN " % cond.column
else:
str += "%s IN " % cond.column
if cond.value is Condition:
str += "(%s) " % cond.value.to_string()
elif cond.value is Array:
str += "(%s) " % ", ".join(cond.value)
else:
assert(false, "IN only takes Array of values or a Condition")
_CT.LIKE:
str += "%s LIKE '%s' " % [cond.column, cond.value]
pos += 1
return str.strip_edges()