2

这个东西的想法是用户可以从两个输入向 SQL 编辑器添加参数,一个用于参数本身,另一个用于其值

在此处输入图像描述 在此处输入图像描述

如果用户在 SQL 编辑器中编写,会自动添加参数和值的输入。

从 SQL 编辑器到输入它工作正常,因为我正在发送一个正则表达式。问题出在我尝试将输入发送到 SQL 编辑器的地方。我认为更像是一个逻辑问题,但我仍然没有找到解决方案。关键是,通过从输入中添加一个参数,它会添加超过所需的参数,即使我总是在添加之前清理它,但显然这并没有影响。

在此处输入图像描述

这是代码

import React, { useEffect, useState} from 'react';
import SQLContainerInput from '../Components/SQLContainerInput';

........

function arrayParamsExec(stringSql) {
 const paramsQueryText = [...stringSql.matchAll(/{{(\w+)}}/ig)];
 const newArray = paramsQueryText.map(item => item[1]);
 return newArray;
}

const initalStateCurrentChartInfo = {
  SQLQuery: '',
  dataType: 'TABLE',
  columns: [],
};

const CustomSQLEditor = ({
 fromQuery, // del Redux
}) = {
 const [currentChartInfo, setCurrentChartInfo] = useState(
  initalStateCurrentChartInfo,
 );
 const [params, setParams] = useState([]);
 const [textSql, setTextSql] = useState('');

 useEffect(() => {
   ....
   let sqlDefaultString = '';
   sqlDefaultString = fromQuery.internal_name
    ? `SELECT * FROM \`${fromQuery.internal_name}__${fromQuery.items[0]}\` LIMIT 20`
    : '';
   setCurrentChartInfo({
    ...currentChartInfo,
    SQLQuery: `${sqlQuery}`,
   });
 },[fromQuery]);

 // ------------------params---------------------
 const addProperty = () => {
  setParams([
    ...params,
   { name: '', value: '' },
  ]);
 };

 const updateProperty = (event, index, key) => {
  const newProperties = [...params];
  newProperties[index][key] = event?.target?.value;

  // agregar parámetros al editor SQL
  let sqlParams = textSql;
  if (key === 'name') {
    params.forEach(p => {
      if (p.name && /^\w+$/i.test(p.name)) {
        sqlParams += `{{${p.name}}}`;
      }
    });

    setTextSql('');
    setTextSql(`${sqlParams}`);
  }

  setParams(newProperties);
 };

 const deleteProperty = index => {
  const newProperties = [...params];
  newProperties.splice(index, 1);
  const newTextSQL = replaceAll(textSql, `{{${params[index]?.name}}}`, '');
  setTextSql(newTextSQL);
  setParams(newProperties);
 };

 // ------------------end params---------------------

 const changeTextEditor = (valueEditor) => {
    const namesParams = arrayParamsExec(valueEditor);
    const newProperties = namesParams.map((pName) => {
      const valueNew = params.find(p => p.name === pName);
      return {name: pName, value: valueNew?.value || ''};
    });
    setParams(newProperties);
    setTextSql(valueEditor);
 }

 return (
  <>
   <SQLContainerInput
     button={{
      onClick: handleSubmit,
     }}
     input={{
      value: `${textSql}\n`,
      onChange: changeTextEditor,
     }}
   />
   <DymanicKeyValueInputInput
     properties={params}
     updateProperty={updateProperty}
     deleteProperty={deleteProperty}
     addProperty={addProperty}
   />
  </>
 );
}

然后,我尝试设置另一个值作为解决方案textSql,它负责放置连接的字符串,而来自 redux 的字符串是fromQuery. redux 字符串设置在sqlParams变量中,添加时与参数连接,然后,我清理textSql

 ......
 const updateProperty = (event, index, key) => {
  const newProperties = [...params];
  newProperties[index][key] = event?.target?.value;

  // agregar parámetros al editor SQL
  let sqlParams = currentChartInfo.SQLQuery;
  if (key === 'name') {
    params.forEach(p => {
      if (p.name && /^\w+$/i.test(p.name)) {
        sqlParams += `{{${p.name}}}`;
      }
    });

    setTextSql('');
    setTextSql(`${sqlParams}`);
  }

  setParams(newProperties);
 };
 ......

那里的问题是,如果我直接从 SQL 编辑器编写,它会重置整个字符串,我的意思是,所有已经编写的内容,但是当我放置参数时它会起作用并且不会重复。我找不到这样做的方法,所以如果我做错了什么,我很抱歉。

例如,当我编写大型 SQL 文本时。

在此处输入图像描述

在此处输入图像描述

当从输入添加参数时,它会重置。

在此处输入图像描述 在此处输入图像描述

带有错误演示的视频:https ://www.youtube.com/watch?v= rQBPOPyeXlI 回购网址:https ://gitlab.com/albert925/parametrosui-a-editor-sql

4

1 回答 1

1

尝试这个:

import { useState, useEffect } from 'react';
import DymanicKeyValueInputInput from './components/DymanicKeyValueInputInput';
import SQLContainerInput from './components/SQLContainerInput';
import { fromQuery } from './bd/data';
import { replaceAll, arrayParamsExec } from './utils/strings';
import { Content, ContentAddButton } from './stylesApp';

