pgkiln 0.45.0 → 0.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/db/migrations/106_form_designer.sql +102 -0
- package/db/migrations/107_app_version.sql +9 -0
- package/db/migrations/108_sql_history.sql +25 -0
- package/docs/apex-feature-parity.md +33 -4
- package/docs/guide/03-builder.md +123 -28
- package/docs/guide/04-pages-and-regions.md +74 -2
- package/docs/guide/05-items.md +14 -2
- package/docs/guide/08-security.md +1 -1
- package/docs/guide/09-reference.md +1 -1
- package/docs/guide/10-tutorial.md +1 -1
- package/docs/guide/11-from-apex.md +2 -1
- package/docs/guide/12-development.md +26 -3
- package/docs/guide/16-files.md +2 -2
- package/examples/hr/hr_61_form_designer.sql +80 -0
- package/package.json +1 -1
- package/public/app.css +62 -2
- package/public/app.js +244 -35
- package/public/builder.css +21 -1
- package/public/builder.js +67 -0
- package/public/sw.js +2 -1
- package/public/worksheet.css +244 -0
- package/public/worksheet.js +665 -0
- package/src/app.ts +9 -1
- package/src/builder/ai-builder.ts +3 -3
- package/src/builder/appwizard.ts +22 -6
- package/src/builder/arrange.ts +33 -12
- package/src/builder/code-editor.ts +1 -1
- package/src/builder/components.ts +1 -1
- package/src/builder/designer.ts +44 -17
- package/src/builder/errors.ts +65 -0
- package/src/builder/form-designer.ts +229 -0
- package/src/builder/locks.ts +6 -0
- package/src/builder/newapp.ts +2 -1
- package/src/builder/object-actions.ts +166 -0
- package/src/builder/object-browser.ts +111 -33
- package/src/builder/querybuilder.ts +1 -1
- package/src/builder/region-help.ts +2 -0
- package/src/builder/region-settings.ts +2 -0
- package/src/builder/reporter.ts +1 -1
- package/src/builder/routes.ts +7 -5
- package/src/builder/sampledata.ts +2 -2
- package/src/builder/scripts.ts +3 -3
- package/src/builder/search.ts +3 -3
- package/src/builder/shared.ts +2 -2
- package/src/builder/sql.ts +15 -73
- package/src/builder/table-editor.ts +219 -0
- package/src/builder/ui.ts +5 -3
- package/src/builder/unload.ts +8 -4
- package/src/builder/worksheet.ts +569 -0
- package/src/builder/workspaces.ts +1 -1
- package/src/cli/replace.ts +10 -0
- package/src/i18n/ar.ts +62 -0
- package/src/i18n/cs.ts +62 -0
- package/src/i18n/da.ts +62 -0
- package/src/i18n/de.ts +62 -0
- package/src/i18n/el.ts +62 -0
- package/src/i18n/es.ts +62 -0
- package/src/i18n/fi.ts +62 -0
- package/src/i18n/fr.ts +62 -0
- package/src/i18n/he.ts +62 -0
- package/src/i18n/it.ts +62 -0
- package/src/i18n/ja.ts +62 -0
- package/src/i18n/ko.ts +62 -0
- package/src/i18n/nb.ts +62 -0
- package/src/i18n/pl.ts +62 -0
- package/src/i18n/pt.ts +62 -0
- package/src/i18n/ru.ts +62 -0
- package/src/i18n/sv.ts +62 -0
- package/src/i18n/tr.ts +62 -0
- package/src/i18n/uk.ts +62 -0
- package/src/i18n/zh.ts +62 -0
- package/src/i18n.ts +124 -0
- package/src/metadata.ts +4 -2
- package/src/runtime/devbar.ts +1 -1
- package/src/runtime/facet-state.ts +10 -5
- package/src/runtime/facets.ts +29 -5
- package/src/runtime/form-designer.ts +676 -0
- package/src/runtime/grid.ts +15 -8
- package/src/runtime/items.ts +33 -21
- package/src/runtime/lists.ts +1 -1
- package/src/runtime/pdf.ts +2 -1
- package/src/runtime/regions.ts +4 -0
- package/src/runtime/render.ts +7 -3
- package/src/runtime/report.ts +2 -2
- package/src/runtime/routes.ts +3 -1
- package/src/runtime/smart-filters.ts +2 -1
- package/src/runtime/tasks.ts +6 -3
- package/src/sqlformat.ts +208 -0
- package/src/sqlplan.ts +133 -0
- package/src/sqlscript.ts +6 -2
- package/src/sqlworksheet.ts +278 -0
- package/src/tabledef.ts +226 -0
- package/src/unload.ts +14 -3
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
-- ---------------------------------------------------------------------
|
|
2
|
+
-- 106: Form Designer: the application's administrators build their own
|
|
3
|
+
-- data entry forms in the running application.
|
|
4
|
+
--
|
|
5
|
+
-- The developer places a region of type 'form_designer' and lists in its
|
|
6
|
+
-- settings (config.sources) the tables and views it offers: the columns
|
|
7
|
+
-- forms may show and change, the column that identifies a row, and what
|
|
8
|
+
-- forms on it may do at most (add, change, delete rows). Who may design
|
|
9
|
+
-- forms is an authorization scheme (config.design_authz); without one
|
|
10
|
+
-- nobody can. Those settings are part of the region, so they travel with
|
|
11
|
+
-- the application export.
|
|
12
|
+
--
|
|
13
|
+
-- A user form is a definition (source, fields with labels, help, required,
|
|
14
|
+
-- display and default, the columns of its row list, the actions it allows)
|
|
15
|
+
-- under a name, kept per region; published forms are used by everyone who
|
|
16
|
+
-- can see the region, drafts only by designers. User forms are data of the
|
|
17
|
+
-- installation (like meta.data_report): not part of the application export,
|
|
18
|
+
-- kept when an application is replaced. Applications reach the table only
|
|
19
|
+
-- through meta.user_forms and the two functions; the runtime checks every
|
|
20
|
+
-- definition against the region's offered columns before it renders or
|
|
21
|
+
-- saves, and reads and writes rows as the application's database role, so
|
|
22
|
+
-- grants and row level security apply.
|
|
23
|
+
-- ---------------------------------------------------------------------
|
|
24
|
+
alter table meta.region drop constraint region_type_check;
|
|
25
|
+
alter table meta.region add constraint region_type_check
|
|
26
|
+
check (type in ('report', 'form', 'chart', 'cards', 'static', 'grid', 'calendar', 'dynamic', 'facets', 'tasks', 'workflows', 'map', 'tree',
|
|
27
|
+
'template_component', 'smart_filters', 'display_selector', 'list', 'data_reporter', 'ai_assistant', 'plugin', 'url', 'search',
|
|
28
|
+
'login', 'form_designer'));
|
|
29
|
+
|
|
30
|
+
create table meta.user_form (
|
|
31
|
+
id serial primary key,
|
|
32
|
+
app_id int not null references meta.app on delete cascade,
|
|
33
|
+
region_id int not null references meta.region on delete cascade,
|
|
34
|
+
name text not null check (length(btrim(name)) between 1 and 80),
|
|
35
|
+
description text check (length(description) <= 500),
|
|
36
|
+
published boolean not null default false,
|
|
37
|
+
definition jsonb not null check (jsonb_typeof(definition) = 'object' and length(definition::text) <= 32000),
|
|
38
|
+
created_by text not null,
|
|
39
|
+
updated_by text not null,
|
|
40
|
+
created_at timestamptz not null default now(),
|
|
41
|
+
updated_at timestamptz not null default now(),
|
|
42
|
+
unique (region_id, name)
|
|
43
|
+
);
|
|
44
|
+
create index user_form_app_idx on meta.user_form (app_id);
|
|
45
|
+
revoke all on meta.user_form from public;
|
|
46
|
+
|
|
47
|
+
create view meta.user_forms with (security_barrier) as
|
|
48
|
+
select id, region_id, name, description, published, definition, created_by, updated_by, created_at, updated_at
|
|
49
|
+
from meta.user_form
|
|
50
|
+
where app_id = meta.app_id();
|
|
51
|
+
grant select on meta.user_forms to public;
|
|
52
|
+
|
|
53
|
+
-- Save a form of a Form Designer region of the current application: a new
|
|
54
|
+
-- one (p_id null) or an existing one (p_id). Returns its id. Whether the
|
|
55
|
+
-- user may design forms (the region's authorization scheme) is checked by
|
|
56
|
+
-- the runtime before it calls this.
|
|
57
|
+
create function meta.save_user_form(p_region int, p_id int, p_name text, p_description text, p_definition jsonb, p_published boolean default false)
|
|
58
|
+
returns int
|
|
59
|
+
language plpgsql security definer set search_path = meta, pg_catalog as $$
|
|
60
|
+
declare
|
|
61
|
+
v_user text := meta.app_user();
|
|
62
|
+
v_app int := meta.app_id();
|
|
63
|
+
v_id int;
|
|
64
|
+
begin
|
|
65
|
+
if v_user is null or v_user = 'nobody' then
|
|
66
|
+
raise exception 'sign in to design forms';
|
|
67
|
+
end if;
|
|
68
|
+
if not exists (select 1 from region r join page p on p.id = r.page_id where r.id = p_region and p.app_id = v_app and r.type = 'form_designer') then
|
|
69
|
+
raise exception 'unknown form designer region %', p_region;
|
|
70
|
+
end if;
|
|
71
|
+
begin
|
|
72
|
+
if p_id is null then
|
|
73
|
+
insert into user_form (app_id, region_id, name, description, published, definition, created_by, updated_by)
|
|
74
|
+
values (v_app, p_region, btrim(p_name), nullif(btrim(p_description), ''), coalesce(p_published, false), p_definition, v_user, v_user)
|
|
75
|
+
returning id into v_id;
|
|
76
|
+
else
|
|
77
|
+
update user_form
|
|
78
|
+
set name = btrim(p_name), description = nullif(btrim(p_description), ''), published = coalesce(p_published, false),
|
|
79
|
+
definition = p_definition, updated_by = v_user, updated_at = now()
|
|
80
|
+
where id = p_id and app_id = v_app and region_id = p_region
|
|
81
|
+
returning id into v_id;
|
|
82
|
+
if v_id is null then
|
|
83
|
+
raise exception 'form % does not exist', p_id;
|
|
84
|
+
end if;
|
|
85
|
+
end if;
|
|
86
|
+
exception when unique_violation then
|
|
87
|
+
raise exception 'There is already a form named "%".', btrim(p_name) using errcode = 'P0001';
|
|
88
|
+
end;
|
|
89
|
+
return v_id;
|
|
90
|
+
end
|
|
91
|
+
$$;
|
|
92
|
+
|
|
93
|
+
-- Delete a form of a Form Designer region of the current application.
|
|
94
|
+
create function meta.delete_user_form(p_region int, p_id int) returns boolean
|
|
95
|
+
language sql security definer set search_path = meta, pg_catalog as $$
|
|
96
|
+
with d as (delete from user_form where id = p_id and region_id = p_region and app_id = meta.app_id()
|
|
97
|
+
and meta.app_user() is not null and meta.app_user() <> 'nobody' returning 1)
|
|
98
|
+
select exists (select 1 from d)
|
|
99
|
+
$$;
|
|
100
|
+
|
|
101
|
+
revoke all on function meta.save_user_form(int, int, text, text, jsonb, boolean), meta.delete_user_form(int, int) from public;
|
|
102
|
+
grant execute on function meta.save_user_form(int, int, text, text, jsonb, boolean), meta.delete_user_form(int, int) to public;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-- ---------------------------------------------------------------------
|
|
2
|
+
-- 107: an application's version (APEX: Application Definition → Version,
|
|
3
|
+
-- "Release 1.0"), shown in the footer of its pages with "Back to top".
|
|
4
|
+
-- New applications start with 'Release 1.0'; existing ones have none (no
|
|
5
|
+
-- version in the footer) until a developer sets one in Settings. It travels
|
|
6
|
+
-- with the export like the other columns of meta.app.
|
|
7
|
+
-- ---------------------------------------------------------------------
|
|
8
|
+
alter table meta.app add column version text check (length(version) <= 40);
|
|
9
|
+
comment on column meta.app.version is 'The application''s version, e.g. Release 1.0: shown in its pages'' footer (107)';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- ---------------------------------------------------------------------
|
|
2
|
+
-- 108: the SQL Worksheet's history (sprint 92, Database Actions DA-5:
|
|
3
|
+
-- SQL History). One row per statement a developer ran in the worksheet:
|
|
4
|
+
-- the text, how it ended (ok or error), the rows and the time. Running
|
|
5
|
+
-- the same statement again right after counts on the same row (runs,
|
|
6
|
+
-- at), so repeated runs don't flood the list. Kept per developer and
|
|
7
|
+
-- workspace, at most 500 rows each (the builder deletes older ones).
|
|
8
|
+
-- The builder reads and writes it as the owner; nobody else has grants.
|
|
9
|
+
-- The activity log keeps its own 'sql_command' entries (the SQL Workshop
|
|
10
|
+
-- home's Recent SQL Commands).
|
|
11
|
+
-- ---------------------------------------------------------------------
|
|
12
|
+
create table meta.sql_history (
|
|
13
|
+
id bigint generated always as identity primary key,
|
|
14
|
+
username text not null,
|
|
15
|
+
workspace_id int not null default 1 references meta.workspace on delete cascade,
|
|
16
|
+
sql text not null check (length(sql) <= 20000),
|
|
17
|
+
status text not null check (status in ('ok', 'error')),
|
|
18
|
+
rows bigint,
|
|
19
|
+
ms int,
|
|
20
|
+
error text,
|
|
21
|
+
runs int not null default 1,
|
|
22
|
+
at timestamptz not null default now()
|
|
23
|
+
);
|
|
24
|
+
create index sql_history_user_idx on meta.sql_history (username, workspace_id, id desc);
|
|
25
|
+
comment on table meta.sql_history is 'The SQL Worksheet''s history per developer and workspace (108); installation data, not exported';
|
|
@@ -7,7 +7,7 @@ open item and open an issue or pull request; see [CONTRIBUTING.md](../CONTRIBUTI
|
|
|
7
7
|
Legend: ✅ available · 🟡 partial (see notes) · ❌ not yet · ➖ not planned (a deliberate choice,
|
|
8
8
|
or better served by the PostgreSQL ecosystem; see the notes and [extensions](guide/15-extensions.md))
|
|
9
9
|
|
|
10
|
-
Last reviewed: 2026-10-
|
|
10
|
+
Last reviewed: 2026-10-16 (sprint 95: Table Properties: create, edit or copy a table in a form with a DDL preview and Apply in one transaction; sprint 94: an object's menu with Open in a panel, Quick DDL, Add index / trigger / policy and Drop with dependents; sprint 93: worksheets saved as SQL Scripts with tabs and a Files list, Format, Convert case, find and replace, bind and substitution variables; sprint 92: the worksheet's Query Result with sort, value dialog, copy and downloads, plans as a tree with the slowest step and misestimates, SQL History with status, search and run again; sprint 91: the SQL Worksheet like Database Actions' SQL: navigator, Run Statement at the cursor and Run Script with a log per statement, Explain Plan, Autotrace, notices, history, Run as an application role; sprint 90: Comment Out in the page designer, gallery labels in title case; sprint 89: the Object Browser's schema, one row of tabs, blank NULLs, Modify column; sprint 88: home cards with colour bands and round icons, the hero on the page background, a page footer with the version and Back to top; sprint 87: the Create Application wizard reloads the page list for a schema, RLS badges, the alias from the name; sprint 86: the page designer by page number, HTML error pages in the builder; sprint 85: the Form Designer, beyond APEX; sprint 84: the date picker, facet menus; sprint 83: Component Settings and Component Groups; sprint 82: Report Queries; sprint 81: Application Computations and Shortcuts in Shared Components; sprint 80: the master grid's first row selected when the page opens and after a search; grid cells as text with their format mask until edited, with cell navigation by arrow keys, Enter, F2 and Escape; sprint 79: generated dashboards with sums, donuts and lines, leaving out charts that say nothing; applications open in their own light or dark mode until the user chooses, per application; a user menu with Appearance and Sign in when signed out; the developer toolbar's App and Page texts and debug state; the report search's column scope in the magnifier; sprint 78: generated faceted search reports with one column per foreign key, the faceted search's total row count, Show all and Yes/No values, one search field, friendly headings and number formats in generated grids and master-detail pages, friendly names in the Create Application wizard's page list; sprint 77: the Page Designer's layout and tree by display position, button positions, the tree's context menu with Duplicate and Copy to other page, Show Common / Show All, Go to group and the Template Options dialog; display positions, button positions and side-column page templates at runtime; sprint 76: the interactive report's menus and pagination, date items in the date format; sprint 75: the SQL Workshop's Object Browser and tabs; sprint 74: the builder's information architecture: Shared Components grid, Settings tabs, application home search and tasks; sprint 73: the Create Application wizard on one page with page types and features; sprint 72: the runtime chrome compared with APEX 26.2's: the developer toolbar, the Iris look, the navigation bar's Help menu and Install button; sprint 71: generated applications compared with APEX 26.2's: labels, foreign key names in reports, file columns, format masks, the Home page and the dashboard; sprint 70: treemap, sunburst and timeline charts; sprint 69: dragging tasks on a Gantt chart; sprint 68: the Data Reporter's welcome page, Find my workspace; sprint 67: REST source catalogs from OpenAPI documents, a workspace's export and import (two rows added); sprint 66: a blueprint from an existing application; sprint 65: facet charts; sprint 64: approval vacation rules and expiration policies; sprint 63: range, box plot and stock charts; sprint 62: workspace preferences (SQL Workshop and RESTful services per workspace), extension links, Manage backups across applications, SQL Workshop utilities with object reports, About Database and a database monitor; sprint 61: the builder's screens compared with APEX 26.1: the workspace sign-in page, the Administration menu with workspace message, environment banner and utilization, the SQL Workshop home, the App Gallery, application groups and cross application reports (four rows added); sprint 60: isolated workspaces with their own database logins, row-level security on pgkiln's tables and workspace database roles, workspace administrators; sprint 59: the Page Designer's help pane, Quick edit from the developer toolbar; sprint 58: page groups; sprint 57: region templates hero, title bar, buttons container, inline dialog and drawer, wizard with wizard progress, the carousel; sprint 56: Generate DDL and Schema Comparison in the SQL Workshop, `pgkiln ddl` and `pgkiln compare`; sprint 55: an editable login page with a Login region and the Minimal page template, Forgot password through the application's mail service; sprint 54: interactive grid views, the single row view, group by and chart; sprint 53: application settings, user preferences and items kept per user, dynamic translations, `meta.data_export` and data export downloads, display image and geocoded address items; sprint 52: every dynamic action event and action, Ajax callbacks, an error handling function, the session timeout warning; sprint 51: checked imports, application backups, availability and Run only, feedback, type-specific attribute help; sprint 50: lost update detection, warn on unsaved changes, the URL and search regions with search configurations, the developer toolbar with a session state viewer, and e-mail through SMTP with OAuth2, Microsoft Graph, Amazon SES and HTTP APIs; import checks, application availability, property help and e-mail compared again; 2026-10-06: pgkiln 0.31.0, in progress: static application files and the Execute JavaScript dynamic action; region, item, dynamic action and process plug-ins; conditional and dynamic theme styles; XML and Excel in `meta.parse_data`, zips in SQL, `meta.v_boolean`; file items in S3-compatible object storage; map layers by the visible area and as vector tiles; a graphical query builder; tenants for workflows and tasks; application files as YAML and region static IDs; Lucide icons and icon modifiers; PWA push notifications; 0.30.0: 136 icons and an icon picker; an axe-core accessibility audit; cropping pictures; session sharing between applications; twenty-two built-in languages; 0.29.0: workspaces; the Iris base style; drawers; built-in template components including the metric card; Theme Roller dark-mode colours, live preview and template options on items and report columns; report selection across pages; instance settings; fourteen built-in languages; 0.28.0: AI with Claude and OpenAI; 0.27.0: Data Reporter; sample data generator; create application from several sheets, pasted data or existing tables; 0.26.0: working copies with a three-way merge; theme, library and boilerplate applications with subscriptions; 0.25.0: Gantt, pyramid and polar charts; map layers, clustering and server-side spatial filters; REST data sources that write back from forms and grids and synchronise into tables, OAuth2 password and refresh-token grants; debug messages per request and an install/upgrade log; `meta.web_request()` and `meta.parse_data()`; Theme Roller style variants and template options; 0.24.0: automations with several actions, error handling per row and runs from SQL; invoke-API workflow steps; Unload Data in the Data Workshop; create page wizards for cards, calendar, chart, map, faceted search, form and master-detail; create an application from a file; 0.23.0: interactive grid aggregates, frozen/moved/resized columns, layouts and saved grid reports, master-detail, row actions and copy/paste; download processes, execution chains in the background, workflow processes, branches to a function's URL or another app, the Dialog Closed event; number format masks, automatic time zone, runtime messages in German, French and Spanish; SQL scripts, Quick SQL, a query builder, XML loading and data load definitions; custom authentication, lists, page and application locks with developer comments, supporting objects; 0.22.0: keyset paging, report PDFs and REST collections streamed from a cursor, database-account authentication; 0.21.0: HTTP-header authentication behind a reverse proxy; 0.20.0: a popup list of values with server-side search; 0.19.0: row-range pagination, maximum row counts and row limits, lazy loading and caching of regions, streamed CSV/Excel downloads; 0.18.0: calendar week/day/list views with drag and drop, bubble/gauge/funnel/radar charts and drill-down, smart filters, a region display selector and more facet types, computations, conditional branches, build options, menu buttons, REST data sources and web credentials, rich text/Markdown, rating, combobox, date range and QR code items; 0.17.0: an App Builder home, workspace dashboard and utilities like APEX's; 0.16.0: a Page Designer with drag-and-drop layout, a code editor with autocomplete, template components and plug-ins, parallel branches and versions of workflows, the `pgkiln` command line with one file per component; 0.15.0: drop and paste files, heat maps, filtering a report by the map area; 0.14.0: stacked, combo, scatter and pie charts, several files per upload item; 0.13.0: map and tree regions; 0.12.0: REST modules in the builder; 0.11.0: workflows and Progressive Web Apps; 0.10.0: LDAP, SAML, "Keep me signed in", document templates, JSON loading, approvals and the task list; pgkiln installs no application, HR is an example).
|
|
11
11
|
|
|
12
12
|
## At a glance
|
|
13
13
|
|
|
@@ -38,7 +38,7 @@ two, REST source catalogs and the workspace export, with their features.)
|
|
|
38
38
|
| App Builder: create, edit, delete, run apps | ✅ | Builder at `/builder` |
|
|
39
39
|
| Create application wizard | ✅ | Blank app with its own database role and schema, started from a **boilerplate application** if wanted; **from a file**: CSV/TSV/XLSX/JSON/XML, where an Excel workbook with several sheets (or JSON with several arrays) becomes several tables, with a preview to include or leave out each sheet, edit table/column names, types and primary keys, and **foreign keys proposed** from matching columns; **from pasted data** (CSV/TSV text); **from existing tables** (pick the tables and views of a schema). Each gives a report and form per table, navigation and an optional dashboard (a chart per table), plus an optional faceted search for a single table, all created in one transaction. (sprint 73) **One page like APEX's**: name, icon and description, appearance (theme style, side or top menu, accent), a **page type per table** (interactive report with form, faceted search, cards, calendar, master detail, interactive grid, report, none; large tables proposed as a grid), **features** (About page, access control roles, activity reporting, feedback, theme style selection, PWA, push), settings (alias, authentication, first user, language) and a boilerplate under Advanced; a progress message, then straight to the new application. (sprint 71) The generated pages read like APEX's: human labels (abbreviations, run-together words, column and table comments), plural page and menu names with singular form titles, foreign keys shown by the parent's name in reports, `bytea` columns as one file item with their name/mime/size/updated columns, number format masks, a pencil per report row, the Dashboard after Home with *(none)* and top-N charts, and a Home page with a hero and a card per page. **Missing:** blueprints (26.1) |
|
|
40
40
|
| Create page wizards | ✅ | Report and form, interactive grid, form, cards, calendar, chart, map, faceted search and master-detail (stacked grids) from any table or view, with defaults from the catalog (columns, key, dates, positions, foreign keys), an optional modal form page and a navigation entry; also from SQL (`meta.generate_page`). No side-by-side or drill-down master-detail, no wizard for smart filters or trees |
|
|
41
|
-
| Page Designer | ✅ | IDE-style window (dark or light): component tree, a layout canvas with drag and drop (with keyboard and button alternatives) and a gallery of regions, items and buttons, a filterable property editor; undo/redo; panes become tabs on phones. Settings forms for report, grid, chart, cards, calendar, faceted search, smart filters, display selector, map, tree and template component regions. A code editor for SQL, PL/pgSQL, JSON and HTML with highlighting and autocomplete of tables, columns and `:ITEM` binds (no extra libraries). Drag and drop needs a mouse; on touch screens the Arrange buttons move components. (sprint 77) The layout draws the page template's display positions (banner, breadcrumb bar, left/right column, body, footer) as drop zones and a region's button positions; the rendering tree groups by position and has a context menu (create in or below, Duplicate, Copy to other page, expand/collapse all, delete); the property editor has Common / All, Go to group and a Template Options dialog; a page number in the toolbar. No nested regions (APEX's sub regions) and no Comment Out |
|
|
41
|
+
| Page Designer | ✅ | IDE-style window (dark or light): component tree, a layout canvas with drag and drop (with keyboard and button alternatives) and a gallery of regions, items and buttons, a filterable property editor; undo/redo; panes become tabs on phones. Settings forms for report, grid, chart, cards, calendar, faceted search, smart filters, display selector, map, tree and template component regions. A code editor for SQL, PL/pgSQL, JSON and HTML with highlighting and autocomplete of tables, columns and `:ITEM` binds (no extra libraries). Drag and drop needs a mouse; on touch screens the Arrange buttons move components. (sprint 77) The layout draws the page template's display positions (banner, breadcrumb bar, left/right column, body, footer) as drop zones and a region's button positions; the rendering tree groups by position and has a context menu (create in or below, Duplicate, Copy to other page, expand/collapse all, (sprint 90) Comment out with a COMMENTED_OUT build option, delete; no Create Sub Region: no nested regions); the property editor has Common / All, Go to group and a Template Options dialog; a page number in the toolbar. No nested regions (APEX's sub regions) and no Comment Out |
|
|
42
42
|
| Shared components | ✅ | (sprint 74) A grid of ten groups with counts like APEX's, a searchable, sortable list per type with Create, and Settings-backed types linking to their Settings tab ([mapping below](#shared-components-apex-links-and-pgkiln)). Navigation menu, **lists** (static entries with nesting, badges, conditions, authorization and build options, or a query; for list regions, the navigation menu and the navigation bar), authorization schemes, build options, lists of values, application items and processes, access control, globalization, template components and plug-ins, web credentials, REST data sources, data load definitions, supporting objects |
|
|
43
43
|
| Export / import | ✅ | `meta.export_app()` / `meta.import_app()`: portable JSON, also in the builder (new applications; `pgkiln import --replace` and the MCP `import_app` update one in place, live for every user at the commit). (sprint 51) **Checked imports**: `pgkiln import --check` (`--dry-run`, `--force`), the MCP import (by default) and the builder's import run the Advisor inside the import's transaction (SQL planned as the application's role: missing tables, columns, functions, types, grants; references) and refuse on errors, so nothing changes; APEX doesn't check. The version an import replaces is [backed up](guide/03-builder.md#backups) first ([chapter 18](guide/18-cli.md#checking-before-an-import)) |
|
|
44
44
|
| APEXlang: human-readable, diffable app files; static IDs (26.1) | ✅ | `pgkiln export --format dir`: one JSON file per component with sorted keys, SQL and HTML in sibling files, references by static id instead of database ids; `pgkiln import --replace` updates an app in place, `pgkiln diff` compares ([chapter 18](guide/18-cli.md)). (0.31) **`--format text`**: the same files as YAML (a strict subset any YAML tool reads) with the SQL and templates inline, read back losslessly ([text files](guide/18-cli.md#text-files-apexlang)); regions have a stored **Static ID** (exported as their key, rendered as `data-static-id`), other components are named by their stored names. The syntax is YAML rather than APEXlang's own, so APEXlang files don't import |
|
|
@@ -176,7 +176,7 @@ two, REST source catalogs and the workspace export, with their features.)
|
|
|
176
176
|
| Translated applications (26.1: text-message-based translation of one app) | ✅ | One app with translations, like 26.1; XLIFF 1.2 and CSV export/import, coverage per language |
|
|
177
177
|
| Text messages (`APEX_LANG.MESSAGE`, `&APP_TEXT$…`) | ✅ | `meta.message()`, `&APP_TEXT$NAME.`, fallback to the base and primary language |
|
|
178
178
|
| Language from browser, preference or session | ✅ | Browser, user preference or primary; `?lang=`; right-to-left languages |
|
|
179
|
-
| Date and timestamp format masks | ✅ | Per app or per language; (sprint 76) date items show and read the application's date format (or their own) with a calendar button |
|
|
179
|
+
| Date and timestamp format masks | ✅ | Per app or per language; (sprint 76) date items show and read the application's date format (or their own) with a calendar button; (sprint 84) pgkiln's date picker (keyboard, week start, Today, Clear) for date items, date ranges, grid date cells and facet date ranges; timestamps keep the browser's field |
|
|
180
180
|
| Dynamic translations (`APEX_LANG.LANG`: translated data values, e.g. list of values entries) | ✅ | (sprint 53) Shared Components → Dynamic translations; `meta.lang(text)` in a query returns the value in the session's language (base language fallback); exported with the application |
|
|
181
181
|
| Number format masks, automatic time zone | ✅ | Oracle-style number masks (`999G999G990D00`, `FML…`, `0000`, `%`, `S`/`MI`/`PR`, `EEEE`, `X`, `RN`) on report, grid and cards columns, charts and number/display items, in the language's separators with the app's currency; Automatic Time Zone (browser, My account, app or database), `timestamptz` shown in it ([chapter 14](guide/14-globalization.md)) |
|
|
182
182
|
|
|
@@ -184,7 +184,7 @@ two, REST source catalogs and the workspace export, with their features.)
|
|
|
184
184
|
|
|
185
185
|
| APEX | pgkiln | Notes |
|
|
186
186
|
|---|---|---|
|
|
187
|
-
| SQL Workshop: SQL commands, object browser | ✅ | (sprint 61) A **home page** like APEX's: tiles, recently created tables, your recent SQL commands and the workspace's recent scripts, and the session's **default schema** (first in the search path of SQL
|
|
187
|
+
| SQL Workshop: SQL commands, object browser | ✅ | (sprint 61) A **home page** like APEX's: tiles, recently created tables, your recent SQL commands and the workspace's recent scripts, and the session's **default schema** (first in the search path of the SQL Worksheet and Scripts). (sprint 91) **SQL Commands is the SQL Worksheet** like Database Actions' SQL: a navigator, the statement at the cursor or a script with a log per statement, Explain Plan and Autotrace, notices and history (see the Database Actions section below). (sprint 75) The **Object Browser** like APEX's: a schema in the header, a tree by object type (tables, views, materialized views, indexes, sequences, types, functions, procedures, triggers) with a filter and a Create menu, system and extension objects hidden unless asked, and a table in tabs (columns with Add/Rename/Drop column writing the ALTER TABLE to review, data in pages, indexes, constraints, triggers, grants, row level security, dependencies, statistics, DDL); the tools as main tabs and a More menu. (sprint 62) **Utilities** like APEX's: the tools on one page, **Object Reports** (tables without a primary key, unindexed foreign keys, row-level security without policies or not enabled, PUBLIC grants, unused indexes, largest tables, missing comments), **About Database** and a **Database Monitor** of sessions and blocked queries for administrators. **Missing:** a recycle bin (PostgreSQL has none), user interface defaults (pgkiln's wizards read the catalog and comments) |
|
|
188
188
|
| RESTful services (ORDS) | ✅ | [PostgREST](https://postgrest.org) next to pgkiln: `api` schema, the same RLS as the UI, per-app API role, tokens in the builder, a pre-request check, and **OAuth clients** (client credentials, like ORDS `oauth.create_client`) so tokens renew themselves |
|
|
189
189
|
| REST handler editor, REST-enabled SQL | ✅ | **REST modules** in the builder: handlers (method, path with parameters, SQL as collection, item or statements, roles, public) served by pgkiln with bearer tokens and an OpenAPI description; plus PostgREST for schema-wide APIs. **Missing:** REST-enabled SQL (rarely desirable) |
|
|
190
190
|
| SQL scripts, query builder, Quick SQL | ✅ | **SQL Scripts**: saved, upload/download, a result per statement, stop or continue on errors, optionally one transaction, run history. **Quick SQL** (a subset: tables, child tables, types, the main column directives, `/auditcols`, settings, views). A graphical **query builder**: tables as boxes on a canvas (dragged, placed where left), joins along foreign keys or drawn from column to column (inner or left), column functions with automatic `group by`, conditions, sort, open in SQL Commands; without JavaScript the same as forms ([chapter 3](guide/03-builder.md#sql-workshop)) |
|
|
@@ -269,6 +269,9 @@ Small but real differences, for teams comparing the two:
|
|
|
269
269
|
- An import can be checked before it commits (`pgkiln import --check`): SQL that names a missing
|
|
270
270
|
table or column refuses the deployment instead of failing at run time.
|
|
271
271
|
- E-mail through SMTP with OAuth2, Microsoft Graph, Amazon SES and HTTP APIs, not only SMTP with a password.
|
|
272
|
+
- (sprint 85) A **Form Designer** region ([chapter 4](guide/04-pages-and-regions.md#form_designer-form-designer)): the
|
|
273
|
+
application's administrators build and publish data entry forms in the running application, on the tables and
|
|
274
|
+
columns the developer offers, with grants, row level security and lost update detection applying.
|
|
272
275
|
|
|
273
276
|
## Roadmap (proposed priority)
|
|
274
277
|
|
|
@@ -331,3 +334,29 @@ Sources: [APEX 26.1 new features](https://docs.oracle.com/en/database/oracle/ape
|
|
|
331
334
|
| Map Backgrounds | ➖ Not planned per application: the installation's map tile server (`MAP_TILE_URL`) is every map's background |
|
|
332
335
|
| AI Attributes, AI Services, AI Agents | AI Services; AI agents ➖ not planned |
|
|
333
336
|
|
|
337
|
+
## Database Actions (SQL Developer Web) and the SQL Workshop
|
|
338
|
+
|
|
339
|
+
(sprint 91) Oracle's Database Actions, the ORDS tool next to APEX, is the standard for pgkiln's SQL Workshop, mapped
|
|
340
|
+
to PostgreSQL. pgkiln's own extras stay: Quick SQL, the Query Builder, Sample Data, Schema Comparison, Object Reports,
|
|
341
|
+
AI and row level security badges.
|
|
342
|
+
|
|
343
|
+
| Database Actions | pgkiln | |
|
|
344
|
+
|---|---|---|
|
|
345
|
+
| SQL worksheet: navigator, editor, output tabs, status bar | SQL Workshop → SQL Worksheet (sprint 91): navigator by schema and object type with columns, drag and drop and SELECT / INSERT / UPDATE / DELETE; Query Result, Script Output, Notices (DBMS Output), Explain Plan, Autotrace, SQL History; resizable panes, fullscreen | ✅ |
|
|
346
|
+
| Run Statement (Ctrl+Enter), Run Script (F5) | The statement at the cursor or the selection; a script with a log per statement (psql command tags, error line and column), stop or continue on error; Run as an application's role | ✅ |
|
|
347
|
+
| Explain Plan (F10), Autotrace (F6) | A tree of steps (sprint 92): cost, rows, conditions; with Autotrace (`EXPLAIN ANALYZE, BUFFERS`, rolled back) actual time, rows, loops, buffers, each step's own time, the slowest step and 10× misestimates; the text plan too | ✅ |
|
|
348
|
+
| Query Result grid (paging, download, sharing) | 500 rows (All rows: 10,000) with row numbers, numbers right-aligned, sort, a value dialog, copy, Download as CSV, JSON, XML, Excel or SQL inserts (sprint 92); no sharing links | ✅ |
|
|
349
|
+
| SQL History, DBMS Output | SQL History per developer with status, rows, time, search and run again; Notices with their time (sprint 92) | ✅ |
|
|
350
|
+
| Worksheets saved as files, tabs | Save, Save as, Rename, Download as SQL Scripts, a Files tab, worksheet tabs that survive a reload (sprint 93) | ✅ |
|
|
351
|
+
| Create Chart from a query, Charts | Charts in applications only | ❌ |
|
|
352
|
+
| Object context menu, table properties dialog, Quick DDL | An object's menu (sprint 94): Open in a panel, Quick DDL to the worksheet or a file, Load data, Add index / trigger / policy, Drop with its dependents; **Table Properties** (sprint 95): columns, keys, foreign keys, checks, indexes, comment, RLS, partitioning, DDL preview, Apply in one transaction, use as template | ✅ |
|
|
353
|
+
| Format, Convert Case, Find and replace, bind variables | Format (Ctrl+F7), Convert case, find and replace, Go to line, comment lines, `:NAME` and `&NAME.` asked for before a run (sprint 93); no guided tour | ✅ |
|
|
354
|
+
| Data Modeler (relational diagrams) | Query Builder joins only | ❌ |
|
|
355
|
+
| REST (modules, AutoREST) | Consumes REST (catalogs, sources); the application REST API | 🟡 |
|
|
356
|
+
| Scheduling | pgkiln's own jobs and automations | ❌ |
|
|
357
|
+
| Database Users | Application users and developers; roles in SQL | ❌ |
|
|
358
|
+
| Real Time SQL Monitor | Database Monitor (sessions) and Top SQL per application role | 🟡 |
|
|
359
|
+
| Launchpad, Search Database (Ctrl+K) | The SQL Workshop home | 🟡 |
|
|
360
|
+
| Data Pump | Application backups and Unload Data | 🟡 |
|
|
361
|
+
| Liquibase | Schema Comparison | 🟡 |
|
|
362
|
+
| JavaScript (MLE) | ➖ Not planned: PostgreSQL has plv8 as an extension | ➖ |
|
package/docs/guide/03-builder.md
CHANGED
|
@@ -84,7 +84,7 @@ builder page while the workspace is current.
|
|
|
84
84
|
Administrators and the workspace's administrators set them on the workspace's page (Administration menu →
|
|
85
85
|
*Workspace preferences*; APEX: Set Workspace Preferences):
|
|
86
86
|
|
|
87
|
-
- **Enable the SQL Workshop**: off, every SQL Workshop page (SQL
|
|
87
|
+
- **Enable the SQL Workshop**: off, every SQL Workshop page (the SQL Worksheet, the Object Browser, SQL scripts, Load and
|
|
88
88
|
Unload Data, Quick SQL, the query builder, Sample Data, DDL, Compare, AI) answers *403* while the workspace is
|
|
89
89
|
current, for every developer including administrators; the rail and Workspace utilities no longer show it. A
|
|
90
90
|
developer who belongs to another workspace can still use it there. Turn it off for a workspace whose developers
|
|
@@ -143,7 +143,7 @@ workspace → *Isolation*). It needs `RUNTIME_DATABASE_URL` (applications don't
|
|
|
143
143
|
|
|
144
144
|
- **Two PostgreSQL logins of its own**: `pgkiln_ws<id>_run_<suffix>` runs its applications (pages, processes, REST
|
|
145
145
|
handlers, automations, workflows, background processes, REST synchronisation); `pgkiln_ws<id>_dev_<suffix>` runs its
|
|
146
|
-
developers' SQL: SQL
|
|
146
|
+
developers' SQL: the SQL Worksheet, SQL Scripts, Quick SQL, Load and Unload Data, Sample Data, DDL and Compare, the
|
|
147
147
|
Advisor, code checks and document previews. SQL that runs `RESET ROLE` (or `set_config('role', …)`) only gets back to
|
|
148
148
|
that login, which can use the workspace's database roles and nothing else.
|
|
149
149
|
- **The workspace's database roles** (APEX: workspace schemas): isolating gives the workspace the roles its
|
|
@@ -199,6 +199,11 @@ Every builder page has the same frame, modelled on an IDE:
|
|
|
199
199
|
|
|
200
200
|
On phones the rail gets narrower and the breadcrumb shows only the current page.
|
|
201
201
|
|
|
202
|
+
(sprint 86) An address under `/builder` that leads nowhere (a deleted application or page, a typo, an
|
|
203
|
+
application of a workspace you are not a member of) shows a **Page not found** page in the builder's
|
|
204
|
+
theme with a link to the App Builder home; a server error shows **Something went wrong** (the error
|
|
205
|
+
is in the server log, not on the page). Scripts get the plain answers they always got.
|
|
206
|
+
|
|
202
207
|
## App Builder home
|
|
203
208
|
|
|
204
209
|
The home page is laid out like APEX's App Builder:
|
|
@@ -251,15 +256,15 @@ start from a file, pasted data, a blueprint or the App Gallery instead. Then:
|
|
|
251
256
|
|
|
252
257
|
| Section | Field | Meaning |
|
|
253
258
|
|---|---|---|
|
|
254
|
-
| Data | Pages on the tables of | The parsing schema: an existing schema (
|
|
259
|
+
| Data | Pages on the tables of | The parsing schema: an existing schema, or a new, empty one named after the alias. (sprint 87) Choosing a schema lists its tables under Pages at once, with the name and alias proposed for it (unless you already typed them); without JavaScript, *Show its tables* does it |
|
|
255
260
|
| Application | Name | Display name, shown in the header. Proposed from the schema and selected when you click it, so typing replaces it |
|
|
256
261
|
| | Description, Icon | Shown on the home page's hero and the About page |
|
|
257
262
|
| Appearance | Theme style, Navigation, Accent colour | Iris, Lavender or Standard; a side or top menu; an own accent colour |
|
|
258
|
-
| Pages | a page type per table | *Interactive report with form*, *Faceted search*, *Cards*, *Calendar* (a table with a date column), *Master detail* (a table another table refers to), *Interactive grid*, *Report* or *No page*. Tables with a single-column primary key get a modal form with their report, faceted search, cards and calendar; views and tables without such a key can't have a form or a grid. Proposed: a report with form, an interactive grid for a table of more than 100,000 rows, a report for a view. *Dashboard*: a chart per table |
|
|
263
|
+
| Pages | a page type per table | *Interactive report with form*, *Faceted search*, *Cards*, *Calendar* (a table with a date column), *Master detail* (a table another table refers to), *Interactive grid*, *Report* or *No page*. Tables with a single-column primary key get a modal form with their report, faceted search, cards and calendar; views and tables without such a key can't have a form or a grid. Proposed: a report with form, an interactive grid for a table of more than 100,000 rows, a report for a view. (sprint 87) A table with [row level security](08-security.md) shows *RLS · n* (its number of policies), or *RLS, no policies* in red: the application's role would see no rows. *Dashboard*: a chart per table |
|
|
259
264
|
| Features | | *About page* (in a Help menu), *Access control* (authorization schemes `CONTRIBUTOR` and `READER` next to `ADMIN`, for the roles admin, contributor and reader), *Activity reporting* (page 9010 for administrators: page views per day and the latest activity, from `meta.app_activity`), *Feedback*, *Theme style selection* (users may choose light or dark), *Install as an app* (PWA) and *Push notifications* (needs `PGKILN_SECRET_KEY`) |
|
|
260
|
-
| Settings | Alias | Lowercase URL name: `inventory` gives `/a/inventory` |
|
|
265
|
+
| Settings | Alias | Lowercase URL name: `inventory` gives `/a/inventory`. (sprint 87) It follows the name as you type it (*Café Orders* → `cafe-orders`) until you change it yourself |
|
|
261
266
|
| | Authentication | *App users* (a login page and a user list), *HTTP header* (a trusted reverse proxy names the user, see [chapter 8](08-security.md#http-header-authentication-reverse-proxy)), *Database accounts* (PostgreSQL login roles and their passwords, see [chapter 8](08-security.md#database-accounts-postgresql-roles)), *Custom* (your own PL/pgSQL function, see [chapter 8](08-security.md#custom-authentication-a-plpgsql-function)) or *None* (a public app) |
|
|
262
|
-
| | First user / Password | The first user; they get the `admin` role. An existing account is reused (its password isn't changed) |
|
|
267
|
+
| | First user / Password | The first user; they get the `admin` role. An existing account is reused (its password isn't changed). (sprint 87) Hidden while Authentication is *None* |
|
|
263
268
|
| | Language | The application's primary language |
|
|
264
269
|
| Advanced | Start from | Shown when there are **boilerplate** applications (Settings → Application type): their pages, shared components and settings are copied into the new application, which keeps its own name, alias, role and authentication ([application types](#application-types-and-subscriptions)) |
|
|
265
270
|
|
|
@@ -268,7 +273,9 @@ Creating the app also:
|
|
|
268
273
|
- creates the database role `app_<alias>` with `SELECT/INSERT/UPDATE/DELETE` on all tables,
|
|
269
274
|
`USAGE` on sequences and `EXECUTE` on functions in the schema, plus **default privileges**,
|
|
270
275
|
so tables you create later (as the owner, e.g. in the SQL Workshop) are usable by the app straight away;
|
|
271
|
-
- creates page 1 *Home*, a navigation entry, and an authorization scheme `ADMIN` (role `admin`);
|
|
276
|
+
- creates page 1 *Home*, a navigation entry, and an authorization scheme `ADMIN` (role `admin`); (sprint 88) the home
|
|
277
|
+
page is a hero with the name and icon on the page background and a card per page, each with a colour band and its
|
|
278
|
+
icon in a round badge; the version is *Release 1.0*;
|
|
272
279
|
- shows a progress message while it works and then opens the new application's page in the builder,
|
|
273
280
|
with what was created (and anything left out) as a message.
|
|
274
281
|
|
|
@@ -539,6 +546,11 @@ its pages in four groups.
|
|
|
539
546
|
|
|
540
547
|
## The page designer
|
|
541
548
|
|
|
549
|
+
(sprint 86) A page's address in the page designer is its application's id and its number:
|
|
550
|
+
`/builder/apps/<app id>/pages/<page number>`, with `?c=region-<id>` (and so on) for the selected
|
|
551
|
+
component, so a link names the page you mean. The older `/builder/pages/<internal id>` still works:
|
|
552
|
+
a browser that opens it is sent to the page's number.
|
|
553
|
+
|
|
542
554
|
The page designer has three panes, as in APEX's Page Designer. From 1024 pixels wide they sit
|
|
543
555
|
side by side; on phones and portrait tablets they are tabs (**Tree**, **Layout**, **Properties**):
|
|
544
556
|
choosing a component opens the Properties tab.
|
|
@@ -567,8 +579,12 @@ choosing a component opens the Properties tab.
|
|
|
567
579
|
*Create dynamic action*, *Create region below*, **Duplicate** (a copy right after it; a region comes with its
|
|
568
580
|
items and buttons, names get `_2`), **Copy to other page…** (to the end of a page of the same application; items
|
|
569
581
|
named `P<n>_` get that page's number, a region's buttons and items come along, references in SQL are not changed),
|
|
570
|
-
*Expand all below*, *Collapse all below
|
|
571
|
-
|
|
582
|
+
*Expand all below*, *Collapse all below*, (sprint 90) **Comment out** and *Delete*. The arrow keys move through the
|
|
583
|
+
menu, Escape closes it. **Comment out** (APEX's) leaves a component (a region, item, button, dynamic action,
|
|
584
|
+
validation, process, computation or branch) out of the page without deleting it: it gets the
|
|
585
|
+
[build option](#shared-components) `COMMENTED_OUT`, made with the status *Exclude* when first needed, and is struck
|
|
586
|
+
through in the tree; **Uncomment** takes it off again (another build option of the component is left alone).
|
|
587
|
+
APEX's *Create Sub Region* is not there: pgkiln has no nested regions.
|
|
572
588
|
- **Middle: the Layout**: the page template's display positions as labelled zones (Banner, Breadcrumb bar,
|
|
573
589
|
the side column of a side-column template beside the Body, Footer), each with its regions on the 12-column
|
|
574
590
|
grid, each region with its items and its buttons in their button positions, as they will be placed on the page; under it a **gallery** of region types, item types
|
|
@@ -692,6 +708,7 @@ out, other keys are kept, columns the query no longer returns stay listed so you
|
|
|
692
708
|
| `ai_assistant` | The AI service (those the application may use), system prompt, welcome text, placeholder, error message, tool rounds per question, questions per conversation, public or not, and the context queries and tools as JSON (checked when saving: query shapes, parameter types, REST data sources and authorization schemes that exist) ([AI assistant](04-pages-and-regions.md#ai_assistant-ai-assistant)) |
|
|
693
709
|
| `report` (also) | *Ask in your own words (AI)*: the AI service and placeholder of the [natural-language filters](04-pages-and-regions.md#natural-language-filters-ask-in-your-own-words) |
|
|
694
710
|
| `data_reporter` | Data sources (a table or view each: static id, label, description, offered columns with labels and format masks), who may share reports, rows per page ([Data Reporter](04-pages-and-regions.md#data_reporter-data-reporter)) |
|
|
711
|
+
| `form_designer` | Who may design forms (an authorization scheme), data sources (a table or view each: static id, label, description, key column, may add / change / delete rows, offered columns with labels and lists of values), rows per page ([Form Designer](04-pages-and-regions.md#form_designer-form-designer)) |
|
|
695
712
|
|
|
696
713
|
Links, lists of values and the facets' report are checked when saving: a form can only point to
|
|
697
714
|
pages and shared lists of values of the same application, and to report regions on the same page.
|
|
@@ -1011,7 +1028,9 @@ on Definition (`?tab=…` opens another). *Save settings* saves the first five t
|
|
|
1011
1028
|
you were on. The Security tab shows only the fields of the chosen authentication type (HTTP header, database
|
|
1012
1029
|
accounts or custom).
|
|
1013
1030
|
|
|
1014
|
-
- **Application**: name, alias, home page.
|
|
1031
|
+
- **Application**: name, alias, home page, and (sprint 88) the **version** (APEX: Version, e.g. *Release 1.0*): shown
|
|
1032
|
+
at the bottom of the application's pages, next to *Back to top*. New applications start at *Release 1.0*; empty: no
|
|
1033
|
+
version in the footer.
|
|
1015
1034
|
- **Security**: authentication (*App users*, *HTTP header*, *Database accounts*, *Custom* or
|
|
1016
1035
|
*None*), the database role, and **debug mode** (shows full database errors to users; development
|
|
1017
1036
|
only). The state of the [debug messages](06-processing.md#debug-messages) is shown below it,
|
|
@@ -1172,8 +1191,8 @@ administrator chooses it under **SQL Workshop → AI** (any enabled [AI service]
|
|
|
1172
1191
|
switches the builder's AI off). What it is used for:
|
|
1173
1192
|
|
|
1174
1193
|
- **SQL from a question** (SQL Workshop → AI): pick a schema and ask; the answer is a statement and
|
|
1175
|
-
a short explanation. It is **shown, never run**: check it, change it and run it in SQL
|
|
1176
|
-
yourself (*Run in SQL
|
|
1194
|
+
a short explanation. It is **shown, never run**: check it, change it and run it in the SQL Worksheet
|
|
1195
|
+
yourself (*Run in the SQL Worksheet*).
|
|
1177
1196
|
- **Explain a query or an error** (SQL Workshop → AI): paste a query, an error message or both
|
|
1178
1197
|
(optionally with a schema for context); the explanation is shown with simple formatting.
|
|
1179
1198
|
- **Describe tables for AI** (SQL Workshop → AI → *Describe tables*): per table or view, a
|
|
@@ -1227,31 +1246,107 @@ may use), a form to **issue a token** for an account, and `curl` examples. See
|
|
|
1227
1246
|
|
|
1228
1247
|
## SQL Workshop
|
|
1229
1248
|
|
|
1230
|
-
The SQL Workshop opens on its **home** (`/builder/sql`; APEX: the SQL Workshop home): tiles for the
|
|
1231
|
-
|
|
1232
|
-
PostgreSQL keeps no creation time, so object ids decide), your **recent SQL commands** (click one to open it in SQL
|
|
1233
|
-
|
|
1234
|
-
session's **schema** (APEX: the default schema): it goes first in the search path of SQL
|
|
1249
|
+
The SQL Workshop opens on its **home** (`/builder/sql`; APEX: the SQL Workshop home): tiles for the SQL Worksheet,
|
|
1250
|
+
the Object Browser, SQL Scripts, the utilities and Quick SQL; **Recently created tables** (the newest tables you can read:
|
|
1251
|
+
PostgreSQL keeps no creation time, so object ids decide), your **recent SQL commands** (click one to open it in the SQL
|
|
1252
|
+
Worksheet; other developers' are never shown) and the workspace's **recent SQL scripts**. The side column sets the
|
|
1253
|
+
session's **schema** (APEX: the default schema): it goes first in the search path of the SQL Worksheet and SQL Scripts until
|
|
1235
1254
|
you sign out. Tasks link to Quick SQL, blueprints, table descriptions, sample data and Generate DDL.
|
|
1236
1255
|
|
|
1237
|
-
(sprint 75) The tools are tabs: Home,
|
|
1256
|
+
(sprint 75) The tools are tabs: Home, SQL Worksheet, Object Browser, SQL Scripts and Utilities; **More** opens the
|
|
1238
1257
|
others (Quick SQL, Query Builder, Load and Unload Data, Sample Data, DDL, Compare, AI), and the open one is a tab too.
|
|
1239
1258
|
|
|
1240
|
-
- **SQL
|
|
1241
|
-
|
|
1242
|
-
**
|
|
1243
|
-
|
|
1244
|
-
|
|
1259
|
+
- **SQL Worksheet** (`/builder/sql/worksheet`, sprint 91; Database Actions: SQL; was SQL Commands, whose address
|
|
1260
|
+
`/builder/sql/commands` opens the same page): one screen with a **navigator** on the left, the **editor** with a
|
|
1261
|
+
toolbar, **output tabs** below and a **status bar**.
|
|
1262
|
+
- The navigator has a schema (the same one as the Object Browser), an object type (*All Objects*, tables, views,
|
|
1263
|
+
materialized views, indexes, sequences, types, functions, procedures, triggers, policies) and a search field.
|
|
1264
|
+
A table or view opens to its columns with their types (a key marks the primary key); drag it into the editor
|
|
1265
|
+
for a `SELECT` of all its columns, or use its **SELECT**, **INSERT**, **UPDATE** and **DELETE** buttons, which
|
|
1266
|
+
insert the statement at the cursor. Columns are listed for the first 400 tables and views of a schema.
|
|
1267
|
+
- (sprint 94) Each object has a **⋯ menu** (or right-click it; Shift+right-click keeps the browser's menu), in
|
|
1268
|
+
the Object Browser's tree too: **Open** shows the Object Browser's tabs in a panel at the side, without leaving
|
|
1269
|
+
the worksheet; **Quick DDL** puts the object's DDL into a new worksheet tab (with the search path set to its
|
|
1270
|
+
schema) or downloads it as a `.sql` file; for a table **Load data**, **Add index**, **Add trigger** (a trigger
|
|
1271
|
+
function and the trigger) and **Add policy** (row level security on, a policy to fill in); **Drop…** writes the
|
|
1272
|
+
DROP statement with a comment that lists what depends on the object (views, foreign keys…). Nothing runs: you
|
|
1273
|
+
review the statement and run it.
|
|
1274
|
+
- (sprint 95) **Table Properties** (a table's **Edit…**, **Use as template**, the Object Browser's *Edit table* and
|
|
1275
|
+
its *Table (form)* tile): a form with **Columns** (name, type, primary key, not null, default, identity,
|
|
1276
|
+
comment; move them up or down for a new table, remove them), **Unique keys**, **Foreign keys** (the table it refers
|
|
1277
|
+
to, its columns, on delete), **Checks**, **Indexes** (columns or expressions, unique; indexes with another method or
|
|
1278
|
+
a condition are kept as they are), the table's **comment**, **row level security** (and forcing it for the owner)
|
|
1279
|
+
and, for a new table, **partitioning** (range, list or hash and its key). **Preview DDL** shows the exact CREATE
|
|
1280
|
+
TABLE, or for an existing table the ALTER statements from what the catalog says now; **Apply** runs them in one
|
|
1281
|
+
transaction (nothing changes when one fails, and the error shows under *Output*); **Open in the worksheet** puts
|
|
1282
|
+
them there instead. *Use as template* starts a new table with the same columns and keys (names with `_copy`).
|
|
1283
|
+
Defaults, checks and index expressions are single expressions (no `;` or comments).
|
|
1284
|
+
- **Run Statement** (**Ctrl/Cmd + Enter**) runs the statement at the cursor: the one the cursor is in, else the
|
|
1285
|
+
nearest one before it. A selection runs as it is, even when it holds several statements. The rows of the last
|
|
1286
|
+
query show in **Query Result**, up to 500, with row numbers, numbers right-aligned and NULL as *(null)*. The
|
|
1287
|
+
statement that ran is selected again afterwards. (sprint 92) Click a column heading to sort the rows, a cell to
|
|
1288
|
+
see its whole value (JSON indented), **Copy** for the rows as tab-separated text, and **All rows** to run the
|
|
1289
|
+
statement again for up to 10,000 rows. **Download** saves a SELECT as CSV, JSON, XML, Excel or SQL inserts
|
|
1290
|
+
through Unload Data (a read-only transaction, so the query runs once more).
|
|
1291
|
+
- **Run Script** (**F5**) runs every statement in order and writes **Script Output**: for each statement its line,
|
|
1292
|
+
the rows as text (up to 50), its notices, and its command tag like psql's (`CREATE TABLE`, `INSERT 0 2`,
|
|
1293
|
+
`SELECT 14`) with its time. An error says its line and column in the worksheet; the cursor goes to that line.
|
|
1294
|
+
The script stops at the first error unless **Continue on error** is on. psql meta-commands and `COPY … FROM
|
|
1295
|
+
STDIN` / `TO STDOUT` are skipped (use Load Data and Unload Data).
|
|
1296
|
+
- **Explain Plan** (**F10**) shows the plan of the statement at the cursor; nothing runs. **Autotrace** (**F6**) runs
|
|
1297
|
+
it with `EXPLAIN (ANALYZE, BUFFERS)` in a transaction that is rolled back, so an UPDATE or DELETE changes
|
|
1298
|
+
nothing. (sprint 92) The plan is a tree of steps: the operation, the table or index, cost, estimated rows and
|
|
1299
|
+
width, and the step's conditions (filter, index and join conditions, sort keys). Autotrace adds the actual time,
|
|
1300
|
+
rows, loops and buffers, the time spent in the step itself, marks the **slowest step**, and flags estimates that
|
|
1301
|
+
are 10 times too high or too low (run `ANALYZE` on the table). **Text plan** shows it like psql.
|
|
1302
|
+
- **Notices** lists the `RAISE NOTICE`, `INFO` and `WARNING` messages of the last run with their time.
|
|
1303
|
+
**SQL History** (sprint 92) lists your last 200 statements in this workspace with how they ended, their rows and
|
|
1304
|
+
time; running the same statement again counts on its row (*3×*). Search it, show only the ones that failed or
|
|
1305
|
+
succeeded, click one to insert it at the cursor, **Run** to run it again, or copy it. Other developers' history
|
|
1306
|
+
never shows; 500 statements are kept per developer. The home page's *Recent SQL commands* opens it.
|
|
1307
|
+
- The status bar counts errors and warnings and shows the last message and its time.
|
|
1308
|
+
- (sprint 93) **Worksheets and files**: the worksheet's name is a menu with **Save** (**Ctrl/Cmd + S**), *Save as
|
|
1309
|
+
new*, *Rename*, **Download** (a `.sql` file), **New** and *Open…*. A worksheet is saved as a script of SQL Scripts
|
|
1310
|
+
(shared by the workspace's developers); the navigator's **Files** tab lists them, and SQL Scripts opens one in the
|
|
1311
|
+
worksheet. Several worksheets stay open as **tabs** above the editor (at most 20); a `*` marks text not saved yet.
|
|
1312
|
+
The tabs and their unsaved text are kept in the browser, so they survive a reload.
|
|
1313
|
+
- **Bind variables** (`:NAME`) and **substitution variables** (`&NAME.`) are asked for in a dialog before the run.
|
|
1314
|
+
A bind variable's value is a quoted literal (empty is NULL), so it can never change the statement; a substitution
|
|
1315
|
+
variable's text goes into the statement as it is (a table or column name, for instance). The values are
|
|
1316
|
+
remembered for the session; the history and the log keep the statement as written.
|
|
1317
|
+
- **Format** (**Ctrl + F7**) lays out the selection or the whole worksheet: a clause per line, the columns of a select
|
|
1318
|
+
list and the conditions of a WHERE one per line, joins and subqueries indented, keywords in lower or UPPER case
|
|
1319
|
+
(chosen in the **?** menu). Strings, comments and `$$` bodies stay as they are. **Convert case** (**Ctrl + B**)
|
|
1320
|
+
cycles the selection (or the word at the cursor) through UPPER, lower and Initial caps. **Find and replace**
|
|
1321
|
+
(**Ctrl + F**, **Ctrl + H**) with a regular expression or exact case, **Go to line** (**Ctrl + G**), and
|
|
1322
|
+
**Ctrl + /** comments the selected lines out or in. The **?** menu lists every key; **F1** opens this help. The
|
|
1323
|
+
upload button opens Load Data for the navigator's schema.
|
|
1324
|
+
- Each statement commits on its own. Statements run as the **owner connection** (an isolated workspace's
|
|
1325
|
+
developer login for its developers), on a connection of their own that is closed afterwards, so `SET ROLE` or
|
|
1326
|
+
`SET search_path` doesn't leak. **Run as** picks an application of your workspace instead: the statements then
|
|
1327
|
+
run as its database role, with `pgkiln.app_id` set, so its grants and row level security policies apply. Use
|
|
1328
|
+
it to test policies; it is no security boundary, since the SQL could `RESET ROLE`.
|
|
1329
|
+
- With script, the panes fill the window. Drag the splitters (or focus one and use the arrow keys) to resize
|
|
1330
|
+
them, hide the navigator, or use **Fullscreen** to see only the editor (**Escape** leaves). Sizes are
|
|
1331
|
+
remembered in the browser. Without script, the buttons post the form and the panes stack; Run Statement then
|
|
1332
|
+
runs every statement. The [code editor](#the-code-editor) suggests every schema, table, column and function
|
|
1333
|
+
you can use.
|
|
1334
|
+
- **Object Browser** (APEX's): the **schema** in the header and a tree with a
|
|
1245
1335
|
folder per object type (tables, views, materialized views, indexes, sequences, types, functions, procedures,
|
|
1246
1336
|
triggers) and a **filter** by name. pgkiln's own schemas (`meta`, `pgkiln_plugins`) and objects that belong to an
|
|
1247
1337
|
extension show only with **Show system objects**. **Create** (and the tiles shown when nothing is selected) opens
|
|
1248
|
-
SQL
|
|
1249
|
-
**Columns** (with comments; *Add*, *Rename* and *Drop column* write
|
|
1250
|
-
review and run: nothing changes until you press Run), **Data** (25
|
|
1338
|
+
the SQL Worksheet with a CREATE TABLE, VIEW, FUNCTION, SEQUENCE or INDEX statement to fill in. A table opens in tabs:
|
|
1339
|
+
**Columns** (with comments; the toolbar's *Add*, *Modify* (type, nulls, default), *Rename* and *Drop column* write
|
|
1340
|
+
the ALTER TABLE statement into the SQL Worksheet to review and run: nothing changes until you press Run), **Data** (25
|
|
1341
|
+
rows a page; NULL is a blank cell), **Indexes**, **Constraints**
|
|
1251
1342
|
(primary key, foreign keys with the table they refer to, unique, check), **Triggers**, **Grants**, **Row level
|
|
1252
1343
|
security** (on or off, the policies), **Dependencies** (views and foreign keys that use it, and what it uses),
|
|
1253
1344
|
**Statistics** (rows, sizes, analyze and vacuum times) and **DDL**. A view has the same tabs where they apply; a
|
|
1254
|
-
function or procedure shows its source, a trigger, index, sequence or type its definition.
|
|
1345
|
+
function or procedure shows its source, a trigger, index, sequence or type its definition. (sprint 89) The tabs stay
|
|
1346
|
+
on one row: Columns, Data, Indexes, Constraints and DDL (and the current one), the others under **More**. The
|
|
1347
|
+
schema shown is the one you chose last (remembered for the session), else the session's schema of the SQL Worksheet,
|
|
1348
|
+
else the **parsing schema** of the application changed last in your workspace (the schema its database role
|
|
1349
|
+
uses).
|
|
1255
1350
|
- **SQL Scripts**: saved scripts, shared by the developers of the workspace. Create one in the editor, upload a
|
|
1256
1351
|
`.sql` file (UTF-8, up to 5 MB) or save one from Quick SQL; download it again as `.sql`. **Run**
|
|
1257
1352
|
splits the script into statements at semicolons (outside strings, comments, quoted identifiers,
|
|
@@ -1284,7 +1379,7 @@ others (Quick SQL, Query Builder, Load and Unload Data, Sample Data, DDL, Compar
|
|
|
1284
1379
|
note. Each join can be inner or left. Drag a table by its handle, or focus the handle and use
|
|
1285
1380
|
the arrow keys (Shift for bigger steps); it stays where it was left. On phones the tables are
|
|
1286
1381
|
stacked. Then pick conditions (`=`, `<>`, `<`, `like`, `in (a, b)`, `is null` …, combined with
|
|
1287
|
-
AND or OR), the sort, `distinct` and a row limit. The SELECT is shown and opens in SQL
|
|
1382
|
+
AND or OR), the sort, `distinct` and a row limit. The SELECT is shown and opens in the SQL Worksheet.
|
|
1288
1383
|
The state is in the URL (tables in the order chosen, joins, functions and the tables' places), so
|
|
1289
1384
|
a query can be bookmarked; everything except dragging works without JavaScript. Only names from
|
|
1290
1385
|
the catalog and the fixed functions are used, and condition values are string literals.
|