Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ subprojects/*
*.flatpak
*.dot
io.github.ppvan.tarug.flatpak

.vscode/*
17 changes: 0 additions & 17 deletions .vscode/launch.json

This file was deleted.

18 changes: 0 additions & 18 deletions .vscode/tasks.json

This file was deleted.

26 changes: 17 additions & 9 deletions pkgs/flatpak/io.github.ppvan.tarug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,23 @@ modules:
- type: archive
url: https://ftp.postgresql.org/pub/source/v17.0/postgresql-17.0.tar.bz2
sha256: 7e276131c0fdd6b62588dbad9b3bb24b8c3498d5009328dba59af16e819109de
- name: libcsv
buildsystem: meson
- name: libpg_query
buildsystem: simple
build-commands:
- make
- make install prefix=/app
sources:
- type: git
url: https://github.com/ppvan/libcsv
commit: c8f01b8b4aa8d8156a624405b8a4c646e3f6efaa
- name: libquery-vala
buildsystem: meson
url: https://github.com/pganalyze/libpg_query
tag: 17-6.0.0
- name: libcsv
buildsystem: simple
build-commands:
- ./configure --prefix=/app
- make
- make check
- make install
sources:
- type: git
url: https://github.com/ppvan/pg_query_vala
commit: 1672a38f04d4c8ba61f0ddc11e1203c824e704e9
- type: archive
url: http://deb.debian.org/debian/pool/main/libc/libcsv/libcsv_3.0.3+dfsg.orig.tar.gz
sha256: 06fddfaca720a4be7603bad63eb1833bca5b6c5a69b42b1c518a02cda2a73aef
10 changes: 7 additions & 3 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ configure_file(output: 'config.h', configuration: conf)

cc = meson.get_compiler('c')
math_dep = cc.find_library('m', required: false)
pg_query_dep = cc.find_library('pg_query', has_headers: ['pg_query.h'])
csv_dep = cc.find_library('csv', has_headers: ['csv.h'])

tarug_deps = [
# assume exists typical gtk system
Expand All @@ -96,10 +98,10 @@ tarug_deps = [
dependency('gee-0.8'),
dependency('gtksourceview-5', version: '>= 5.0'),
dependency('libpq', version: '>= 15.3'),
math_dep,
dependency('sqlite3'),
dependency('pgquery-vala'),
cc.find_library('csv', has_headers: ['csv.h'], required: true),
math_dep,
csv_dep,
pg_query_dep,
valac.find_library('config', dirs: vapi_dir),
]

Expand All @@ -109,6 +111,8 @@ add_project_arguments(
'--vapidir', vapi_dir,
'--gresourcesdir', tarug_resources_dir,
'--enable-deprecated',
# IIUC, cc.find_library will not intergrate with vala compiler, hence the custom --pkg option
'--pkg', 'pg_query',
'--pkg', 'csv'
],
language: 'vala',
Expand Down
2 changes: 1 addition & 1 deletion src/services/SQLCompletionService.vala
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ namespace Tarug {

foreach (var item in keywords) {
var propose_query = cur_stmt.strip() + " " + item.value;
if (PGQuery.split_statement(propose_query, true) != null) {
if (is_sql_query (propose_query)) {
final.append(item);
}
}
Expand Down
22 changes: 14 additions & 8 deletions src/ui/editor/QueryEditor.vala
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,18 @@ namespace Tarug {
}

private void highlight_current_query (){
var stmts = PGQuery.split_statement(buffer.text);
var raw_query = buffer.text;
var stmts = PgQuery.split_with_scanner(raw_query);
this.clear_highlight();
stmts.foreach((token) => {
var start = token.location;
var end = token.location + token.statement.length;

for (var i = 0; i < stmts.n_stmts; i++) {
if (stmts.error != null) {
return;
}
var current_statement = stmts.stmts[i];

var start = current_statement->stmt_location;
var end = start + current_statement->stmt_len;

// debug ("[%d, %d], %s", token.location, token.end, token.value);

Expand All @@ -154,7 +161,7 @@ namespace Tarug {
if (start < buffer.cursor_position && buffer.cursor_position <= end + 1) {
// Double-check with strict mode.
string statement = buffer.get_text(iter1, iter2, false);
if (PGQuery.split_statement(statement, true) == null) {
if (!is_sql_query(statement)) {
return;
}

Expand All @@ -165,13 +172,12 @@ namespace Tarug {
buffer.apply_tag_by_name(LIGHT_TAG, iter1, iter2);
}

// Important
query_viewmodel.selected_query_changed(token.statement);
query_viewmodel.selected_query_changed(statement);
} else {
buffer.remove_tag_by_name(DARK_TAG, iter1, iter2);
buffer.remove_tag_by_name(LIGHT_TAG, iter1, iter2);
}
});
}
}

private inline void clear_highlight (){
Expand Down
5 changes: 5 additions & 0 deletions src/utils/types.vala
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ namespace Tarug {
return local_time;
}

public bool is_sql_query(string input) {
var result = PgQuery.parse(input);
return result.error == null;
}

public class Vec<T>: Object {
static int DEFAULT_CAPACITY = 64;

Expand Down
152 changes: 152 additions & 0 deletions src/vapi/pg_query.vapi
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Copyright (c) 2023 Phạm Văn Phúc <phuclaplace@gmail.com>
*/

