All files / src/rules sql_value_conversion.ts

97.43% Statements 76/78
92.3% Branches 12/13
100% Functions 7/7
97.43% Lines 76/78

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 781x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11092x 11092x 11092x 11092x 11092x 33123x 33123x 33123x 33123x 33123x 33123x 33123x 33123x 33123x 33123x 33123x 33123x 33123x 33123x 11092x 11092x 10571x 10571x 11092x 11092x 244x 244x 11092x 11092x 250x 250x 250x 11092x 11092x 333x 333x 91x 91x 242x 242x 242x 242x 242x 242x 242x 11092x 11092x 1106x 1106x 1106x 3x 3x     3x 3x 1106x 1106x 864x 864x 1106x 1106x 1106x 11092x 11092x
import {Issue} from "../issue";
import {IRule, IRuleMetadata} from "./_irule";
import {IObject} from "../objects/_iobject";
import {IRegistry} from "../_iregistry";
import {BasicRuleConfig} from "./_basic_rule_config";
import {Interface} from "../objects";
import {SyntaxLogic} from "../abap/5_syntax/syntax";
import {ABAPObject} from "../objects/_abap_object";
import {ISpaghettiScopeNode} from "../abap/5_syntax/_spaghetti_scope";
 
export class SQLValueConversionConf extends BasicRuleConfig {
}
 
export class SQLValueConversion implements IRule {
  private conf = new SQLValueConversionConf();
  private reg: IRegistry;
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "sql_value_conversion",
      title: "Implicit SQL Value Conversion",
      shortDescription: `Ensure types match when selecting from database`,
      extendedInformation: `
* Integer to CHAR conversion
* Integer to NUMC conversion
* NUMC to Integer conversion
* CHAR to Integer conversion
* Source field longer than database field, CHAR -> CHAR
* Source field longer than database field, NUMC -> NUMC`,
      tags: [],
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: SQLValueConversionConf) {
    this.conf = conf;
  }
 
  public initialize(reg: IRegistry): IRule {
    this.reg = reg;
    return this;
  }
 
  public run(obj: IObject): Issue[] {
 
    if (!(obj instanceof ABAPObject) || obj instanceof Interface) {
      return [];
    }
 
    // messages defined in sql_compare.ts
 
    const issues = this.traverse(new SyntaxLogic(this.reg, obj).run().spaghetti.getTop());
 
    return issues;
  }
 
  private traverse(node: ISpaghettiScopeNode): Issue[] {
    const ret: Issue[] = [];
 
    for (const r of node.getData().sqlConversion) {
      const file = this.reg.getFileByName(node.getIdentifier().filename);
      if (file === undefined) {
        continue;
      }
      ret.push(Issue.atToken(file, r.token, r.message, this.getMetadata().key, this.getConfig().severity));
    }
 
    for (const c of node.getChildren()) {
      ret.push(...this.traverse(c));
    }
 
    return ret;
  }
 
}