DBUtils.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { StringUtils } from "@imengyu/imengyu-utils";
  2. import { DataModel } from "@imengyu/js-request-transform";
  3. export interface SqlPlaceholder {
  4. index: number,
  5. length: number,
  6. name: string
  7. }
  8. /**
  9. * SQL静态参数的结构
  10. */
  11. export interface SqlStatcParams {
  12. [index: string]: any;
  13. }
  14. const sqlPlaceholderCache = new Map<string, SqlPlaceholder[]>();
  15. /**
  16. * 分割sql中的参数占位符
  17. * @param sql 原始sql
  18. * @returns
  19. */
  20. export function solveSqlPlaceholders(sql : string) {
  21. const hash = StringUtils.stringHashCode(sql);
  22. let result : SqlPlaceholder[]|null = null;
  23. if (sqlPlaceholderCache.has(hash))
  24. result = sqlPlaceholderCache.get(hash)!;
  25. if (result)
  26. return result;
  27. result = [];
  28. let currentBracketsStart = -1;
  29. let currentBracketsEnd = -1;
  30. let chr = '';
  31. for(let i = 0; i < sql.length; i++) {
  32. chr = sql.charAt(i);
  33. if(currentBracketsStart < 0) {
  34. if(chr === '{') currentBracketsStart = i;
  35. } else {
  36. if(chr === '}') {
  37. currentBracketsEnd = i;
  38. if(currentBracketsEnd - currentBracketsStart > 0) {
  39. result.push({
  40. index: currentBracketsStart,
  41. length: currentBracketsEnd - currentBracketsStart + 1,
  42. name: sql.substring(currentBracketsStart + 1, currentBracketsEnd)
  43. });
  44. } else {
  45. console.warn('Bad sql placeholder, the brackets dose not contains a name , at ' + currentBracketsStart);
  46. }
  47. currentBracketsEnd = -1;
  48. currentBracketsStart = -1;
  49. }
  50. }
  51. if(i === sql.length - 1 && currentBracketsStart >= 0) {
  52. console.warn('Bad sql placeholder, not found end brackets, at ' + currentBracketsStart);
  53. }
  54. }
  55. sqlPlaceholderCache.set(hash, result);
  56. return result;
  57. }
  58. /**
  59. * 按占位符和参数拼接最终sql
  60. * @param sql 原始sql
  61. * @param placeholders 占位符数据
  62. * @param args 传入参数
  63. * @returns
  64. */
  65. export function splicingSQL(sql : string, placeholders : SqlPlaceholder[], args: unknown[], fn : Function|null, staticParams : SqlStatcParams) {
  66. let result = '';
  67. let startOffset = 0;
  68. let funcArgNames = (fn ? (fn.toString()
  69. .replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s))/mg,'')
  70. .match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)?.[1]
  71. .split(/,/)) : null) || null;
  72. for (let i = 0; i < args.length; i++) {
  73. const item = args[i];
  74. if (item instanceof DataModel)
  75. args[i] = item.toServerSide();
  76. }
  77. for(let i = 0; i < placeholders.length; i++) {
  78. let p = placeholders[i];
  79. let index = p.name === '?' ? i : parseInt(p.name);
  80. let argval = null;
  81. if(index >= 0) argval = args[index];
  82. else {
  83. let ii = funcArgNames ? funcArgNames.indexOf(p.name) : -1;
  84. argval = ii >= 0 ? args[ii] : staticParams[p.name];
  85. }
  86. result = result.concat(sql.substring(startOffset, p.index), (argval !== null ? argval : ''));
  87. startOffset = p.index + p.length;
  88. if(i === placeholders.length - 1) {
  89. result = result.concat(sql.substring(startOffset));
  90. }
  91. }
  92. return result;
  93. }