/** * Fetch the next incremental value for the specified field. * If no field name is specified, it will use the primary key * field by default. */ public function next ($field = false) { if ($field === false) { $field = $this->key; } $res = DB::shift ( 'select (' . Model::backticks ($field) . ' + 1)' . ' from ' . Model::backticks ($this->table) . ' order by ' . Model::backticks ($field) . ' desc' . ' limit 1' ); if (! $res) { return 1; } return $res; }
/** * Performs a batch of changes wrapped in a database transaction. * The batch `$task` can be an array of items to insert at once, * or a closure function that executes a series of tasks and * performs whatever logic necessary. If any insert fails, or if * the function returns false, the transaction will be rolled * back, otherwise it will be committed. For databases that support * it, records will be inserted using a single SQL insert statement * for greater efficiency. */ public static function batch($tasks) { DB::execute('begin'); if ($tasks instanceof Closure) { if ($tasks() === false) { self::$batch_error = DB::error(); DB::execute('rollback'); return false; } } elseif (is_array($tasks)) { // Check the driver type, because SQLite doesn't support // multiple row inserts $db = DB::get_connection(1); if (!$db) { self::$batch_error = 'No database connection'; return false; } if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) === 'sqlite') { $class = get_called_class(); foreach ($tasks as $task) { $o = new $class($task); if (!$o->put()) { self::$batch_error = $o->error; DB::execute('rollback'); return false; } } return DB::execute('commit'); } // Build the multi-row insert statement $sql = 'insert into `' . $this->table . '` ('; $data = array(); // Figure out how many placeholders are needed per record $ins = array(); $len = count($tasks[0]); for ($i = 0; $i < $len; $i++) { $ins[] = '?'; } // Add fields to statement $sql .= join(', ', Model::backticks(array_keys($tasks[0]))) . ') values '; $sep = ''; // Add each record to the statement foreach ($tasks as $task) { $data = array_merge($data, array_values($task)); $sql .= $sep . '(' . join(', ', $ins) . ')'; $sep = ', '; } if (!DB::execute($sql, $data)) { self::$batch_error = DB::error(); DB::execute('rollback'); return false; } } return DB::execute('commit'); }