MySQLManager.

A Flutter-based MySQL admin client — saved connections, browse databases → tables → rows, PK-safe CRUD, plus a free-form SQL shell; one codebase, five platforms.

Year2026
RoleSolo · flutter + sql
Timeline3 weeks
Status● Live · self-use

01.Overview

The big picture

Every DBA or backend dev hits this once: you are at a café and your boss pings "check the orders table, two rows are in a weird state". Opening a laptop and TablePlus is five minutes; phpMyAdmin needs a public port. I wanted a thin MySQL client straight on the phone — type host, port, user, log in, done. No proxy.

Mysql-manager-mobile is a Flutter app powered by mysql_client (a pure-Dart driver, no native binary needed) talking to MySQL directly over TCP. It saves connection profiles, auto-reconnects to the last one used, browses databases → tables → rows, edits rows by primary key, and ships a free-form SQL shell. The same codebase builds for Android, iOS, macOS, Linux and Windows — I now run it on an iPad for ~90% of my casual database check-ins.

02.Features

What it does
  • 01
    Saved connectionsList · edit · auto-reconnect last used

    Each profile has name / host / port / user / password / autoReconnect. They live in one JSON file under Directory.systemTemp via the SessionStore. On launch, if the last-used profile has autoReconnect=true, the app connects right away — one less keystroke.

  • 02
    Three-level browserdatabases → tables → rows · pull-to-refresh

    SHOW DATABASES → database list; SHOW TABLES FROM <db> → table list; SELECT * FROM db.table LIMIT 200 → row preview. Each level has its own icon (storage / table / row), native pull-to-refresh and breadcrumb-style back navigation.

  • 03
    PK-safe CRUDInsert · update · delete · LIMIT 1

    The Insert form is generated from SHOW COLUMNS with a Set NULL checkbox per field. Update / Delete always carry a WHERE: primary-key columns first (Key=PRI), or every-column equality as a fallback. Every statement ends with LIMIT 1 — no accidental whole-table updates.

  • 04
    Free-form SQL shellAuto-detect SELECT vs DML

    The Query screen is a textarea + Run button. The service classifies: SELECT / SHOW / DESC / EXPLAIN render as a horizontally-scrollable DataTable; everything else returns affected rows + last insert id. Parameters use named placeholders (:v_xxx); identifiers are backtick-escaped.

  • 05
    5 platforms · 1 codebaseAndroid · iOS · macOS · Linux · Windows

    Because mysql_client is pure Dart (needs only TCP), builds drop straight onto all five Flutter desktop / mobile platforms. Material 3 UI (teal seed #0D7A65); the DataTable scrolls horizontally so tablets feel great and phones still usable.

03.Tech stack

Tools used
AppFlutter 3.11 · Dart · Material 3 (teal seed #0D7A65) · DataTable + Scrollbar · TextField + AlertDialog
MySQL drivermysql_client ^0.0.27 · pure-Dart TCP client · named parameters (:v_xxx) · IResultSet → row.assoc() / row.colByName()
SafetyIdentifier backtick-escape (` → ``) · WHERE required on UPDATE/DELETE · LIMIT 1 on every mutation · _safeParam normalises column names to [a-zA-Z0-9_]
Storagedart:io File JSON in Directory.systemTemp · ConnectionStoreState + ConnectionProfile (id / name / host / port / user / password / autoReconnect)
UXFriendly errors: Android localhost → hint 10.0.2.2 or LAN IP · connection refused → hint bind-address + firewall · access denied → user/password / remote permission
PlatformsAndroid · iOS · macOS · Linux · Windows · one Dart codebase, no native plugin

04.How it works

Architecture

All SQL lives in a single MySqlAdminService class holding one MySQLConnection?. Each screen calls 4-5 methods (getDatabases, getTables, getTableSnapshot, insertRow / updateRow / deleteRow, executeCustomQuery) and renders the result. Keeping it isolated means later swapping the driver (perhaps to mysql1 or a native FFI driver) does not touch any UI.

Updating a single row is the most important piece. updateRow calls SHOW COLUMNS to find any column with Key=PRI; if a PK exists, WHERE uses it, otherwise WHERE compares every column to its old value. NULL values are translated to IS NULL (never = NULL, which is always false). Every statement ends with LIMIT 1. If the WHERE somehow ends up empty, an Exception is thrown before MySQL even sees the query.

Design decision

"UPDATE and DELETE never run without a WHERE. That is a rule the service imposes on itself, not on the user. A DB admin app on a phone — fat fingers, flaky network, dying battery — cannot afford to allow 'oops, I just UPDATE-ed the whole table'."

05.Comments

Leave a few words

No comments yet.

Xem tiep
python-ocr preview
O
Captcha OCR

CaptchaOCR is a FastAPI micro-service that accepts a 4-digit captcha image in base64 and returns the corresponding integer. The ddddocr pretrained model is loaded once at process startup — every subsequent request is pure inference, with latency in the range of a few tens of milliseconds per image. The service is deployed via PM2 with auto-restart and a hard RAM cap, keeping it stable over long periods without manual oversight.

chatgpt-auto-login preview
G
GPT Login

A NestJS API that auto-logs into ChatGPT via puppeteer-real-browser (Cloudflare anti-bot bypass), supports email OTP, persists the session for route /ask reuse and directly promt promt, and runs an hourly cron that pings Telegram when the session expires. This allows me to send prompts and receive responses directly through the API without needing to open a browser.

hotel preview
H
Hotel management

Hotel Management is an internal hotel administration system built for front desk staff and operations managers. The entire core workflow runs within a single system: accepting reservations from walk-in guests or online channels, handling check-in and check-out, recording ancillary services incurred during the stay, and automatically generating invoices at checkout. Permissions are scoped down to individual actions — receptionists, cashiers, and managers each have different screens and access levels. Every change in the system is written to a full audit log, with enough detail to trace back anything when needed.

random-tools preview
R
Random Tools

RandomKit is a lightweight collection of randomisation tools that runs entirely client-side — no server, no data sent anywhere. It includes the tools people actually reach for: a customisable spinner with fair probabilities and transparent percentage display, duck racing, a draw lots picker, coin flip, dice roller, random number generator, password generator, and a random location picker on a map. The interface supports both Vietnamese and English, with clean SEO structure so each individual tool is independently discoverable.