DB
object
%DB
/phlo/resources/DB/DB.phlo
prop
%DB -> PDO:\PDO
line 12
This function triggers an error if no PDO connector is defined for database operations.
error('No PDO connector defined')prop
%DB -> fieldQuotes:string
line 13
Retrieves the field quotes for a specified database field, allowing for the correct formatting of SQL queries.
btprop
%DB -> savepoint:int
line 14
Creates a savepoint in the current database transaction, allowing for partial rollbacks.
prop
%DB -> insertIgnore:string
line 15
Inserts a new record into the database while ignoring any duplicate entries that would cause a conflict.
' IGNORE'prop
%DB -> insertOnConflict:string
line 16
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 18
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 30
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):\PDOStatement
line 37
Runs a statement, retrying once when the connection was lost.
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):bool
line 61
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):array
line 63
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 64
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):array
line 65
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):array
line 66
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):array
line 67
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):array
line 68
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):?obj
line 69
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):string
line 70
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):string
line 75
Safely quotes a SQL identifier such as a column or table name.
$this->fieldQuotes.str_replace($this->fieldQuotes, $this->fieldQuotes.$this->fieldQuotes, (string)$id).$this->fieldQuotesmethod
%DB -> create (string $table, ...$data)
line 77
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 86
Returns the ID of the last inserted row in the database.
$this->PDO->lastInsertId()method
%DB -> change (string $table, string $where, ...$data):int
line 88
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):int
line 98
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:?bool
line 99
Starts a new database transaction using PDO.
$this->PDO->beginTransaction()method
%DB -> commit:?bool
line 100
Commits the current transaction in the database, making all changes made during the transaction permanent.
$this->PDO->commit()method
%DB -> rollback:?bool
line 101
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 103
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 12
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 13
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:\PDO
line 17
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:string
line 18
Retrieves the quotes for a specified field in a JSONDB resource.
voidprop
%JSONDB -> lastInsertedId
line 19
Returns the ID of the last inserted record in the JSONDB.
nullmethod
%JSONDB -> quoteList (array $ids):string
line 26
Builds the quoted id list an IN clause expects.
dq.implode(dq.comma.dq, $ids).dqmethod
%JSONDB -> objRead:array
line 28
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):int|false
line 29
file_put_contents($this->file, json_encode(array_values($data), jsonPretty), LOCK_EX)method
%JSONDB -> objNextId (array $data):int
line 30
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):array
line 32
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):array
line 56
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 70
ignore compares ids loosely, so the string "7" and the number 7 count as one row.
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):int
line 84
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):int
line 101
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):JSON_result
line 110
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 115
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:?bool
line 117
Begins a transaction in the JSONDB, allowing for multiple operations to be executed atomically.
nullmethod
%JSONDB -> commit:?bool
line 118
Commits the current transaction to the JSONDB, saving all changes made during the transaction.
nullmethod
%JSONDB -> rollback:?bool
line 119
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 10
This property is used to access the internal handle of a JSON_result object.
nullprop
%JSON_result -> data:array
line 11
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 12
Initializes a JSON_result object with the provided data array.
$this->data = $datamethod
%JSON_result -> fetchAll ($mode = 2, $class = 'obj'):array
line 14
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 $class
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 $class
foreach ((array)$row AS $k => $v) $o->$k = $v
$out[] = $o
}
return $out
}
return $this->datamethod
%JSON_result -> fetchObject ($class = 'obj'):?obj
line 45
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 53
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 60
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:int
line 67
Returns the number of rows in the JSON result set.
count($this->data)object
%model
/phlo/resources/DB/model.phlo
static
model :: DB
line 12
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 13
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 14
Sets the maximum number of records that can be retrieved by the model.
10000static
model :: objAudit
line 15
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 16
The model::$objValidate property indicates whether the object validation is enabled or disabled, returning false if validation is not active.
falsestatic
model :: idColumn
line 17
The model::$idColumn property specifies the name of the identifier column used in the model, defaulting to 'id'.
'id'static
model :: idType
line 18
Defines the data type for the model's identifier as an integer.
'int'static
model :: canView
line 20
This property indicates whether the current user has permission to view the model.
truestatic
model :: canCreate
line 21
The model::$canCreate property indicates whether a new instance of the model can be created.
truestatic
model :: canChange
line 22
This property indicates whether the model can be changed, returning true if changes are allowed.
truestatic
model :: canDelete
line 23
The model::$canDelete property indicates whether the model instance can be deleted.
truestatic
model :: state:obj
line 25
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:string
line 26
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:string
line 33
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:array
line 38
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:array
line 43
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 49
Accesses a specific field defined in the model's static fields array using the provided name.
static::fields()[$name]static
model :: create (...$args):?static
line 51
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):?static
line 61
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):bool
line 70
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:array
line 81
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 82
Creates a new record in the specified database table using the provided arguments.
static::DB()->create(static::$table, ...$args)static
model :: change ($where, ...$args):int
line 83
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):int
line 98
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):int
line 107
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):int
line 116
Logs changes to the specified model object, capturing the state before and after modifications.
static::change($where, ...$args)method
%model -> objSave:?static
line 118
$pk = static::idColumn()
$pkValue = $this->$pk ?? $this->id ?? null
$pkValue || error('Can\'t save '.static::class.' record without '.$pk)
$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):?static
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: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):array
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):array
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):array
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):?static
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 162
Loads records and keeps a full record read on the request-local state for relation reuse.
$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):array
line 187
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:array
line 192
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 193
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):string
line 194
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 200
Mirrors a freshly loaded relation onto a stale reference to the same record.
$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 209
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 232
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 250
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):int
line 274
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 304
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):string
line 330
Resolves the class name for the specified model object, allowing dynamic class handling in Phlo.
$namestatic
model :: objShortName ($class = null):string
line 331
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:array
line 333
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:array
line 339
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:array
line 345
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:\PDO
line 12
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:\PDO
line 12
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:string
line 13
Returns the field name wrapped in double quotes for PostgreSQL compatibility.
dqprop
%PostgreSQL -> insertIgnore:string
line 14
Inserts a new record into a PostgreSQL database, ignoring the operation if a record with the same unique key already exists.
voidprop
%PostgreSQL -> insertOnConflict:string
line 15
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 21
Asks for the last id inside a savepoint, so a failed lastval() cannot abort the transaction.
$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):array
line 11
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:array
line 13
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'):bool
line 14
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 15
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 16
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):array
line 17
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 18
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 20
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 11
Retrieves the class type of the current query object.
prop
%query -> conditions
line 12
Defines conditions for filtering results in a query.
[]prop
%query -> bindings
line 13
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 14
Specifies the field by which the results of a query should be ordered.
prop
%query -> limitVal
line 15
Sets the maximum number of results to return from a query in Phlo.
prop
%query -> offsetVal
line 16
Retrieves the current offset value for pagination in a query.
method
%query -> fq:string
line 17
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):string
line 18
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):static
line 24
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):static
line 25
Filters results where the specified column is not equal to the given value.
$this->where($this->q($column)." != ?", $value)method
%query -> gt ($column, $value):static
line 26
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):static
line 27
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):static
line 28
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):static
line 29
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):static
line 30
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):static
line 31
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):static
line 32
Checks if the specified column in the query is null.
$this->where($this->q($column)." IS NULL")method
%query -> notNull ($column):static
line 33
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):static
line 34
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):static
line 35
Executes a raw SQL query with the provided bindings, allowing for dynamic query construction.
$this->where($sql, ...$bindings)method
%query -> where ($condition, ...$values):static
line 36
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):static
line 42
Sets the order for the query using the specified $order value and returns the current instance.
$this->orderBy = $order
return $thismethod
%query -> limit ($limit):static
line 47
Sets the maximum number of results to return from a query, defined by the $limit parameter.
$this->limitVal = $limit
return $thismethod
%query -> offset ($offset):static
line 52
Sets the offset value for the query, allowing for pagination of results.
$this->offsetVal = $offset
return $thismethod
%query -> build:array
line 56
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:array
line 64
Retrieves a collection of records from the specified class using the provided build parameters.
($class = $this->class) && $class::records(...$this->build)prop
%query -> record:?model
line 65
Retrieves a record from the specified class using the provided build parameters.
($class = $this->class) && $class::record(...$this->build)prop
%query -> column:array
line 66
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 67
Retrieves an item from a class using the provided build parameters.
($class = $this->class) && $class::item(...$this->build)prop
%query -> count
line 68
Returns the total number of records in the specified class using the recordCount method.
($class = $this->class) && $class::recordCount(...$this->build)method
%query -> delete:int
line 69
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 12
This property holds the handle to the SQLite database connection, allowing interaction with the database.
"SQLite/$file"method
%SQLite -> __construct (private string $file)
line 13
Initializes a new SQLite instance with the specified database file.
prop
%SQLite -> PDO:\PDO
line 14
Creates a new PDO instance for SQLite using the specified file.
new PDO('sqlite:'.$this->file)prop
%SQLite -> insertIgnore:string
line 15
Inserts a new record into the SQLite database, ignoring the operation if a record with the same primary key already exists.
' OR IGNORE'Last updated on 23 August 2026