From 229e8a482c69b2ee56b0610a534f08166e8dbf47 Mon Sep 17 00:00:00 2001 From: Juarez Rudsatz Date: Wed, 10 Sep 2025 18:30:39 -0300 Subject: [PATCH 1/9] Add SQL Support to Pastum Extension --- extension.js | 5 + package.json | 19 ++++ src/paste-default.js | 5 + src/paste-sql.js | 220 +++++++++++++++++++++++++++++++++++++ test/extension.test.js | 1 + test/paste-modules.test.js | 8 ++ 6 files changed, 258 insertions(+) create mode 100644 src/paste-sql.js diff --git a/extension.js b/extension.js index 0cc8fe2..64435ec 100644 --- a/extension.js +++ b/extension.js @@ -4,6 +4,7 @@ const py = require("./src/paste-python.js"); const jl = require("./src/paste-julia.js"); const js = require("./src/paste-js.js"); const md = require("./src/paste-markdown.js"); +const sql = require("./src/paste-sql.js"); const def = require("./src/paste-default.js"); function activate(context) { @@ -28,6 +29,10 @@ function activate(context) { "pastum.Markdown", md.clipboardToMarkdown ), + vscode.commands.registerCommand( + "pastum.Sql", + sql.clipboardToSql + ), vscode.commands.registerCommand("pastum.Defaultdataframe", def.pasteDefault) ); } diff --git a/package.json b/package.json index cb656a5..50bef4f 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,11 @@ "title": "Table ➔ JavaScript Dataframe", "category": "Pastum" }, + { + "command": "pastum.Sql", + "title": "Table ➔ SQL", + "category": "Pastum" + }, { "command": "pastum.Markdown", "title": "Table ➔ Markdown", @@ -153,6 +158,20 @@ ], "default": "columnar ↔️", "markdownDescription": "Select the default aligment for Markdown tables to be pasted using the `pastum.Defaultdataframe` command." + }, + "pastum.defaultSqlStatement": { + "type": "string", + "enum": [ + "SELECT FROM VALUES", + "SELECT UNION ALL", + "INSERT INTO VALUES", + "INSERT INTO SELECT VALUES", + "INSERT INTO", + "DELETE WHERE", + "CREATE TABLE" + ], + "default": "INSERT INTO VALUES", + "markdownDescription": "Select the default SQL statement to be pasted using the `pastum.Defaultdataframe` command." } } } diff --git a/src/paste-default.js b/src/paste-default.js index 9a5719e..b81c7b3 100644 --- a/src/paste-default.js +++ b/src/paste-default.js @@ -4,6 +4,7 @@ const py = require("./paste-python.js"); const jl = require("./paste-julia.js"); const js = require("./paste-js.js"); const md = require("./paste-markdown.js"); +const sql = require("./paste-sql.js"); function pasteDefault() { // Get the default dataframe framework @@ -12,6 +13,7 @@ function pasteDefault() { const framePy = config.get("defaultDataframePython"); const frameJS = config.get("defaultDataframeJavascript"); const frameMD = config.get("defaultAligmentMarkdown"); + const frameSql = config.get("defaultSqlStatement"); // Get the active editor language const editor = vscode.window.activeTextEditor; @@ -37,6 +39,9 @@ function pasteDefault() { case "markdown": md.clipboardToMarkdown(frameMD); break; + case "sql": + sql.clipboardToSql(frameSql); + break; default: vscode.window.showErrorMessage("No default framework selected"); } diff --git a/src/paste-sql.js b/src/paste-sql.js new file mode 100644 index 0000000..f9bad80 --- /dev/null +++ b/src/paste-sql.js @@ -0,0 +1,220 @@ +const vscode = require("vscode"); +const { parseClipboard } = require("./parse-table"); +const { addTrailingZeroes, normalizeBool } = require("./utils"); + +async function clipboardToSql(statement = null) { + try { + // 1: Read the clipboard content + const clipboardContent = await vscode.env.clipboard.readText(); + + if (!clipboardContent) { + vscode.window.showErrorMessage( + "Clipboard is empty or contains unsupported content." + ); + return; + } + + // 2: Try to extract the table from clipboard content + let formattedData = null; + formattedData = parseClipboard(clipboardContent); + + // 3: Ask the user which statement they want to use + if (statement === null) { + const stlist = [ + "SELECT FROM VALUES", + "SELECT UNION ALL", + "INSERT INTO VALUES", + "INSERT INTO SELECT VALUES", + "INSERT INTO", + "DELETE WHERE", + "CREATE TABLE" + ]; + statement = await vscode.window.showQuickPick( + stlist, + { + placeHolder: "Select the statement for creating the Sql table", + } + ); + } + + if (!statement) { + vscode.window.showErrorMessage("No statement selected."); + return; + } + + // 4: Generate the Sql code using the selected statement + const sqlCode = createSql(formattedData, statement); + + if (!sqlCode) { + vscode.window.showErrorMessage("Failed to generate Sql code."); + return; + } + + // 5: Insert the generated code into the active editor + const editor = vscode.window.activeTextEditor; + if (editor) { + editor.edit((editBuilder) => { + editBuilder.insert(editor.selection.active, sqlCode); + }); + } + } catch (error) { + vscode.window.showErrorMessage(`Error: ${error.message}`); + } +} + +/** + * Generates a Sql script based on the provided table data. + */ +function createSql(tableData, statement) { + + /** + * Formats a value according to its column type for SQL syntax + * @param {any} value - The value to format + * @param {number} colIndex - Column index for type lookup + * @returns {string} Formatted value + */ + function formatValue(value, colIndex) { + if (value === "") { + return "NULL"; + } else if (columnTypes[colIndex] === "string") { + return `'${value}'`; + } else if (columnTypes[colIndex] === "numeric") { + return addTrailingZeroes(value); + } else if (columnTypes[colIndex] === "boolean") { + return normalizeBool(value, "javascript"); + } else if (columnTypes[colIndex] === "integer") { + return value; + } else { + return `'${value}'`; + } + } + + function getSqlTypeFor(colIndex) { + let colt = columnTypes[colIndex]; + if (colt === "string") { + return "VARCHAR(100)"; + } else if (colt === "numeric") { + return "NUMERIC(9,6)"; + } else if (colt === "boolean") { + return "BOOLEAN"; + } else if (colt === "integer") { + return "INTEGER"; + } else { + return "VARCHAR(50)"; + } + } + + function getRowsAs(rows, cols, template, colstart, colsep, colend, rowsep) { + let lines = []; + rows.forEach((row) => { + const vals = row + .map(function (value, i) { + let nam1 = cols[i]; + let val2 = formatValue(value, i); + let res1 = template.replace("{1}", nam1); + let res2 = res1.replace("{2}", val2); + return res2; + }).join(colsep); + lines = lines.concat(colstart + vals + colend); + }); + if (lines.length > 0) { + return lines.join(rowsep); + } + return ""; + } + + // Pads a value to the target width + function padToWidth(value, width, padding) { + let wide = width - value.toString().length; + return value +padding.repeat(wide); + } + + function getRowsAsTuple(rows, cols) { + return getRowsAs(rows, cols, "{2}", " (", ", ", ")", ",\n"); + } + + function getRowsAsUnionAll(rows, cols) { + return getRowsAs(rows, cols, "{2} AS {1}", " SELECT", ", ", "", " UNION ALL\n"); + } + + function getColumnsAsTuple(cols) { + let cols2 = cols ? cols.join(", ") : ""; + return `(${cols2})`; + } + + function getSqlAsCreateTable(rows, cols) { + let width = cols.reduce((prev, col) => prev > col.length ? prev : col.length, 0); + let names = cols.map(function (value, i) { + let colname = padToWidth(value, width, " "); + let coltype = getSqlTypeFor(i); + return ` ${colname} ${coltype}`; + }); + let fields = names.join(",\n"); + let drop = "-- DROP TABLE IF EXISTS mytable;"; + let sql = `${drop}\n\nCREATE TABLE IF NOT EXISTS mytable (\n${fields}\n);\n\n`; + return sql; + } + + function getSqlAsSelectFromValues(rows, cols) { + let names = getColumnsAsTuple(cols); + let lines = getRowsAsTuple(rows, cols); + let sql = `SELECT * FROM (VALUES\n${lines}\n) AS t${names};\n`; + return sql; + } + + function getSqlAsSelectUnionAll(rows, cols) { + let lines = getRowsAsUnionAll(rows, cols); + let sql = `WITH mytable AS (\n${lines}\n)\nSELECT m.* FROM mytable AS m;\n`; + return sql; + } + + function getSqlAsInsertFromSelectValues(rows, cols) { + let sql = getSqlAsSelectFromValues(rows, cols); + return `INSERT INTO mytable\n${sql}`; + } + + function getSqlAsInsertIntoValues(rows, cols) { + let names = getColumnsAsTuple(cols); + let lines = getRowsAsTuple(rows, cols); + let sql = `INSERT INTO mytable\n ${names}\nVALUES\n${lines};\n`; + return sql; + } + + function getSqlAsInsertIntoMultiple(rows, cols) { + let names = getColumnsAsTuple(cols); + let pre = `INSERT INTO mytable ${names} VALUES (`; + let sql = getRowsAs(rows, cols, "{2}", pre, ", ", ");", "\n"); + return sql + "\n"; + } + + function getSqlAsDeleteWhere(rows, cols) { + let names = getColumnsAsTuple(cols); + let pre = `DELETE FROM mytable WHERE `; + let sql = getRowsAs(rows, cols, "{1} = {2}", pre, " AND ", "", ";\n"); + let res = sql.replaceAll("= NULL", "IS NULL") + ";\n\n"; + return res; + } + + const { headers, data, columnTypes } = tableData; + switch (statement) { + case "SELECT FROM VALUES": + return getSqlAsSelectFromValues(data, headers); + case "SELECT UNION ALL": + return getSqlAsSelectUnionAll(data, headers); + case "INSERT INTO VALUES": + return getSqlAsInsertIntoValues(data, headers); + case "INSERT INTO SELECT VALUES": + return getSqlAsInsertFromSelectValues(data, headers); + case "INSERT INTO": + return getSqlAsInsertIntoMultiple(data, headers); + case "DELETE WHERE": + return getSqlAsDeleteWhere(data, headers); + case "CREATE TABLE": + return getSqlAsCreateTable(data, headers); + } + return ""; +} + +module.exports = { + clipboardToSql, +}; diff --git a/test/extension.test.js b/test/extension.test.js index 64a1dfb..d2f78a7 100644 --- a/test/extension.test.js +++ b/test/extension.test.js @@ -157,6 +157,7 @@ suite('Pastum Extension Test Suite', () => { 'pastum.Jldataframe', 'pastum.JSdataframe', 'pastum.Markdown', + 'pastum.Sql', 'pastum.Defaultdataframe' ]; diff --git a/test/paste-modules.test.js b/test/paste-modules.test.js index 91aaf7d..3c02c3e 100644 --- a/test/paste-modules.test.js +++ b/test/paste-modules.test.js @@ -6,6 +6,7 @@ const pastePython = require('../src/paste-python'); const pasteJulia = require('../src/paste-julia'); const pasteJS = require('../src/paste-js'); const pasteMarkdown = require('../src/paste-markdown'); +const pasteSql = require('../src/paste-sql'); const pasteDefault = require('../src/paste-default'); suite('Paste Modules Test Suite', () => { @@ -48,6 +49,7 @@ suite('Paste Modules Test Suite', () => { case 'defaultDataframePython': return 'pandas 🐼'; case 'defaultDataframeJavascript': return 'polars 🐻'; case 'defaultAligmentMarkdown': return 'columnar ↔️'; + case 'defaultSqlStatement': return 'INSERT INTO VALUES'; default: return null; } } @@ -92,6 +94,12 @@ suite('Paste Modules Test Suite', () => { }); }); + suite('Sql Paste Module Tests', () => { + test('clipboardToSql - function exists', () => { + assert.strictEqual(typeof pasteSql.clipboardToSql, 'function'); + }); + }); + suite('Default Paste Module Tests', () => { test('pasteDefault - function exists', () => { assert.strictEqual(typeof pasteDefault.pasteDefault, 'function'); From 17082fed58d43fb4de3d55324b0529a330bddf1c Mon Sep 17 00:00:00 2001 From: Juarez Rudsatz Date: Wed, 10 Sep 2025 18:58:33 -0300 Subject: [PATCH 2/9] Added documentation regarding sql conversion --- README.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 00d780c..176a588 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Or you can specify the `pastum.defaultDataframeR`/`pastum.defaultDataframePython - Julia: `DataFrames.jl` - JavaScript: `base`, `polars 🐻`, `arquero 🏹`, `danfo 🐝` - Markdown: `columnar ↔️`, `compact ↩️` -- SQL: work in progress +- SQL: many options to generate SELECT, INSERT, UPDATE, MERGE, AND CREATE TABLE statements. `pastum` recognises tables in the following formats: text, HTML, CSV, TSV. diff --git a/package.json b/package.json index 50bef4f..1e34c10 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pastum", "displayName": "Pastum", - "description": "Convert table from clipboard to R, Python, Julia, JS or Markdown dataframe", + "description": "Convert table from clipboard to R, Python, Julia, or JS dataframes and also to SQL or Markdown", "version": "0.3.0", "publisher": "atsyplenkov", "license": "MIT", From 7baebaeb414a9405bf55c90357664bcca530f8aa Mon Sep 17 00:00:00 2001 From: Juarez Rudsatz Date: Thu, 11 Sep 2025 14:52:23 -0300 Subject: [PATCH 3/9] feat: Add UPDATE WHERE SQL statement --- package.json | 1 + src/paste-sql.js | 78 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 1e34c10..facfc72 100644 --- a/package.json +++ b/package.json @@ -168,6 +168,7 @@ "INSERT INTO SELECT VALUES", "INSERT INTO", "DELETE WHERE", + "UPDATE WHERE", "CREATE TABLE" ], "default": "INSERT INTO VALUES", diff --git a/src/paste-sql.js b/src/paste-sql.js index f9bad80..0f030d8 100644 --- a/src/paste-sql.js +++ b/src/paste-sql.js @@ -3,20 +3,21 @@ const { parseClipboard } = require("./parse-table"); const { addTrailingZeroes, normalizeBool } = require("./utils"); async function clipboardToSql(statement = null) { + + function abortOnError(message) { + vscode.window.showErrorMessage(message); + } + try { // 1: Read the clipboard content const clipboardContent = await vscode.env.clipboard.readText(); if (!clipboardContent) { - vscode.window.showErrorMessage( - "Clipboard is empty or contains unsupported content." - ); - return; + return abortOnError("Clipboard is empty or contains unsupported content."); } // 2: Try to extract the table from clipboard content - let formattedData = null; - formattedData = parseClipboard(clipboardContent); + let tableData = parseClipboard(clipboardContent); // 3: Ask the user which statement they want to use if (statement === null) { @@ -27,6 +28,7 @@ async function clipboardToSql(statement = null) { "INSERT INTO SELECT VALUES", "INSERT INTO", "DELETE WHERE", + "UPDATE WHERE", "CREATE TABLE" ]; statement = await vscode.window.showQuickPick( @@ -38,16 +40,28 @@ async function clipboardToSql(statement = null) { } if (!statement) { - vscode.window.showErrorMessage("No statement selected."); - return; + return abortOnError("No SQL statement selected."); + } + + let keyColumns = []; + if (statement === "UPDATE WHERE") { + keyColumns = await vscode.window.showQuickPick( + tableData.headers, + { + placeHolder: "Select the key columns for matching rows", + canPickMany: true + } + ); + if (!keyColumns || keyColumns.length === 0) { + return abortOnError("No key columns for matching rows selected."); + } } // 4: Generate the Sql code using the selected statement - const sqlCode = createSql(formattedData, statement); + const sqlCode = createSql(tableData, statement, keyColumns); if (!sqlCode) { - vscode.window.showErrorMessage("Failed to generate Sql code."); - return; + return abortOnError("Failed to generate Sql code."); } // 5: Insert the generated code into the active editor @@ -58,14 +72,14 @@ async function clipboardToSql(statement = null) { }); } } catch (error) { - vscode.window.showErrorMessage(`Error: ${error.message}`); + abortOnError(`Error: ${error.message}`); } } /** * Generates a Sql script based on the provided table data. */ -function createSql(tableData, statement) { +function createSql(tableData, statement, keyColumns) { /** * Formats a value according to its column type for SQL syntax @@ -123,10 +137,33 @@ function createSql(tableData, statement) { return ""; } + function getRowsAs2Columns( + rows, cols, keys, + template1, col1start, col1sep, col1end, + template2, col2start, col2sep, col2end) { + + const lines = rows.map(function (row, j) { + const vals = row.map(function (value, i) { + let nam1 = cols[i]; + let val2 = formatValue(value, i); + let pos = keys.indexOf(nam1) < 0 ? 1 : 2; + let tpl = pos === 1 ? template1 : template2; + let res = tpl.replace("{1}", nam1).replace("{2}", val2); + return [res, pos]; + }); + let val1 = vals.filter(v => v[1] === 1).map(v => v[0]); + let val2 = vals.filter(v => v[1] === 2).map(v => v[0]); + let text1 = col1start + val1.join(col1sep) + col1end; + let text2 = col2start + val2.join(col2sep) + col2end; + return [text1, text2]; + }); + return lines; + } + // Pads a value to the target width function padToWidth(value, width, padding) { let wide = width - value.toString().length; - return value +padding.repeat(wide); + return value + padding.repeat(wide); } function getRowsAsTuple(rows, cols) { @@ -134,7 +171,7 @@ function createSql(tableData, statement) { } function getRowsAsUnionAll(rows, cols) { - return getRowsAs(rows, cols, "{2} AS {1}", " SELECT", ", ", "", " UNION ALL\n"); + return getRowsAs(rows, cols, "{2} AS {1}", " SELECT ", ", ", "", " UNION ALL\n"); } function getColumnsAsTuple(cols) { @@ -195,6 +232,15 @@ function createSql(tableData, statement) { return res; } + function getSqlAsUpdateWhere(rows, cols, keys) { + const vals = getRowsAs2Columns( + rows, cols, keys, "{1} = {2}", "", ", ", "", "{1} = {2}", "", " AND ", "" + ); + let stmt = `UPDATE mytable SET {1} WHERE {2};`; + let sql = vals.map(v => stmt.replace("{1}", v[0]).replace("{2}", v[1].replaceAll("= NULL", "IS NULL"))); + return sql.join("\n") + "\n\n"; + } + const { headers, data, columnTypes } = tableData; switch (statement) { case "SELECT FROM VALUES": @@ -209,6 +255,8 @@ function createSql(tableData, statement) { return getSqlAsInsertIntoMultiple(data, headers); case "DELETE WHERE": return getSqlAsDeleteWhere(data, headers); + case "UPDATE WHERE": + return getSqlAsUpdateWhere(data, headers, keyColumns); case "CREATE TABLE": return getSqlAsCreateTable(data, headers); } From c0331b5b135559457091d262d995f98e479230f7 Mon Sep 17 00:00:00 2001 From: Juarez Rudsatz Date: Thu, 11 Sep 2025 15:36:29 -0300 Subject: [PATCH 4/9] feat: Add MERGE INTO SQL statement --- package.json | 1 + src/paste-sql.js | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index facfc72..81dcee0 100644 --- a/package.json +++ b/package.json @@ -169,6 +169,7 @@ "INSERT INTO", "DELETE WHERE", "UPDATE WHERE", + "MERGE INTO", "CREATE TABLE" ], "default": "INSERT INTO VALUES", diff --git a/src/paste-sql.js b/src/paste-sql.js index 0f030d8..a0a7055 100644 --- a/src/paste-sql.js +++ b/src/paste-sql.js @@ -29,6 +29,7 @@ async function clipboardToSql(statement = null) { "INSERT INTO", "DELETE WHERE", "UPDATE WHERE", + "MERGE INTO", "CREATE TABLE" ]; statement = await vscode.window.showQuickPick( @@ -44,7 +45,7 @@ async function clipboardToSql(statement = null) { } let keyColumns = []; - if (statement === "UPDATE WHERE") { + if (statement === "UPDATE WHERE" || statement === "MERGE INTO") { keyColumns = await vscode.window.showQuickPick( tableData.headers, { @@ -205,6 +206,23 @@ function createSql(tableData, statement, keyColumns) { return sql; } + function getSqlAsMergeInto(rows, cols, keys) { + let unionall = getRowsAsUnionAll(rows, cols); + let onkeys = keys.map(k => `t2.${k} = s1.${k}`).join("\n AND "); + let nonkeys = cols.filter(k => keys.indexOf(k) < 0); + let upset = nonkeys.map(k => ` ${k} = s1.${k}`).join(",\n"); + let c1 = cols.join(", "); + let c2 = cols.join(", s1."); + let into = ` INSERT (${c1})\n VALUES (s1.${c2})`; + + let sql = `MERGE INTO mytable AS t2 USING(\n${unionall}\n` + + ` ) AS s1\n ON ${onkeys}\n` + + `WHEN MATCHED THEN UPDATE SET\n${upset}\n` + + `WHEN NOT MATCHED THEN\n${into}\n` + + `WHEN NOT MATCHED BY SOURCE THEN\n DELETE;\n`; + return sql; + } + function getSqlAsInsertFromSelectValues(rows, cols) { let sql = getSqlAsSelectFromValues(rows, cols); return `INSERT INTO mytable\n${sql}`; @@ -257,6 +275,8 @@ function createSql(tableData, statement, keyColumns) { return getSqlAsDeleteWhere(data, headers); case "UPDATE WHERE": return getSqlAsUpdateWhere(data, headers, keyColumns); + case "MERGE INTO": + return getSqlAsMergeInto(data, headers, keyColumns); case "CREATE TABLE": return getSqlAsCreateTable(data, headers); } From d81320ddbfe1c78463827d5ccbb4412fdd0e4daa Mon Sep 17 00:00:00 2001 From: Anatolii Tsyplenkov <34775595+atsyplenkov@users.noreply.github.com> Date: Fri, 19 Sep 2025 04:30:47 +0000 Subject: [PATCH 5/9] bump version to v0.3.1 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 81dcee0..1ec879f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "pastum", "displayName": "Pastum", "description": "Convert table from clipboard to R, Python, Julia, or JS dataframes and also to SQL or Markdown", - "version": "0.3.0", + "version": "0.3.1", "publisher": "atsyplenkov", "license": "MIT", "pricing": "Free", @@ -188,4 +188,4 @@ "@vscode/test-electron": "^2.5.2", "typescript": "^5.9.2" } -} \ No newline at end of file +} From 8a729e8431bc28f75fab227f74e1c95c6679dfa4 Mon Sep 17 00:00:00 2001 From: Anatolii Tsyplenkov <34775595+atsyplenkov@users.noreply.github.com> Date: Fri, 19 Sep 2025 04:33:15 +0000 Subject: [PATCH 6/9] bump to dev version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1ec879f..4b1caff 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "pastum", "displayName": "Pastum", "description": "Convert table from clipboard to R, Python, Julia, or JS dataframes and also to SQL or Markdown", - "version": "0.3.1", + "version": "0.3.0.9000", "publisher": "atsyplenkov", "license": "MIT", "pricing": "Free", From 782d30f53bcfec9d26146f9423b452a0010e00ab Mon Sep 17 00:00:00 2001 From: Anatolii Tsyplenkov <34775595+atsyplenkov@users.noreply.github.com> Date: Fri, 19 Sep 2025 04:38:21 +0000 Subject: [PATCH 7/9] update package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4b1caff..1ec879f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "pastum", "displayName": "Pastum", "description": "Convert table from clipboard to R, Python, Julia, or JS dataframes and also to SQL or Markdown", - "version": "0.3.0.9000", + "version": "0.3.1", "publisher": "atsyplenkov", "license": "MIT", "pricing": "Free", From e104372963077da0bc5b8ac2b24e2fc7d8e1992b Mon Sep 17 00:00:00 2001 From: Juarez Rudsatz Date: Fri, 19 Sep 2025 14:37:35 -0300 Subject: [PATCH 8/9] docs: updated changelog regarding SQL script --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c1cb64..16c330c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ### Added +- Support to generate SQL statements for querying and modifying database tables (in #41, thanks to @juarezr) - Markdown table support (thanks to @juarezr) - TSV and CSV table support (thanks to @juarezr) - `pastum.libraryDeclaration` configuration option, which allows the user to add library declaration to the pasted dataframe. (#18) From 2692c3a1d9703e5058e7b191adf35ded879d4374 Mon Sep 17 00:00:00 2001 From: Anatolii Tsyplenkov <34775595+atsyplenkov@users.noreply.github.com> Date: Sat, 20 Sep 2025 04:21:31 +0000 Subject: [PATCH 9/9] Update CHANGELOG.md --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16c330c..c9f1dfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,12 @@ ## Development version ### Added - - Support to generate SQL statements for querying and modifying database tables (in #41, thanks to @juarezr) + +## [0.3.0] - 2025-09-12 + +### Added + - Markdown table support (thanks to @juarezr) - TSV and CSV table support (thanks to @juarezr) - `pastum.libraryDeclaration` configuration option, which allows the user to add library declaration to the pasted dataframe. (#18)