<commit_before>'use strict';

const path    = require('path');
const qforms = require('../../../qforms');
const Model  = require('../Model');

class DataSource extends Model {
    constructor(data, parent) {
        super(data, parent);
        this.application      = parent instanceof qforms.Application ? parent : null;
        this.page             = parent instanceof qforms.Page        ? parent : null;
        this.form             = parent instanceof qforms.Form        ? parent : null;
        this.keyColumns       = null;
        this.parentKeyColumns = null;
    }

    static async create(data, parent) {
        if (parent instanceof qforms.Form) {
            const form = parent;
            const name = data['@attributes'].name;
            const customClassFilePath = path.join(
                form.page.application.dirPath,
                'pages', form.page.name,
                'forms', form.name,
                'dataSources', name,
                `${name}.backend.js`
            );
            const content = await qforms.Helper.getFileContent(customClassFilePath);
            if (content) {
                const CustomClass = eval(content);
                return new CustomClass(data, parent);
            }
            return new qforms.SqlDataSource(data, parent);
        } else {
            return new DataSource(data, parent);
        }
    }

    async init() {
        // console.log('DataSource.init', this.name);
        await super.init();
        this.keyColumns       = this.getKeyColumns();
        this.parentKeyColumns = this.getParentKeyColumns();
    }

    getKeyColumns() {
        if (this.data.keyColumns === undefined || Object.keys(this.data.keyColumns).length === 0) {
            throw new Error(`${this.getFullName()}: data Source must have at least one key column`);
        }
        return Object.keys(this.data.keyColumns);
    }

    getParentKeyColumns() {
        return this.data.parentKeyColumns ? Object.keys(this.data.parentKeyColumns) : [];
    }

    checkColumn(row, column) {
        if (!row.hasOwnProperty(column)) {
            throw new Error(`${this.getFullName()}: no column '${column}' in result set`);
        }
    }

    checkAndCalcColumns(row) {
        // console.log('DataSource.checkAndCalcColumns', this.getFullName());
        this.keyColumns.forEach(column => {
            this.checkColumn(row, column);
        });
        this.parentKeyColumns.forEach(column => {
            this.checkColumn(row, column);
        });
        if (!(this.parent instanceof qforms.Form) || this.name !== 'default') return;
        Object.keys(this.parent.fields).forEach(name => {
            const field = this.parent.fields[name];
            const columnName = field.getAttr('column');
            if (!columnName) {
                throw new Error(`[${this.getFullName()}]: no column name`);
            }<commit_msg>fixed bug with create SqlDataSource instead of DataSource<commit_after>'use strict';

const path    = require('path');
const qforms = require('../../../qforms');
const Model  = require('../Model');

class DataSource extends Model {
    constructor(data, parent) {
        super(data, parent);
        this.application      = parent instanceof qforms.Application ? parent : null;
        this.page             = parent instanceof qforms.Page        ? parent : null;
        this.form             = parent instanceof qforms.Form        ? parent : null;
        this.keyColumns       = null;
        this.parentKeyColumns = null;
    }

    static async create(data, parent) {
        if (parent instanceof qforms.Form) {
            const form = parent;
            const name = data['@attributes'].name;
            const customClassFilePath = path.join(
                form.page.application.dirPath,
                'pages', form.page.name,
                'forms', form.name,
                'dataSources', name,
                `${name}.backend.js`
            );
            const content = await qforms.Helper.getFileContent(customClassFilePath);
            if (content) {
                const CustomClass = eval(content);
                return new CustomClass(data, parent);
            }
            return new DataSource(data, parent);
        } else {
            return new DataSource(data, parent);
        }
    }

    async init() {
        // console.log('DataSource.init', this.name);
        await super.init();
        this.keyColumns       = this.getKeyColumns();
        this.parentKeyColumns = this.getParentKeyColumns();
    }

    getKeyColumns() {
        if (this.data.keyColumns === undefined || Object.keys(this.data.keyColumns).length === 0) {
            throw new Error(`${this.getFullName()}: DataSource must have at least one key column`);
        }
        return Object.keys(this.data.keyColumns);
    }

    getParentKeyColumns() {
        return this.data.parentKeyColumns ? Object.keys(this.data.parentKeyColumns) : [];
    }

    checkColumn(row, column) {
        if (!row.hasOwnProperty(column)) {
            throw new Error(`${this.getFullName()}: no column '${column}' in result set`);
        }
    }

    checkAndCalcColumns(row) {
        // console.log('DataSource.checkAndCalcColumns', this.getFullName());
        this.keyColumns.forEach(column => {
            this.checkColumn(row, column);
        });
        this.parentKeyColumns.forEach(column => {
            this.checkColumn(row, column);
        });
        if (!(this.parent instanceof qforms.Form) || this.name !== 'default') return;
        Object.keys(this.parent.fields).forEach(name => {
            const field = this.parent.fields[name];
            const columnName = field.getAttr('column');
            if (!columnName) {
                throw new Error(`[${this.getFullName()}]: no column name`);
            }
{'fraction_non_alphanumeric': 0.1270358306188925, 'fraction_numerical': 0.0003428767358134751, 'mean_word_length': 1.9826175869120655, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2361582', 'n_tokens_mistral': 1527, 'n_tokens_neox': 1511, 'n_words': 338}