Skip to content
18 changes: 18 additions & 0 deletions src/views/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ export function getHeader(options: {withCollapsed?: boolean} = {}): string {

#resultset tbody tr {
border-bottom: 1px solid var(--vscode-activityBar-border);
position: relative;
}

#resultset tbody [contenteditable="true"].nullable:before {
color: var(--vscode-banner-foreground);
position: absolute;
top: -22px;
content: "Shift+Enter for null";
background-color: var(--vscode-list-hoverBackground);
opacity: 1;
padding: 2px;
font-style: normal;
border: 1px solid var(--vscode-banner-foreground);
}

#resultset tbody .null {
font-style: italic;
background-color: var(--vscode-editor-wordHighlightBackground);
}

${options.withCollapsed ? /*css*/`
Expand Down
39 changes: 29 additions & 10 deletions src/views/results/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface BasicColumn {
name: string;
useInWhere: boolean
jsType: "number"|"asString";
isNullable: boolean,
maxInputLength?: number;
}

Expand Down Expand Up @@ -137,19 +138,14 @@ document.getElementById('resultset').onclick = function(e){
}

// Can return undefined or {updateStatement, bindings, saneStatement?}
const getSqlStatement = (newValue, withSane = false) => {
const getSqlStatement = (newValue, withSane = false, nullify = false) => {
const useRrn = updateKeyColumns.length === 1 && updateKeyColumns.some(col => col.name === 'RRN');

let bindings = [];
let updateStatement = 'UPDATE ' + updateTable.table + ' t SET t.' + chosenColumn + ' = ';

if (chosenColumnDetail.maxInputLength >= 4 && newValue === 'null') {
// If the column can fit 'null', then set it to null value
if (nullify) {
updateStatement += 'NULL';
} else if (chosenColumnDetail.maxInputLength < 4 && newValue === '-') {
// If the column cannot fit 'null', then '-' is the null value
updateStatement += 'NULL';

} else {
switch (chosenColumnDetail.jsType) {
case 'number':
Expand Down Expand Up @@ -223,7 +219,11 @@ document.getElementById('resultset').onclick = function(e){

// Already editable, just return
if (editableNode.contentEditable === 'true') return;
let nullify = false;
editableNode.contentEditable = true;
if((editableNode.classList.contains("null") || editableNode.parentNode.classList.contains("null")) && editableNode.innerText === 'null') {
editableNode.innerText = '';
}
editableNode.focus();
updateMessageWithSql(originalValue);

Expand All @@ -237,6 +237,9 @@ document.getElementById('resultset').onclick = function(e){

switch (e.key) {
case 'Enter':
if(chosenColumnDetail.isNullable && e.shiftKey) {
nullify = true;
}
e.preventDefault();
editableNode.blur();
break;
Expand All @@ -263,19 +266,31 @@ document.getElementById('resultset').onclick = function(e){
editableNode.contentEditable = false;
let newValue = editableNode.innerText;

if (newValue === originalValue) return;
if (!nullify && newValue === originalValue) return;
if (chosenColumnDetail.maxInputLength && newValue.length > chosenColumnDetail.maxInputLength) {
newValue = newValue.substring(0, chosenColumnDetail.maxInputLength);
editableNode.innerText = newValue;
}

const sql = getSqlStatement(newValue);
const sql = getSqlStatement(newValue, false, nullify);

if (!sql) {
editableNode.innerHTML = originalValue;
return;
}

if(nullify) {
editableNode.innerHTML = "null";
if(editableNode.tagName.toLowerCase() === "td") {
editableNode.classList.add("null");
} else {
editableNode.parentNode.classList.add("null");
}
} else {
editableNode.classList.remove("null");
editableNode.parentNode.classList.remove("null");
}

requestCellUpdate(editableNode, originalValue, sql.updateStatement, sql.bindings);

editableNode = undefined;
Expand Down Expand Up @@ -481,6 +496,10 @@ export function generateScroller(basicSelect: string, isCL: boolean, withCancel?

let newDiv = document.createElement("div");
newDiv.className = "hoverable";
if(columnMetaData[currentColumn].nullable === 1) {
newCell.classList.add("nullable");
newDiv.classList.add("nullable");
}

// Append a formatted JSON object to the cell
const contentMightBeJson = typeof cell === 'string' && (cell.startsWith('{') || cell.startsWith('[')) && (cell.endsWith('}') || cell.endsWith(']'));
Expand All @@ -501,7 +520,7 @@ export function generateScroller(basicSelect: string, isCL: boolean, withCancel?
newDiv.style["font-family"] = "monospace";
newDiv.appendChild(document.createTextNode(cell === undefined ? 'null' : cell));
if(cell === undefined || cell === null) {
newDiv.style["font-style"] = "italic";
newCell.classList.add("null");
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/views/results/resultSetPanelProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ export class ResultSetPanelProvider implements WebviewViewProvider {
name: column.COLUMN_NAME,
jsType: column.NUMERIC_PRECISION ? `number` : `asString`,
useInWhere: column.IS_IDENTITY === `YES`,
isNullable: column.IS_NULLABLE === `Y`,
maxInputLength: column.CHARACTER_MAXIMUM_LENGTH
}));

Expand Down Expand Up @@ -263,7 +264,7 @@ export class ResultSetPanelProvider implements WebviewViewProvider {


basicSelect = `select rrn(${cName}) as RRN, ${possibleColumnList} from ${schema}.${ref.object.name} as ${cName} ${fromWhereClause || ``}`;
currentColumns = [{ name: `RRN`, jsType: `number`, useInWhere: true }, ...currentColumns];
currentColumns = [{ name: `RRN`, jsType: `number`, isNullable: false, useInWhere: true }, ...currentColumns];
}

updatable = {
Expand Down
Loading