Mengelola database SQLite di perangkat dengan Eloquent ORM dan migration Laravel: CRUD offline-first, konfigurasi database, strategi sinkronisasi ketika online, serta repository pattern untuk data catatan offline.

Setelah di episode 9 kita mengakses GPS, haptic feedback, dan clipboard, pada episode ini kita masuk ke database offline: cara menyimpan data di perangkat menggunakan SQLite yang dikelola oleh Eloquent ORM dan migration Laravel. Ini adalah inti dari arsitektur offline-first — aplikasi berfungsi tanpa koneksi internet, dan data disinkronkan ke server saat online.
SQLite adalah pilihan ideal untuk mobile: tanpa server, zero-configuration, dan sudah terbundel di iOS & Android. Dengan Eloquent, kalian menggunakan syntax Laravel yang sama persis — hanya beda di konfigurasi koneksi.
<?php
return [
'default' => env('DB_CONNECTION', 'sqlite'),
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
// NativePHP menggunakan path relatif ke app bundle
'database' => database_path('database.sqlite'),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
],
];Di NativePHP, database_path() meresol ke direktori writable di dalam app bundle. SQLite database dibuat otomatis jika belum ada — tidak perlu setup server atau kredensial.
Gunakan migration yang sama persis seperti web:
php artisan make:migration create_notes_table<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('notes', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->boolean('completed')->default(false);
$table->timestamp('synced_at')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('notes');
}
};Perhatikan kolom synced_at — ini adalah flag yang menandai apakah record sudah disinkronkan ke server. Kita gunakan ini di strategi sync episode 15.
php artisan migrateEloquent berfungsi persis seperti biasa — tetapi semua operasi terjadi di SQLite lokal:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Note extends Model
{
protected $fillable = ['title', 'content', 'completed', 'synced_at'];
public function markUnsynced(): void
{
$this->update(['synced_at' => null]);
}
public function markSynced(): void
{
$this->update(['synced_at' => now()]);
}
public function scopeUnsynced($query)
{
return $query->whereNull('synced_at');
}
}<?php
use App\Models\Note;
// Create
$note = Note::create([
'title' => 'Belajar NativePHP',
'content' => 'Episode 10: Database offline',
]);
// Read
$notes = Note::where('completed', false)->get();
$note = Note::find(1);
// Update
$note->update(['completed' => true]);
// Delete
$note->delete();Semua operasi ini berjalan offline — tidak ada koneksi internet yang dibutuhkan. Karena SQLite berjalan di perangkat, kecepatan operasi sangat tinggi bahkan untuk ribuan record.
Untuk aplikasi yang lebih besar, gunakan repository pattern untuk memisahkan logic bisnis dari akses data:
<?php
namespace App\Repositories;
use App\Models\Note;
class NoteRepository
{
public function getUnsynced(): \Illuminate\Database\Eloquent\Collection
{
return Note::unsynced()->get();
}
public function create(array $data): Note
{
return Note::create($data);
}
public function markSynced(array $ids): void
{
Note::whereIn('id', $ids)->update([
'synced_at' => now(),
]);
}
public function getPendingCount(): int
{
return Note::unsynced()->count();
}
}Repository ini menjadi titik pusat semua operasi data — memudahkan testing, refactor, dan strategi sync yang akan kita bahas nanti.
Prinsip offline-first: app harus berfungsi tanpa internet, bukan "app berhenti saat offline":
synced_at.Tip
Selalu tampilkan indikator status: "Online" atau "Offline — X catatan perlu disinkronkan". User perlu tahu apakah data mereka sudah aman di server atau masih lokal.
Inti yang harus dibawa pulang:
synced_at menandai record yang belum disinkronkan.Di episode 11 selanjutnya, kita akan membahas Proses Background & Persistent Mode — bagaimana PHP runtime tetap hidup, menjalankan background task, polling, dan perbedaan background execution antara iOS dan Android. Sampai jumpa di episode 11!