function insert()
{
$args = [];
$actr = 0;
$nctr = 0;
$fields = '';
$values = '';
$filter = '';
$pkeys = [];
$nkeys = [];
$ckeys = [];
$inc = NULL;
foreach ($this->fields as $key => $field) {
if ($field['pkey']) {
$pkeys[$key] = $field['previous'];
}
}
if (isset($this->trigger['beforeinsert']) && \Base::instance()->call($this->trigger['beforeinsert'], [$this, $pkeys]) === FALSE) {
return $this;
}
foreach ($this->fields as $key => &$field) {
if ($field['pkey']) {
$field['previous'] = $field['value'];
if (!$inc && $field['pdo_type'] == \PDO::PARAM_INT && empty($field['value']) && !$field['nullable']) {
$inc = $key;
}
$filter .= ($filter ? ' AND ' : '') . $this->db->quotekey($key) . '=?';
$nkeys[$nctr + 1] = [$field['value'], $field['pdo_type']];
$nctr++;
}
if ($field['changed'] && $key != $inc) {
$fields .= ($actr ? ',' : '') . $this->db->quotekey($key);
$values .= ($actr ? ',' : '') . '?';
$args[$actr + 1] = [$field['value'], $field['pdo_type']];
$actr++;
$ckeys[] = $key;
}
$field['changed'] = FALSE;
unset($field);
}
if ($fields) {
$this->db->exec((preg_match('/mssql|dblib|sqlsrv/', $this->engine) && array_intersect(array_keys($pkeys), $ckeys) ? 'SET IDENTITY_INSERT ' . $this->table . ' ON;' : '') . 'INSERT INTO ' . $this->table . ' (' . $fields . ') ' . 'VALUES (' . $values . ')', $args);
$seq = NULL;
if ($this->engine == 'pgsql') {
$names = array_keys($pkeys);
$aik = end($names);
if ($this->fields[$aik]['pdo_type'] == \PDO::PARAM_INT) {
$seq = $this->source . '_' . $aik . '_seq';
}
}
if ($this->engine != 'oci' && !($this->engine == 'pgsql' && !$seq)) {
$this->_id = $this->db->lastinsertid($seq);
}
// Reload to obtain default and auto-increment field values
if ($inc || $filter) {
$this->load($inc ? [$inc . '=?', $this->db->value($this->fields[$inc]['pdo_type'], $this->_id)] : [$filter, $nkeys]);
}
if (isset($this->trigger['afterinsert'])) {
\Base::instance()->call($this->trigger['afterinsert'], [$this, $pkeys]);
}
}
return $this;
}