DB
object
%DB
/phlo/resources/DB/DB.phlo
prop
%DB -> PDO
line 11
This function triggers an error if no PDO connector is defined for database operations.
error('No PDO connector defined')prop
%DB -> fieldQuotes
line 12
Retrieves the field quotes for a specified database field, allowing for the correct formatting of SQL queries.
btprop
%DB -> savepoint
line 13
Creates a savepoint in the current database transaction, allowing for partial rollbacks.
prop
%DB -> insertIgnore
line 14
Inserts a new record into the database while ignoring any duplicate entries that would cause a conflict.
' IGNORE'prop
%DB -> insertOnConflict
line 15
Inserts a new record into the database, and in case of a conflict, it updates the existing record instead.
voidmethod
%DB -> load (string $table, string $columns = '*', string $where = void, string $joins = void, string $group = void, string $limit = void, string $order = void, ...$args)
line 17
Loads data from the specified table in the database, allowing for optional selection of columns, filtering with conditions, joining with other tables, grouping, ordering, and limiting the results.
$table = strpos($table, space) || strpos($table, dot) ? $table : "$this->fieldQuotes$table$this->fieldQuotes"
$args && $where = ($where ? "$where AND " : void).loop(array_keys($args), fn($column) => $table.dot.$this->quoteId($column).'=?', ' AND ')
$joins && $joins = " $joins"
$where && $where = " WHERE $where"
$group && $group = " GROUP BY $group"
$order && $order = " ORDER BY $order"
$limit && $limit = " LIMIT $limit"
$query = "SELECT $columns FROM $table$joins$where$group$order$limit"
return $this->query($query, ...array_values($args))method
%DB -> query ($query, ...$args)
line 29
Executes a database query with the specified SQL statement and arguments, returning the result set.
$this->queryRun($query, $args, true)method
%DB -> queryRun ($query, $args, $retry)
line 35
Executes a database query with optional arguments and retries on specific errors for idempotent read statements.
try {
if (!$args) $stmt = $this->PDO->query($query)
else {
$stmt = $this->PDO->prepare($query)
$stmt->execute($args)
}
if (debug){
$match = regex('/\b(UPDATE|INSERT INTO|DELETE FROM|FROM)\b\s+([`"\[]?\w+[`"\]]?)/i', strtr($query, [$this->fieldQuotes => void]))
$where = strtr(regex('/\bWHERE (\b.+)/is', $query)[1] ?? void, [' ORDER BY' => void])
$match && debug("Q: $match[1] $match[2]".strtr(rtrim(" $where "), [dq => void])." (".$stmt->rowCount().")")
}
return $stmt
}
catch (\PDOException $e){
// Retry only idempotent read statements outside a transaction. WITH is excluded: a `WITH ... UPDATE`
// or `WITH ... DELETE` CTE is a mutation that may already have run before the connection dropped
// (error 2013), and a reconnect would start a fresh, transaction-less session.
if (!$retry || !$this->goneAway($e) || $this->PDO->inTransaction() || !preg_match('/^\s*\(*\s*(SELECT|SHOW|EXPLAIN|DESCRIBE|DESC)\b/i', $query)) error('Database error'.colon.lf.$query.lf.lf.$e->getMessage())
unset($this->PDO)
return $this->queryRun($query, $args, false)
}method
%DB -> goneAway ($e)
line 59
Checks if a database connection error indicates that the connection has been lost or the server is unavailable.
in_array((int)($e->errorInfo[1] ?? 0), [2006, 2013], true) || stripos($e->getMessage(), 'gone away') !== false || stripos($e->getMessage(), 'lost connection') !== falsemethod
%DB -> column (...$args)
line 61
Fetches a single column from the result set of a database query, using the provided arguments to load the data.
$this->load(...$args)->fetchAll(\PDO::FETCH_COLUMN)method
%DB -> item (...$args)
line 62
Loads an item from the database using the provided arguments and returns it as a single column value, or null if not found.
($v = $this->load(...$args)->fetch(\PDO::FETCH_COLUMN)) === false ? null : $vmethod
%DB -> pair (...$args)
line 63
Fetches all rows from the database as a key-value pair array using the provided arguments.
$this->load(...$args)->fetchAll(\PDO::FETCH_KEY_PAIR)method
%DB -> group (...$args)
line 64
Fetches all records from the database grouped by a specified column or columns, returning the results as an array of objects of the specified class.
$this->load(...$args)->fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_CLASS, obj::class)method
%DB -> records (...$args)
line 65
Fetches all records from the database as objects of the specified class, using the provided arguments for the query.
$this->load(...$args)->fetchAll(\PDO::FETCH_CLASS|\PDO::FETCH_UNIQUE, obj::class)method
%DB -> rows (...$args)
line 66
Fetches all rows from the database as instances of the specified class using the provided arguments.
$this->load(...$args)->fetchAll(\PDO::FETCH_CLASS, obj::class)method
%DB -> record (...$args)
line 67
Fetches a single record from the database as an object of the specified class, returning null if no record is found.
$this->load(...$args)->fetchObject(obj::class) ?: nullmethod
%DB -> quoteList (array $ids)
line 68
Quotes each element in the provided array of IDs for safe use in SQL queries, returning a comma-separated string.
loop($ids, fn($id) => $this->PDO->quote((string)$id), comma)method
%DB -> quoteId ($id)
line 72
Escapes an identifier for use in a SQL query, ensuring it is properly quoted to prevent SQL injection.
$this->fieldQuotes.str_replace($this->fieldQuotes, $this->fieldQuotes.$this->fieldQuotes, (string)$id).$this->fieldQuotesmethod
%DB -> create (string $table, ...$data)
line 74
Inserts a new record into the specified table with the provided data, optionally ignoring conflicts based on the 'ignore' flag.
if ($ignore = $data['ignore'] ?? false) unset($data['ignore'])
$columns = implode(comma, loop(array_keys($data), fn($k) => $this->quoteId($k)))
$values = implode(comma, array_fill(0, count($data), qm))
$query = "INSERT".($ignore ? $this->insertIgnore : void)." INTO $table ($columns) VALUES ($values)".($ignore ? $this->insertOnConflict : void)
$this->query($query, ...array_values(loop($data, fn($value) => is_a($value, obj::class) ? $value->id : $value)))
return $this->lastId() ?: ($data['id'] ?? null)method
%DB -> lastId
line 83
Returns the ID of the last inserted row in the database.
$this->PDO->lastInsertId()method
%DB -> change (string $table, string $where, ...$data)
line 85
Updates records in the specified table based on the given conditions and data.
$whereCount = substr_count($where, qm)
$updates = isset($data['updates']) ? $data['updates'] : void
unset($data['updates'])
$updates .= (($wheres = array_slice(array_keys($data), $whereCount)) && $updates ? comma : void).loop($wheres, fn($key) => $this->quoteId($key).'=?', comma)
$query = "UPDATE $table SET $updates WHERE $where"
$args = array_values([...array_slice($data, $whereCount), ...array_slice($data, 0, $whereCount)])
return $this->query($query, ...$args)->rowCount()method
%DB -> delete (string $table, string $where, ...$args)
line 95
Deletes rows from the specified table based on the given condition. It returns the number of affected rows.
$this->query("DELETE FROM $table WHERE $where", ...$args)->rowCount()method
%DB -> begin
line 96
Starts a new database transaction using PDO.
$this->PDO->beginTransaction()method
%DB -> commit
line 97
Commits the current transaction in the database, making all changes made during the transaction permanent.
$this->PDO->commit()method
%DB -> rollback
line 98
Rolls back the current transaction if one is active, reverting any changes made during the transaction.
$this->PDO->inTransaction() && $this->PDO->rollBack()method
%DB -> transaction ($callback)
line 100
Executes a database transaction, allowing for a callback function to be run within the transaction context. If an error occurs, it rolls back to the last savepoint or the beginning of the transaction, ensuring data integrity.
if (!$this->PDO->inTransaction()){
$this->begin
try {
$result = $callback()
$this->commit
return $result
} catch (\Throwable $e){
$this->rollback
throw $e
}
}
// Nested: a savepoint gives the inner unit its own rollback point, so its failure
// (e.g. an audit insert) is undone even when the outer transaction commits.
$sp = 'phlo_sp_'.(++$this->savepoint)
$this->PDO->exec('SAVEPOINT '.$sp)
try {
$result = $callback()
$this->PDO->exec('RELEASE SAVEPOINT '.$sp)
$this->savepoint--
return $result
} catch (\Throwable $e){
$this->PDO->exec('ROLLBACK TO SAVEPOINT '.$sp)
$this->PDO->exec('RELEASE SAVEPOINT '.$sp)
$this->savepoint--
throw $e
}object
%JSONDB
/phlo/resources/DB/JSONDB.phlo
static
JSONDB :: __handle
line 11
JSONDB::$__handle is a reference to the internal file handle used for accessing the JSON database specified by the $file path.
"JSONDB/$file"method
%JSONDB -> __construct (private string $file)
line 12
The constructor initializes a JSONDB instance and ensures that the directory for the specified file exists, creating it if necessary.
$dir = dirname($this->file)
is_dir($dir) || mkdir($dir, 0755, true) || error("JSONDB: cannot create dir $dir")prop
%JSONDB -> PDO
line 16
This function triggers an error indicating that the JSONDB driver is not compatible with PDO.
error('JSONDB driver does not use PDO')prop
%JSONDB -> fieldQuotes
line 17
Retrieves the quotes for a specified field in a JSONDB resource.
voidprop
%JSONDB -> lastInsertedId
line 18
Returns the ID of the last inserted record in the JSONDB.
nullmethod
%JSONDB -> quoteList (array $ids)
line 25
Joins an array of IDs into a single string, separated by commas, and wraps it in double quotes.
dq.implode(dq.comma.dq, $ids).dqmethod
%JSONDB -> objRead
line 27
Reads a JSON file and returns its contents as an associative array. If the file does not exist or is empty, it returns an empty array.
file_exists($this->file) ? json_decode(file_get_contents($this->file), true) ?: [] : []method
%JSONDB -> objWrite (array $data)
line 28
Writes the provided array data to a JSON file, encoding it in a pretty-printed format while ensuring Unicode characters are not escaped.
file_put_contents($this->file, json_encode(array_values($data), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX)method
%JSONDB -> objNextId (array $data)
line 29
Returns the next available ID for a new object in the given array of data by finding the maximum current ID and adding one, or returns 1 if the array is empty.
$data ? (int)max(array_column($data, 'id')) + 1 : 1method
%JSONDB -> objFilter (array $data, string $where = void, ...$args)
line 31
Filters an array of data based on specified conditions in the 'where' clause, returning only the matching rows.
if (!$where) return $data
$filtered = []
foreach ($data AS $row){
$match = true
$parts = preg_split('/\s+AND\s+/i', $where)
$argIndex = 0
foreach ($parts AS $part){
if (preg_match('/^[`"]?(\w+)[`"]?\s*=\s*\?$/', trim($part), $m)){
$column = $m[1]
$value = $args[$argIndex++] ?? null
if (($row[$column] ?? null) != $value) $match = false
}
elseif (preg_match('/^[`"]?(\w+)[`"]?\s+IN\s*\((.+)\)$/i', trim($part), $m)){
$column = $m[1]
$ids = array_map(fn($v) => trim($v, "\"' "), explode(comma, $m[2]))
if (!in_array($row[$column] ?? null, $ids)) $match = false
}
}
$match && $filtered[] = $row
}
return $filteredmethod
%JSONDB -> objSelect (string $where = void, string $limit = void, string $order = void, ...$args)
line 55
Selects objects from the JSON database based on specified conditions, with optional ordering and limiting of results.
$data = $this->objFilter($this->objRead(), $where, ...array_values($args))
if ($order){
$desc = str_contains($order, 'DESC')
$col = trim(preg_replace('/\s+(ASC|DESC)/i', void, $order), '` ')
usort($data, fn($a, $b) => $desc ? ($b[$col] ?? 0) <=> ($a[$col] ?? 0) : ($a[$col] ?? 0) <=> ($b[$col] ?? 0))
}
$limit && $data = array_slice($data, 0, (int)$limit)
return $datamethod
%JSONDB -> create (string $table, ...$data)
line 66
Creates a new entry in the specified table of the JSON database, assigning an ID if not provided, and optionally ignoring duplicates based on the ID.
if ($ignore = $data['ignore'] ?? false) unset($data['ignore'])
$all = $this->objRead()
$data['id'] ??= $this->objNextId($all)
foreach ($data AS $key => $value) is_a($value, 'obj') && $data[$key] = $value->id
if ($ignore){
foreach ($all AS $row) if (($row['id'] ?? null) == $data['id']) return $data['id']
}
$all[] = $data
$this->objWrite($all)
$this->lastInsertedId = $data['id']
return $data['id']method
%JSONDB -> change (string $table, string $where, ...$data)
line 80
Updates rows in the specified table that match the given condition with new data, returning the number of rows changed.
$all = $this->objRead()
$whereCount = substr_count($where, qm)
$whereArgs = array_slice(array_values($data), 0, $whereCount)
$updates = array_slice($data, $whereCount, null, true)
$changed = 0
foreach ($all AS &$row){
if ($this->objFilter([$row], $where, ...$whereArgs)){
foreach ($updates AS $key => $value) $row[$key] = $value
$changed++
}
}
unset($row)
$this->objWrite($all)
return $changedmethod
%JSONDB -> delete (string $table, string $where, ...$args)
line 97
Deletes records from the specified table in the JSON database that match the given condition.
$all = $this->objRead()
$matching = $this->objFilter($all, $where, ...$args)
$matchIds = array_column($matching, 'id')
$remaining = array_values(array_filter($all, fn($row) => !in_array($row['id'] ?? null, $matchIds)))
$this->objWrite($remaining)
return count($matching)method
%JSONDB -> load (string $table, string $columns = '*', string $where = void, string $joins = void, string $group = void, string $limit = void, string $order = void, ...$args)
line 106
Loads data from a specified table in JSONDB, allowing for optional selection of columns, filtering with conditions, joining with other tables, grouping, limiting results, and ordering.
!$where && $args && $where = loop(array_keys($args), fn($column) => "$column=?", ' AND ')
$data = $this->objSelect($where, $limit, $order, ...array_values($args))
return %JSON_result($data)method
%JSONDB -> query ($query, ...$args)
line 111
Executes a query against the JSONDB, but does not support raw SQL queries.
error('JSONDB driver does not support raw SQL queries')method
%JSONDB -> begin
line 113
Begins a transaction in the JSONDB, allowing for multiple operations to be executed atomically.
nullmethod
%JSONDB -> commit
line 114
Commits the current transaction to the JSONDB, saving all changes made during the transaction.
nullmethod
%JSONDB -> rollback
line 115
Reverts the last transaction in the JSONDB, restoring the database to its previous state.
nullobject
%JSON_result
/phlo/resources/DB/JSON.result.phlo
static
JSON_result :: __handle
line 9
This property is used to access the internal handle of a JSON_result object.
nullprop
%JSON_result -> data
line 10
Accesses the `$data` property of the `JSON_result` object, which contains the parsed data from a JSON response.
[]method
%JSON_result -> __construct (array $data)
line 11
Initializes a JSON_result object with the provided data array.
$this->data = $datamethod
%JSON_result -> fetchAll ($mode = 2)
line 13
Fetches all results from the JSON resource according to the specified mode, allowing for different formats such as a single column, key-value pairs, or objects.
if ($mode === \PDO::FETCH_COLUMN) return loop($this->data, fn($row) => reset((array)$row))
if ($mode === \PDO::FETCH_KEY_PAIR){
$out = []
foreach ($this->data AS $row){
$vals = array_values((array)$row)
$out[$vals[0] ?? null] = $vals[1] ?? null
}
return $out
}
if (($mode & (\PDO::FETCH_CLASS | \PDO::FETCH_UNIQUE)) === (\PDO::FETCH_CLASS | \PDO::FETCH_UNIQUE)){
$out = []
foreach ($this->data AS $row){
$o = new obj
foreach ((array)$row AS $k => $v) $o->$k = $v
$out[$row['id'] ?? count($out)] = $o
}
return $out
}
if (($mode & \PDO::FETCH_CLASS) === \PDO::FETCH_CLASS){
$out = []
foreach ($this->data AS $row){
$o = new obj
foreach ((array)$row AS $k => $v) $o->$k = $v
$out[] = $o
}
return $out
}
return $this->datamethod
%JSON_result -> fetchObject ($class = 'obj')
line 44
Fetches a single object of the specified class from the JSON result data, mapping the properties of the object to the values in the first row of the data.
if (!$this->data) return null
$row = reset($this->data)
$o = new $class
foreach ((array)$row AS $k => $v) $o->$k = $v
return $omethod
%JSON_result -> fetch ($mode = 2)
line 52
Fetches a result row from the JSON data, returning either the entire row or a specific column based on the provided mode.
if (!$this->data) return null
$row = reset($this->data)
if ($mode === \PDO::FETCH_COLUMN) return reset((array)$row)
return $rowmethod
%JSON_result -> fetchColumn ($col = 0)
line 59
Fetches a single column from the first row of the JSON result set, returning the value at the specified column index or false if not found.
if (!$this->data) return false
$row = reset($this->data)
$vals = array_values((array)$row)
return $vals[$col] ?? falsemethod
%JSON_result -> rowCount
line 66
Returns the number of rows in the JSON result set.
count($this->data)object
%model
/phlo/resources/DB/model.phlo
static
model :: DB
line 11
This property accesses the database engine configuration for the model, throwing an error if none is configured.
error('No database engine configured for '.static::class)static
model :: objCache
line 12
The model::$objCache property holds a cache for model objects, allowing for improved performance by reducing the need to repeatedly fetch the same data.
falsestatic
model :: objRecordLimit
line 13
Sets the maximum number of records that can be retrieved by the model.
10000static
model :: objAudit
line 14
The `model::$objAudit` property is used to access the audit object associated with the model, allowing for tracking changes and modifications.
falsestatic
model :: objValidate
line 15
The model::$objValidate property indicates whether the object validation is enabled or disabled, returning false if validation is not active.
falsestatic
model :: idColumn
line 16
The model::$idColumn property specifies the name of the identifier column used in the model, defaulting to 'id'.
'id'static
model :: idType
line 17
Defines the data type for the model's identifier as an integer.
'int'static
model :: canView
line 19
This property indicates whether the current user has permission to view the model.
truestatic
model :: canCreate
line 20
The model::$canCreate property indicates whether a new instance of the model can be created.
truestatic
model :: canChange
line 21
This property indicates whether the model can be changed, returning true if changes are allowed.
truestatic
model :: canDelete
line 22
The model::$canDelete property indicates whether the model instance can be deleted.
truestatic
model :: state
line 24
The `model::$state` property holds the current state of the model, including metadata, records, and errors.
%req->model ??= obj(meta: [], records: [], errors: [])static
model :: columns
line 25
Retrieves the columns defined in the model, either from the static::$columns property or by calling the schema method if it exists.
if (isset(static::$columns)) return static::$columns
if (!method_exists(static::class, 'schema')) return static::$table.'.*'
$state = static::state()
$key = spl_object_id(static::DB()).':'.static::DB()->fieldQuotes.':'.static::$table
return $state->meta[static::class]['columns'][$key] ??= static::_columns()static
model :: _columns
line 32
Retrieves the column names of the model's associated database table, formatted with field quotes.
$fq = static::DB()->fieldQuotes
$list = array_merge(...array_values(array_filter(loop(static::fields(), fn($field) => loop($field->objColumns, fn($col) => static::$table."$fq.$fq".$col)))))
return $fq.implode("$fq,$fq", $list).$fqstatic
model :: fields
line 37
Returns the fields defined in the model's schema, or an empty array if no schema exists. If the schema is available, it retrieves the fields from the model's state metadata.
if (!method_exists(static::class, 'schema')) return static::$fields ?? []
$state = static::state()
return $state->meta[static::class]['fields'] ??= static::_fields()static
model :: _fields
line 42
This property retrieves the fields defined in the model's schema, ensuring that none of the field names conflict with reserved keywords.
$reserved = ['table','order','fields','columns','create','change','delete','records','record','column','item','pair','DB','objCache','objState','objSave','objGet','objAudit','objValidate','objErrors','idColumn','idType']
$fields = loop(static::schema(), fn($field, $column) => last($field->name ??= $column, $field->type === 'parent' && $field->obj ??= $column, $field))
foreach ($reserved AS $word) isset($fields[$word]) && error("Reserved column name '$word' in ".static::class)
return $fieldsstatic
model :: field ($name)
line 48
Accesses a specific field defined in the model's static fields array using the provided name.
static::fields()[$name]static
model :: create (...$args)
line 50
Creates a new instance of the model, validating the input arguments and executing any defined lifecycle methods before saving the record to the database.
$class = static::class
if (static::objValidate() && !static::objRunValidation($args)) return null
$record = new $class(...$args)
method_exists(static::class, 'beforeSave') && $record->beforeSave()
method_exists(static::class, 'beforeCreate') && $record->beforeCreate()
$pk = static::idColumn()
return static::objAudit() ? static::transaction(fn() => static::objCreateCommit($record, $pk)) : static::objCreateCommit($record, $pk)static
model :: objCreateCommit ($record, $pk)
line 60
Creates a new record in the model and triggers afterCreate and afterSave methods if they exist, while also logging the creation event for auditing purposes.
$id = static::createRecord(...$record)
$record = static::record(...[$pk => $record->$pk ?? $id])
method_exists(static::class, 'afterCreate') && $record->afterCreate()
method_exists(static::class, 'afterSave') && $record->afterSave()
static::objAudit() && audit::log($record, 'create', [], $record->objData)
return $recordstatic
model :: objRunValidation ($data)
line 69
Validates the provided data against the defined fields of the model, collecting any errors encountered during the validation process.
$errors = []
$fields = static::fields()
foreach ($data AS $column => $value){
if (!($field = $fields[$column] ?? null) || !method_exists($field, 'objValidate')) continue
if ($error = $field->objValidate($value)) $errors[$column] = $error
}
static::state()->errors[static::class] = $errors
return empty($errors)static
model :: objErrors
line 80
Retrieves the error messages associated with the current model instance, returning an empty array if none are found.
static::state()->errors[static::class] ?? []static
model :: createRecord (...$args)
line 81
Creates a new record in the specified database table using the provided arguments.
static::DB()->create(static::$table, ...$args)static
model :: change ($where, ...$args)
line 82
This method handles the change operation for a model, performing an audit if necessary and logging updates to the database.
if (!static::objAudit()) return static::DB()->change(static::$table, $where, ...$args)
$pk = static::idColumn()
$bindings = array_values(array_filter($args, 'is_int', ARRAY_FILTER_USE_KEY))
return static::transaction(function() use ($where, $args, $bindings, $pk){
$old = static::DB()->query('SELECT '.static::$table.'.* FROM '.static::$table.' WHERE '.$where, ...$bindings)->fetchAll(\PDO::FETCH_CLASS, static::class)
$result = static::DB()->change(static::$table, $where, ...$args)
foreach ($old AS $record){
$fresh = static::record(...[$pk => $record->$pk])
$fresh && audit::log($fresh, 'update', $record->objData, $fresh->objData)
}
return $result
})static
model :: delete ($where, ...$args)
line 97
Deletes records from the database table associated with the model, invoking 'beforeDelete' and 'afterDelete' methods if they exist, and handling auditing and transactions as necessary.
if (method_exists(static::class, 'beforeDelete') || method_exists(static::class, 'afterDelete') || static::objAudit()){
$records = static::DB()->query('SELECT '.static::$table.'.* FROM '.static::$table.' WHERE '.$where, ...$args)->fetchAll(\PDO::FETCH_CLASS, static::class)
foreach ($records AS $record) method_exists(static::class, 'beforeDelete') && $record->beforeDelete()
return static::objAudit() ? static::transaction(fn() => static::objDeleteCommit($where, $args, $records)) : static::objDeleteCommit($where, $args, $records)
}
return static::DB()->delete(static::$table, $where, ...$args)static
model :: objDeleteCommit ($where, $args, $records)
line 106
Deletes a record from the database based on the specified conditions and executes an optional after-delete method for each record, logging the deletion if auditing is enabled.
$result = static::DB()->delete(static::$table, $where, ...$args)
foreach ($records AS $record){
method_exists(static::class, 'afterDelete') && $record->afterDelete()
static::objAudit() && audit::log($record, 'delete', $record->objData, [])
}
return $resultstatic
model :: objLogChange ($where, ...$args)
line 115
Logs changes to the specified model object, capturing the state before and after modifications.
static::change($where, ...$args)method
%model -> objSave
line 117
Saves the current object to the database, handling both new and existing records with appropriate hooks for before and after save operations.
$pk = static::idColumn()
$pkValue = $this->$pk ?? $this->id ?? null
$pkValue || error('Can\'t save '.static::class.' record without '.$pk)
// Hooks receive the persisted row as $old, never a clone of the already-mutated object.
$old = static::record(...[$pk => $pkValue])
$isNew = !$old
method_exists(static::class, 'beforeSave') && $this->beforeSave($old)
if ($isNew){
method_exists(static::class, 'beforeCreate') && $this->beforeCreate()
$saved = static::objAudit() ? static::transaction(fn() => $this->objSaveCreate($pk, $pkValue)) : $this->objSaveCreate($pk, $pkValue)
}
else {
method_exists(static::class, 'beforeChange') && $this->beforeChange($old)
static::change($pk.'=?', $pkValue, ...$this)
$saved = static::record(...[$pk => $pkValue])
method_exists(static::class, 'afterChange') && $saved->afterChange($old)
}
method_exists(static::class, 'afterSave') && $saved->afterSave($old)
return $savedmethod
%model -> objSaveCreate ($pk, $pkValue)
line 139
Creates a new record in the model and performs post-creation actions if defined, such as logging and auditing.
static::createRecord(...$this)
$saved = static::record(...[$pk => $pkValue])
method_exists(static::class, 'afterCreate') && $saved->afterCreate()
static::objAudit() && audit::log($saved, 'create', [], $saved->objData)
return $savedstatic
model :: transaction ($callback)
line 147
Executes a database transaction using the provided callback function, ensuring that all operations within the transaction are completed successfully before committing.
static::DB()->transaction($callback)static
model :: query
line 148
Executes a query on the model's database, returning the results based on the specified conditions.
phlo('query', class: static::class)static
model :: column (...$args)
line 150
Accesses a specific column from the records loaded by the model, using the fetchAll method with PDO's FETCH_COLUMN option.
static::recordsLoad($args, 'fetchAll', [\PDO::FETCH_COLUMN])static
model :: item (...$args)
line 151
Loads records from the database using the specified arguments and fetch mode, returning a single column of data.
static::recordsLoad($args, 'fetch', [\PDO::FETCH_COLUMN])static
model :: pair (...$args)
line 152
Loads records from the database as a key-value pair array using the specified fetch mode.
static::recordsLoad($args, 'fetchAll', [\PDO::FETCH_KEY_PAIR])static
model :: records (...$args)
line 153
Retrieves all records from the model, loading them as instances of the model class.
static::recordsLoad($args, 'fetchAll', [\PDO::FETCH_CLASS|\PDO::FETCH_UNIQUE, static::class], true)static
model :: recordCount (...$args)
line 154
Returns the total number of records in the model's database table.
static::item(...$args, columns: 'COUNT('.static::idColumn().')')static
model :: record (...$args)
line 155
Retrieves a single record from the model's records based on the provided arguments, returning an error if multiple records are found.
count($records = static::records(...$args)) > 1 ? error('Multiple records for '.static::class) : (current($records) ?: null)static
model :: recordsLoad ($args, $fetch, $fetchMode, $saveRelations = false)
line 157
Loads records from the database based on specified arguments and caching options, while optionally saving related records in the state.
$pk = static::idColumn()
$args['table'] ??= static::$table
$saveRelations && $args['columns'] ??= static::$table.'.'.$pk.' as _,'.static::columns()
isset(static::$joins) && debug && error('DEPRECATED: static $joins in '.static::class.'. Use getParent/getChildren/getMany instead.')
isset(static::$joins) && $args['joins'] = static::$joins.(isset($args['joins']) ? " $args[joins]" : void)
method_exists(static::class, 'where') && $args['where'] = static::where().(isset($args['where']) ? " AND $args[where]" : void)
isset(static::$group) && $args['group'] ??= static::$group
isset(static::$order) && $args['order'] ??= static::$order
if ($cacheKey = $args['cacheKey'] ?? null) unset($args['cacheKey'])
if ($duration = $args['cache'] ?? static::objCache()){
unset($args['cache'])
$cacheArgs = $args
ksort($cacheArgs)
$records = apcu($cacheKey ?? static::class.slash.md5(json_encode($cacheArgs)), fn() => static::DB()->load(...$args)->$fetch(...$fetchMode), $duration === true ? 86400 : $duration)
}
else $records = static::DB()->load(...$args)->$fetch(...$fetchMode)
if ($saveRelations && $records){
$state = static::state()
$state->records[static::class] = array_replace($state->records[static::class] ?? [], array_column($records, null, $pk))
count($state->records[static::class]) > static::objRecordLimit() && $state->records[static::class] = array_slice($state->records[static::class], -static::objRecordLimit(), preserve_keys: true)
}
return $recordsstatic
model :: objRel ($key)
line 182
Accesses the relationship object defined in the model, returning metadata or invoking a method if it exists.
$state = static::state()
return $state->meta[static::class][$key] ??= method_exists(static::class, $key) ? static::$key() : static::$$key ?? []prop
%model -> objState
line 187
The `$objState` property of the model holds the state of the object, including its parents, children, and many relationships, initialized as empty arrays.
['parents' => [], 'children' => [], 'many' => []]method
%model -> objGet ($key)
line 188
Retrieves an object associated with the specified key from the parent, children, or many relationships in the model.
$this->getParent($key) ?? $this->getChildren($key) ?? $this->getMany($key)method
%model -> objIn ($ids, $db = null)
line 189
Returns a quoted list of IDs from the database or 'NULL' if no IDs are provided.
$ids ? ($db ?? static::DB())->quoteList($ids) : 'NULL'method
%model -> objMirror (string $bucket, $key)
line 194
This method synchronizes the state of an object with a canonical version based on a specified bucket and key, ensuring that the object's state reflects any changes made to the canonical object.
$pk = $this->objData[static::idColumn()] ?? null
if ($pk === null) return
$canonical = static::state()->records[static::class][$pk] ?? null
if (!$canonical || $canonical === $this) return
if (array_key_exists($key, $this->objState[$bucket] ?? [])) return
if (array_key_exists($key, $canonical->objState[$bucket] ?? [])) $this->objState[$bucket][$key] = $canonical->objState[$bucket][$key]method
%model -> getParent ($key)
line 203
Retrieves the parent object associated with a given key from the model's state, loading it if necessary.
if (array_key_exists($key, $this->objState['parents'])) return $this->objState['parents'][$key]
$state = static::state()
$parents = self::objRel('objParents')
if (!$relation = $parents[$key] ?? null) return
$isArray = is_array($relation)
$class = $isArray ? $relation['obj'] : $relation
$column = $isArray ? $relation['key'] ?? $key : $key
if (!$parentId = $this->objData[$column] ?? null) return $this->objState['parents'][$key] = null
if (!isset($state->records[$class][$parentId])){
$idsToLoad = [$parentId => true]
$allObjData = array_map(fn($record) => $record->objData, $state->records[static::class] ?? [])
foreach ($parents as $pKey => $pRelation){
$pIsArray = is_array($pRelation)
$pClass = $pIsArray ? $pRelation['obj'] : $pRelation
if ($pClass === $class) foreach (array_column($allObjData, $pIsArray ? $pRelation['key'] ?? $pKey : $pKey) as $pId) $pId && !isset($state->records[$class][$pId]) && $idsToLoad[$pId] = true
}
if ($idsToLoad = array_keys($idsToLoad)) $class::records(where: $class::idColumn().' IN ('.$this->objIn($idsToLoad, $class::DB()).')')
}
$parentObject = $state->records[$class][$parentId] ?? null
return $this->objState['parents'][$key] = $parentObjectmethod
%model -> getChildren ($key)
line 226
Retrieves the child objects associated with a given key from the model's state, loading them if they are not already present.
if (array_key_exists($key, $this->objState['children'])) return $this->objState['children'][$key]
$state = static::state()
if (!$relation = self::objRel('objChildren')[$key] ?? null) return
$isArray = is_array($relation)
$class = $isArray ? $relation['obj'] : $relation
$column = $isArray ? $relation['key'] : static::objShortName()
$toLoad = array_filter($state->records[static::class] ?? [], fn($p) => !array_key_exists($key, $p->objState['children']))
if ($toLoad){
$fq = $class::DB()->fieldQuotes
$children = $class::records(where: $fq.$column.$fq.' IN ('.$this->objIn(array_keys($toLoad), $class::DB()).')')
foreach ($toLoad AS $parentRecord) $parentRecord->objState['children'][$key] = []
foreach ($children AS $childId => $child) !is_null($pId = $child->objData[$column] ?? null) && isset($state->records[static::class][$pId]) && $state->records[static::class][$pId]->objState['children'][$key][$childId] = $child
}
$this->objMirror('children', $key)
return $this->objState['children'][$key] ?? []method
%model -> getMany ($key)
line 244
Retrieves multiple related records based on a specified key from the model's state, loading them if they are not already present.
if (array_key_exists($key, $this->objState['many'])) return $this->objState['many'][$key]
$state = static::state()
if (!$relation = self::objRel('objMany')[$key] ?? null) return
$class = $relation['obj']
$toLoad = array_filter($state->records[static::class] ?? [], fn($p) => !array_key_exists($key, $p->objState['many']))
if ($toLoad){
$fq = static::DB()->fieldQuotes
$lk = $relation['localKey']
$fk = $relation['foreignKey']
$pivotRows = static::DB()->rows(table: $relation['table'], columns: $fq.$lk.$fq.comma.$fq.$fk.$fq, where: $fq.$lk.$fq.' IN ('.$this->objIn(array_keys($toLoad)).')')
$targetIds = array_unique(array_map(fn($row) => $row->{$relation['foreignKey']}, $pivotRows ?: []))
$targetRecords = $targetIds ? $class::records(where: $class::idColumn().' IN ('.$this->objIn($targetIds, $class::DB()).')') : []
foreach ($toLoad AS $parentRecord) $parentRecord->objState['many'][$key] = []
foreach ($pivotRows ?: [] AS $row){
$parentId = $row->$lk
$foreignId = $row->$fk
if (isset($state->records[static::class][$parentId]) && isset($targetRecords[$foreignId])) $state->records[static::class][$parentId]->objState['many'][$key][$foreignId] = $targetRecords[$foreignId]
}
}
$this->objMirror('many', $key)
return $this->objState['many'][$key] ?? []method
%model -> getCount ($key)
line 268
Retrieves the count of related records for a given key, loading data if necessary from the database and caching the result in the object's state.
if (array_key_exists($key, $this->objState['counts'] ?? [])) return $this->objState['counts'][$key]
$state = static::state()
if ($relation = self::objRel('objChildren')[$key] ?? null){
$toLoad = array_filter($state->records[static::class] ?? [], fn($p) => !array_key_exists($key, $p->objState['counts'] ?? []))
if ($toLoad){
$isArray = is_array($relation)
$class = $isArray ? $relation['obj'] : $relation
$column = $isArray ? $relation['key'] : static::objShortName()
$fq = $class::DB()->fieldQuotes
$counts = $class::pair(columns: $fq.$column.$fq.', COUNT(*)', where: $fq.$column.$fq.' IN ('.$this->objIn(array_keys($toLoad), $class::DB()).')', group: $fq.$column.$fq)
foreach ($toLoad as $id => $record) $record->objState['counts'][$key] = (int)($counts[$id] ?? 0)
}
$this->objMirror('counts', $key)
return $this->objState['counts'][$key] ?? 0
}
if ($relation = self::objRel('objMany')[$key] ?? null){
$toLoad = array_filter($state->records[static::class] ?? [], fn($p) => !array_key_exists($key, $p->objState['counts'] ?? []))
if ($toLoad){
$fq = static::DB()->fieldQuotes
$localKey = $relation['localKey']
$counts = static::DB()->load(table: $relation['table'], columns: $fq.$localKey.$fq.',COUNT(*)', where: $fq.$localKey.$fq.' IN ('.$this->objIn(array_keys($toLoad)).')', group: $fq.$localKey.$fq)->fetchAll(\PDO::FETCH_KEY_PAIR)
foreach ($toLoad as $id => $record) $record->objState['counts'][$key] = (int)($counts[$id] ?? 0)
}
$this->objMirror('counts', $key)
return $this->objState['counts'][$key] ?? 0
}
return 0method
%model -> getLast ($key)
line 298
Retrieves the last child object associated with the specified key from the model's state, loading it if necessary.
if (array_key_exists($key, $this->objState['last_child'] ?? [])) return $this->objState['last_child'][$key]
$state = static::state()
if ($relation = self::objRel('objChildren')[$key] ?? null){
$toLoad = array_filter($state->records[static::class] ?? [], fn($p) => !array_key_exists($key, $p->objState['last_child'] ?? []))
if ($toLoad){
$isArray = is_array($relation)
$class = $isArray ? $relation['obj'] : $relation
$column = $isArray ? $relation['key'] : static::objShortName()
$childTable = $class::$table
$fq = $class::DB()->fieldQuotes
$qt = $fq.$childTable.$fq
$qc = $fq.$column.$fq
$ids = $this->objIn(array_keys($toLoad), $class::DB())
$childPk = $class::idColumn()
$joins = ' INNER JOIN (SELECT MAX('.$fq.$childPk.$fq.') AS last_id, '.$qc.' AS parent_id FROM '.$qt.' WHERE '.$qc.' IN ('.$ids.') GROUP BY '.$qc.') AS lcmax ON '.$qt.'.'.$fq.$childPk.$fq.' = lcmax.last_id'
$lastChildren = $class::records(joins: $joins)
foreach ($toLoad as $record) $record->objState['last_child'][$key] = null
foreach ($lastChildren as $child) if (isset($state->records[static::class][$parentId = $child->objData[$column]])) $state->records[static::class][$parentId]->objState['last_child'][$key] = $child
}
$this->objMirror('last_child', $key)
return $this->objState['last_child'][$key] ?? null
}
return nullstatic
model :: objResolveClass ($name)
line 324
Resolves the class name for the specified model object, allowing dynamic class handling in Phlo.
$namestatic
model :: objShortName ($class = null)
line 325
This expression retrieves the class name of the current model or the specified class if it exists, using the static context.
$class ?? static::classstatic
model :: objParents
line 327
Returns the parent objects associated with the current model, utilizing the defined schema and filtering fields of type 'parent'.
if (property_exists(static::class, 'objParents')) return static::$objParents
if (!method_exists(static::class, 'schema')) return []
return loop(array_filter(static::fields(), fn($f) => $f->type === 'parent'), fn($f, $c) => $f->key ? arr(obj: static::objResolveClass($f->obj), key: $f->key) : (static::objResolveClass($f->obj ?? $c)))static
model :: objChildren
line 333
Returns the children objects associated with the current model, leveraging the defined schema and filtering fields of type 'child'.
if (property_exists(static::class, 'objChildren')) return static::$objChildren
if (!method_exists(static::class, 'schema')) return []
return loop(array_filter(static::fields(), fn($f) => $f->type === 'child'), fn($f, $c) => $f->key ? arr(obj: static::objResolveClass($f->obj), key: $f->key) : (static::objResolveClass($f->obj ?? $c)))static
model :: objMany
line 339
Returns the 'objMany' property if it exists; otherwise, it retrieves an array of related objects based on the schema definition.
if (property_exists(static::class, 'objMany')) return static::$objMany
if (!method_exists(static::class, 'schema')) return []
return loop(array_filter(static::fields(), fn($f) => $f->type === 'many'), fn($f) => arr(obj: static::objResolveClass($f->obj), table: $f->table, localKey: $f->localKey ?? static::objShortName(), foreignKey: $f->foreignKey ?? $f->obj))object
%MySQL
/phlo/resources/DB/MySQL.phlo
prop
%MySQL -> PDO
line 11
Creates a new PDO instance for connecting to a MySQL database using the provided credentials.
new \PDO('mysql:host='.%creds->mysql->host.';dbname='.%creds->mysql->database, %creds->mysql->user, %creds->mysql->password)object
%PostgreSQL
/phlo/resources/DB/PostgreSQL.phlo
prop
%PostgreSQL -> PDO
line 11
Creates a new PDO instance for connecting to a PostgreSQL database using the provided credentials.
new PDO('pgsql:host='.%creds->postgresql->host.';dbname='.%creds->postgresql->database, %creds->postgresql->user, %creds->postgresql->password)prop
%PostgreSQL -> fieldQuotes
line 12
Returns the field name wrapped in double quotes for PostgreSQL compatibility.
dqprop
%PostgreSQL -> insertIgnore
line 13
Inserts a new record into a PostgreSQL database, ignoring the operation if a record with the same unique key already exists.
voidprop
%PostgreSQL -> insertOnConflict
line 14
Inserts a new record into a PostgreSQL database, and if a conflict occurs (e.g., a duplicate key), it does nothing instead of throwing an error.
' ON CONFLICT DO NOTHING'method
%PostgreSQL -> lastId
line 16
Retrieves the last inserted ID from the PostgreSQL database, using a savepoint to ensure transaction integrity.
$savepoint = $this->PDO->inTransaction()
$savepoint && $this->PDO->exec('SAVEPOINT phlo_lastid')
try {
$id = $this->PDO->lastInsertId()
} catch (\Throwable $e){
$id = false
}
if ($savepoint) $this->PDO->exec($id === false ? 'ROLLBACK TO SAVEPOINT phlo_lastid' : 'RELEASE SAVEPOINT phlo_lastid')
return $idobject
%Qdrant
/phlo/resources/DB/Qdrant.phlo
method
%Qdrant -> get (string $input, ?string $model = null)
line 10
Retrieves an embedding for the given input string using the specified model, caching the result for 28 days.
apcu('embedding/'.token(input: $input), fn($input) => %AI->embedding(input: $input, model: $model), 86400 * 28)method
%Qdrant -> collections
line 12
Retrieves an array of collection names from the Qdrant API response.
array_column($this->request('collections')->result->collections, 'name')method
%Qdrant -> create ($collection, $size = 1536, $distance = 'Cosine')
line 13
Creates a new collection in Qdrant with specified vector size and distance metric.
$this->request("collections/$collection", PUT: arr(vectors: arr(size: $size, distance: $distance)))->status === 'ok'method
%Qdrant -> upsert ($collection, $id, $input, ...$payload)
line 14
This function updates or inserts a point in a specified Qdrant collection using the provided ID and input vector, along with optional payload data.
$this->request("collections/$collection/points", PUT: arr(points: [arr(id: $id, vector: $this->get($input), payload: $payload ?: null)]))->result->operation_idmethod
%Qdrant -> delete ($collection, ...$ids)
line 15
Deletes specified points from a Qdrant collection based on their IDs.
$this->request("collections/$collection/points/delete", POST: arr(points: $ids))->resultmethod
%Qdrant -> search ($collection, $input = null, $top = 100)
line 16
Searches for points in the specified Qdrant collection based on the input vector and returns the top results.
create($this->request("collections/$collection/points/search", POST: arr(vector: is_null($input) ? array_fill(0, 1536, 0) : $this->get($input), top: $top, with_payload: true))->result, fn($record) => $record->id, fn($record) => last($record = array_merge(get_object_vars($record), get_object_vars($record->payload)), obj(...array_filter($record, fn($key) => $key !== 'payload', ARRAY_FILTER_USE_KEY))))method
%Qdrant -> drop ($collection)
line 17
Drops the specified collection from Qdrant by sending a DELETE request to the appropriate endpoint.
$this->request("collections/$collection", DELETE: true)->resultmethod
%Qdrant -> request ($uri, ...$data)
line 19
Sends an HTTP request to the specified Qdrant server URI with optional data and returns the decoded JSON response.
json_decode(HTTP(%creds->qdrant->server.$uri, %creds->qdrant->key ? ['api-key: '.%creds->qdrant->key] : [], true, ...$data))object
%query
/phlo/resources/DB/query.phlo
prop
%query -> class
line 10
Retrieves the class type of the current query object.
prop
%query -> conditions
line 11
Defines conditions for filtering results in a query.
[]prop
%query -> bindings
line 12
The `query->$bindings` retrieves the bindings associated with a query in Phlo, allowing access to the parameters used in the query execution.
[]prop
%query -> orderBy
line 13
Specifies the field by which the results of a query should be ordered.
prop
%query -> limitVal
line 14
Sets the maximum number of results to return from a query in Phlo.
prop
%query -> offsetVal
line 15
Retrieves the current offset value for pagination in a query.
method
%query -> fq
line 16
This expression retrieves the field quotes from the database class associated with the current instance, or defaults to 'bt' if the class is not set.
($class = $this->class) ? $class::DB()->fieldQuotes : btmethod
%query -> q ($column)
line 17
Validates the specified column name for the query builder and formats it by surrounding each part with the fully qualified name.
preg_match('/^[A-Za-z_][A-Za-z0-9_.]*$/', $column) || error("Invalid column for query builder: $column")
$fq = $this->fq
return implode(dot, array_map(fn($part) => $fq.$part.$fq, explode(dot, $column)))method
%query -> eq ($column, $value)
line 23
Filters the query results to include only those where the specified column equals the given value.
$this->where($this->q($column)." = ?", $value)method
%query -> neq ($column, $value)
line 24
Filters results where the specified column is not equal to the given value.
$this->where($this->q($column)." != ?", $value)method
%query -> gt ($column, $value)
line 25
Adds a condition to the query that filters results where the specified column is greater than the given value.
$this->where($this->q($column)." > ?", $value)method
%query -> gte ($column, $value)
line 26
Generates a query condition that checks if the value of the specified column is greater than or equal to a given value.
$this->where($this->q($column)." >= ?", $value)method
%query -> lt ($column, $value)
line 27
Adds a condition to the query to filter results where the specified column is less than the given value.
$this->where($this->q($column)." < ?", $value)method
%query -> lte ($column, $value)
line 28
Adds a condition to the query that filters results where the specified column is less than or equal to the given value.
$this->where($this->q($column)." <= ?", $value)method
%query -> like ($column, $value)
line 29
Adds a condition to the query that checks if the specified column contains a value similar to the provided value using the SQL LIKE operator.
$this->where($this->q($column)." LIKE ?", $value)method
%query -> in ($column, array $values)
line 30
Adds a condition to the query to filter results where the specified column's value is in the provided array of values.
$this->where($this->q($column)." IN (".implode(comma, array_fill(0, count($values), qm)).")", ...$values)method
%query -> isNull ($column)
line 31
Checks if the specified column in the query is null.
$this->where($this->q($column)." IS NULL")method
%query -> notNull ($column)
line 32
Adds a condition to the query to ensure that the specified column is not null.
$this->where($this->q($column)." IS NOT NULL")method
%query -> between ($column, $min, $max)
line 33
Filters results to include only those where the specified column's value is between the given minimum and maximum values.
$this->where($this->q($column)." BETWEEN ? AND ?", $min, $max)method
%query -> raw ($sql, ...$bindings)
line 34
Executes a raw SQL query with the provided bindings, allowing for dynamic query construction.
$this->where($sql, ...$bindings)method
%query -> where ($condition, ...$values)
line 35
Adds a condition to the query with the specified values for binding. It allows for dynamic filtering of results based on the provided condition.
$this->conditions[] = $condition
foreach ($values AS $v) $this->bindings[] = $v
return $thismethod
%query -> order ($order)
line 41
Sets the order for the query using the specified $order value and returns the current instance.
$this->orderBy = $order
return $thismethod
%query -> limit ($limit)
line 46
Sets the maximum number of results to return from a query, defined by the $limit parameter.
$this->limitVal = $limit
return $thismethod
%query -> offset ($offset)
line 51
Sets the offset value for the query, allowing for pagination of results.
$this->offsetVal = $offset
return $thismethod
%query -> build
line 55
Builds a query argument array based on specified conditions, order, limit, and bindings for use in database operations.
$where = $this->conditions ? implode(' AND ', $this->conditions) : void
$limit = $this->limitVal ? ($this->offsetVal ? "$this->offsetVal,$this->limitVal" : "$this->limitVal") : void
$args = ['where' => $where ?: void, 'order' => $this->orderBy ?: void, 'limit' => $limit ?: void]
foreach ($this->bindings AS $b) $args[] = $b
return $argsprop
%query -> records
line 63
Retrieves a collection of records from the specified class using the provided build parameters.
($class = $this->class) && $class::records(...$this->build)prop
%query -> record
line 64
Retrieves a record from the specified class using the provided build parameters.
($class = $this->class) && $class::record(...$this->build)prop
%query -> column
line 65
Accesses a specific column from a query result set using the defined class and build parameters.
($class = $this->class) && $class::column(...$this->build)prop
%query -> item
line 66
Retrieves an item from a class using the provided build parameters.
($class = $this->class) && $class::item(...$this->build)prop
%query -> count
line 67
Returns the total number of records in the specified class using the recordCount method.
($class = $this->class) && $class::recordCount(...$this->build)method
%query -> delete
line 68
Deletes records from the database based on specified conditions. If no conditions are provided, an error is raised.
$class = $this->class
$where = $this->conditions ? implode(' AND ', $this->conditions) : error('Cannot delete without conditions')
return $class::delete($where, ...$this->bindings)object
%SQLite
/phlo/resources/DB/SQLite.phlo
static
SQLite :: __handle
line 11
This property holds the handle to the SQLite database connection, allowing interaction with the database.
"SQLite/$file"method
%SQLite -> __construct (private string $file)
line 12
Initializes a new SQLite instance with the specified database file.
prop
%SQLite -> PDO
line 13
Creates a new PDO instance for SQLite using the specified file.
new PDO('sqlite:'.$this->file)prop
%SQLite -> insertIgnore
line 14
Inserts a new record into the SQLite database, ignoring the operation if a record with the same primary key already exists.
' OR IGNORE'