tables()->where('name', $table)->first(); $revision = $tableModel->activeRevision; return view('table.view', [ 'table' => $tableModel, 'revision' => $revision, 'columns' => Column::columnsFromJson(json_decode($revision->columns)), 'rows' => $revision->rows, ]); } /** * SHow a form for creating a new table * * @return \Illuminate\Http\Response */ public function create() { $exampleColumns = "latin,string,Latin Name\n" . "common,string,Common Name\n" . "lifespan,int,Lifespan (years)"; $exampleData = "Mercenaria mercenaria,hard clam,40\n" . "Magallana gigas,pacific oyster,30\n" . "Patella vulgata,common limpet,20"; return view('table.create', compact('exampleColumns', 'exampleData') ); } public function storeNew(Request $request) { /** @var User $u */ $u = \Auth::user(); $this->validate($request, [ 'name' => 'required', 'title' => 'string', 'description' => 'string|nullable', 'license' => 'string|nullable', 'origin' => 'string|nullable', 'columns' => 'required', 'data' => 'string|nullable', ]); // Check if table name is unique for user $tabName = $request->get('name'); if ($u->tables()->where('name', $tabName)->exists()) { return $this->backWithErrors([ 'name' => "A table called \"$tabName\" already exists in your account.", ]); } // Parse and validate the columns specification /** @var Column[] $columns */ $columns = []; $colTable = array_map('str_getcsv', explode("\n", $request->get('columns'))); foreach ($colTable as $col) { $col = array_map('trim', $col); if (count($col) < 2) { return $this->backWithErrors([ 'columns' => "All columns must have at least name and type.", ]); } try { $columns[] = new Column([ 'name' => $col[0], 'type' => $col[1], 'title' => count($col) >= 3 ? $col[2] : $col[0], // title falls back to =name if not specified, ]); } catch (\Exception $e) { return $this->backWithErrors(['columns' => $e->getMessage()]); } } $rowTable = array_map('str_getcsv', explode("\n", $request->get('data'))); // Preparing data to insert into the Rows table $rowsData = null; try { $rowsData = array_map(function ($row) use ($columns) { if (count($row) != count($columns)) { throw new NotApplicableException("All rows must have " . count($columns) . " fields."); } $parsed = []; foreach ($row as $i => $val) { $key = $columns[$i]->name; $parsed[$key] = $columns[$i]->cast($val); } return [ 'data' => json_encode($parsed), 'refs' => 1, ]; }, $rowTable); } catch (\Exception $e) { return $this->backWithErrors(['columns' => $e->getMessage()]); } $revision = Revision::create([ 'refs' => 1, // from the new table 'note' => "Initial revision of table $u->name/$tabName", 'columns' => json_encode($columns), ]); $table = Table::create([ 'owner_id' => $u->id, 'revision_id' => $revision->id, 'name' => $tabName, 'title' => $request->get('title'), 'description' => $request->get('description'), 'license' => $request->get('license'), 'origin' => $request->get('origin'), ]); // Attach the revision to the table, set as current $table->revisions()->attach($revision); $table->activeRevision()->associate($revision); // Spawn the rows, linked to the revision $revision->rows()->createMany($rowsData); // Now we create rows, a revision pointing to them, and the table using it. return "Ok."; } }