const initalStateCurrentChartInfo = {
  SQLQuery: '',
  columns: [],
};

function App() {
  const [currentChartInfo, setCurrentChartInfo] = useState(
    initalStateCurrentChartInfo,
  );
  const [params, setParams] = useState([]);
  const [textSql, setTextSql] = useState('');
  const [endSql, setendSql] = useState('');

  useEffect(() => {
    let sqlQuery = '';
    sqlQuery = fromQuery.internal_name
     ? `SELECT * FROM \`${fromQuery.internal_name}__${fromQuery.items[0]}\` LIMIT 20`
     : '';
    setCurrentChartInfo({
     ...currentChartInfo,
     SQLQuery: `${sqlQuery}`,
    });
    setTextSql(sqlQuery);
  },[fromQuery]);

  useEffect(()=>{
    const endSql = replaceAll(textSql, '\n', '');
    setendSql('')
    setendSql(endSql);
  },[textSql]);

  const cleanSQLString = (string) => {
    //corto la cadena en {{
    //reemplazo {{ por "" en cada item
    //devuelvo el array con los reemplazos
    return string.split("{{").map(item=>item.replace("}}",""));
  }

  // ------------------params---------------------
  const addProperty = () => {
    setParams([
      ...params,
      { name: '', value: '' },
    ]);
  };

  const updateProperty = (event, index, key) => {
    const newProperties = [...params];
    newProperties[index][key] = event?.target?.value;

    let currentSQL = cleanSQLString(endSql);
    // clean the string so that then add parameters to sql
    if (key === 'name' && /^\w+$/i.test(event?.target?.value)) {
      let sqlParams;

      if(currentSQL.length > 1){
        sqlParams = `${currentSQL[0]}`;
      }else{
        sqlParams = `${endSql}`;
      }
      params.forEach(p => {
        if (p.name && /^\w+$/i.test(p.name)) {
          sqlParams += `{{${p.name}}}`;
        }
      });

      setTextSql('');
      setTextSql(`${sqlParams}`);

      /*if(currentSQL.length > 1){
        sqlParams = `${currentSQL[0]}`;
      }else{
        sqlParams = `${endSql}`;
      }
      console.log(sqlParams)
      // get parameter positions by regular expression
      const searchParamRegedix = arrayParamsExec(endSql);
      console.log(searchParamRegedix, 'searchParamRegedix')
      if (searchParamRegedix.paramsQueryText.length > 0) {
        console.log(111)
        // get the position
        const searchPosition = searchParamRegedix.paramsQueryText[index]?.index;
        // remove the old word in braces
        const deleteOldParam = replaceAll(sqlParams, `${searchParamRegedix.list[index]}`, '');
        // the remaining string is removed from the obtained position
        const deleteFirtsLetter = deleteOldParam.substr(searchPosition + 2);
        // the string is removed from the beginning to the position obtained
        const deleteRemaining = deleteOldParam.substr(0, searchPosition + 2)
        // the string of the beginning and end is combined with its parameter
        const contantString = deleteRemaining + event?.target?.value + deleteFirtsLetter;
        // the entire string is overwritten in the state
        setTextSql(contantString);
      }
      else{      
        params.forEach(p => {
          if (p.name && /^\w+$/i.test(p.name)) {
            sqlParams += `{{${p.name}}}`;
          }
        });
  
        setTextSql('');
        setTextSql(`${sqlParams}`);
      }*/

    }

    setParams(newProperties);
  };

  const deleteProperty = index => {
    const newProperties = [...params];
    newProperties.splice(index, 1);
    const newTextSQL = replaceAll(textSql, `{{${params[index]?.name}}}`, '');
    setTextSql(newTextSQL);
    setParams(newProperties);
  };

  // ------------------end params---------------------

  const changeTextEditor = (valueEditor) => {
    const namesParams = arrayParamsExec(valueEditor);
      // keep the value with the parameter with respect to adding a new parameter in the sql editor,
      // but if the parameter word is changed, the value is deleted
      const newProperties = namesParams.list.map((pName) => {
        const valueNew = params.find(p => p.name === pName);
        return {name: pName, value: valueNew?.value || ''};
      });
      setParams(newProperties);
      setTextSql(valueEditor);
  }

  return (
    <Content>
      <div>
        <SQLContainerInput
          input={{
            value: `${endSql}\n`,
            onChange: changeTextEditor,
          }}
        />
      </div>
      <div>
        <h2>PARAMS</h2>
        <ContentAddButton>
          <DymanicKeyValueInputInput
            properties={params}
            updateProperty={updateProperty}
            deleteProperty={deleteProperty}
            addProperty={addProperty}
            id="sqlapiparams"
            className="isMultipleInpustSelects"
            tilesColumns={["", ""]}
            inputsPlaceholder={["My_Parameter", "Type params value"]}
            isIconTransfer
            isIconError
          />
        </ContentAddButton>
      </div>
    </Content>
  );
}

export default App;

于 2021-09-28T11:12:20.920 回答