[CCode (cprefix = "pg_query", cheader_filename = "pg_query.h")]
namespace PgQuery {
[CCode (cname = "PgQueryError", destroy_function = "")]
public struct Error {
public string message;
public string funcname;
public string filename;
public int lineno;
public int cursorpos;
public string context;
}

[CCode (cname = "PgQueryProtobuf", destroy_function = "")]
public struct Protobuf {
public size_t len;
public string data;
}

[CCode (cname = "PgQueryScanResult", destroy_function = "pg_query_free_scan_result")]
public struct ScanResult {
public Protobuf pbuf;
public string stderr_buffer;
public Error* error;
}

[SimpleType]
[CCode (cname = "PgQueryParseResult", destroy_function = "pg_query_free_parse_result", has_type_id = false)]
public struct ParseResult {
public string parse_tree;
public string stderr_buffer;
public Error* error;
}

[CCode (cname = "PgQueryProtobufParseResult", destroy_function = "pg_query_free_protobuf_parse_result")]
public struct ProtobufParseResult {
public Protobuf parse_tree;
public string stderr_buffer;
public Error* error;
}

[CCode (cname = "PgQuerySplitStmt", destroy_function = "")]
public struct SplitStmt {
public int stmt_location;
public int stmt_len;
}

[SimpleType]
[CCode (cname = "PgQuerySplitResult", destroy_function = "pg_query_free_split_result", has_type_id = false)]
public struct SplitResult {
public SplitStmt** stmts;
public int n_stmts;
public string stderr_buffer;
public Error* error;
}

[CCode (cname = "PgQueryDeparseResult", destroy_function = "pg_query_free_deparse_result")]
public struct DeparseResult {
public string query;
public Error* error;
}

[CCode (cname = "PgQueryPlpgsqlParseResult", destroy_function = "pg_query_free_plpgsql_parse_result")]
public struct PlpgsqlParseResult {
public string plpgsql_funcs;
public Error* error;
}

[CCode (cname = "PgQueryFingerprintResult", destroy_function = "pg_query_free_fingerprint_result")]
public struct FingerprintResult {
public uint64 fingerprint;
public string fingerprint_str;
public string stderr_buffer;
public Error* error;
}

[CCode (cname = "PgQueryNormalizeResult", destroy_function = "pg_query_free_normalize_result")]
public struct NormalizeResult {
public string normalized_query;
public Error* error;
}

[CCode (cname = "PgQueryParseMode", cprefix = "PG_QUERY_PARSE_")]
public enum ParseMode {
DEFAULT,
TYPE_NAME,
PLPGSQL_EXPR,
PLPGSQL_ASSIGN1,
PLPGSQL_ASSIGN2,
PLPGSQL_ASSIGN3
}

// Constants
public const int PARSE_MODE_BITS;
public const int PARSE_MODE_BITMASK;
public const int DISABLE_BACKSLASH_QUOTE;
public const int DISABLE_STANDARD_CONFORMING_STRINGS;
public const int DISABLE_ESCAPE_STRING_WARNING;

// Function bindings
[CCode (cname = "pg_query_normalize")]
public static NormalizeResult normalize(string input);

[CCode (cname = "pg_query_normalize_utility")]
public static NormalizeResult normalize_utility(string input);

[CCode (cname = "pg_query_scan")]
public static ScanResult scan(string input);

[CCode (cname = "pg_query_parse")]
public static ParseResult parse(string input);

[CCode (cname = "pg_query_parse_opts")]
public static ParseResult parse_opts(string input, int parser_options);

[CCode (cname = "pg_query_parse_protobuf")]
public static ProtobufParseResult parse_protobuf(string input);

[CCode (cname = "pg_query_parse_protobuf_opts")]
public static ProtobufParseResult parse_protobuf_opts(string input, int parser_options);

[CCode (cname = "pg_query_parse_plpgsql")]
public static PlpgsqlParseResult parse_plpgsql(string input);

[CCode (cname = "pg_query_fingerprint")]
public static FingerprintResult fingerprint(string input);

[CCode (cname = "pg_query_fingerprint_opts")]
public static FingerprintResult fingerprint_opts(string input, int parser_options);

[CCode (cname = "pg_query_split_with_scanner")]
public static SplitResult split_with_scanner(string input);

[CCode (cname = "pg_query_split_with_parser")]
public static SplitResult split_with_parser(string input);

[CCode (cname = "pg_query_deparse_protobuf")]
public static DeparseResult deparse_protobuf(Protobuf parse_tree);

[CCode (cname = "pg_query_exit")]
public static void exit();

[CCode (cname = "PG_MAJORVERSION")]
public const string MAJORVERSION;
[CCode (cname = "PG_VERSION")]
public const string VERSION;
[CCode (cname = "PG_VERSION_NUM")]
public const int VERSION_NUM;
}