Skip to content

Commit

Permalink
HCK-6309: american express support for couchbasev7plus fle (#34)
Browse files Browse the repository at this point in the history
* HCK-6309: add PP config for PK structure

* HCK-6309: add randexp module

* HCK-6309: add generating key sample by PK structure

* HCK-6309: clear js docs

* update package-lock

* fix prettier issue
  • Loading branch information
serhii-filonenko authored Jun 20, 2024
1 parent 0421f99 commit ac87bac
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* @typedef {import('../../../shared/types').PkSegment} PkSegment
* @typedef {import('../../../shared/types').UUID} UUID
*/
const RandExp = require('randexp');
const { PK_SEGMENT_TYPE } = require('../../../shared/constants');

/**
* @param {{ collection: object, jsonData: object }}
* @returns {string}
*/
const getPrimaryKeySampleByStructure = ({ collection, jsonData }) => {
const keyField = Object.values(collection.properties || {}).find(field => field.primaryKeyStructure);
const primaryKeyStructure = keyField?.primaryKeyStructure;

if (!Array.isArray(primaryKeyStructure)) {
return '';
}

return primaryKeyStructure.reduce((result, segment) => {
switch (segment.segmentType) {
case PK_SEGMENT_TYPE.field: {
const segmentValue = getPrimaryKeyStructureFieldValue({ segment, collection, jsonData });
return result + segmentValue;
}
case PK_SEGMENT_TYPE.pattern: {
const segmentValue = getPrimaryKeyStructurePatternValue({ segment });
return result + segmentValue;
}
case PK_SEGMENT_TYPE.constant:
case PK_SEGMENT_TYPE.separator: {
return result + (segment.segmentValue ?? '');
}
default:
return result;
}
}, '');
};

/**
* @param {{ segment: PkSegment, collection: object, jsonData: object }}
* @returns {string}
*/
const getPrimaryKeyStructureFieldValue = ({ segment, collection, jsonData }) => {
const fieldNames = (segment.segmentKey || []).map(({ keyId }) => {
return findFieldNameById({ collection, id: keyId });
});

return fieldNames
.filter(Boolean)
.map(fieldName => jsonData[fieldName])
.join('');
};

/**
* @param {{ segment: PkSegment }}
* @returns {string}
*/
const getPrimaryKeyStructurePatternValue = ({ segment }) => {
try {
const randExpInstance = new RandExp(segment.segmentRegex);

return randExpInstance.gen();
} catch (e) {
return segment.segmentSample ?? '';
}
};

/**
* @param {{ collection: object, id: UUID }}
* @returns {string}
*/
const findFieldNameById = ({ collection, id }) => {
return Object.entries(collection.properties || {}).reduce((result, [fieldName, field]) => {
if (result) {
return result;
}

if (field.GUID === id) {
return fieldName;
}

return findFieldNameById({ collection: field, id });
}, '');
};

module.exports = {
getPrimaryKeySampleByStructure,
};
14 changes: 4 additions & 10 deletions forward_engineering/services/statements/insertStatements.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const uuid = require('uuid');
const { getKeySpaceReference } = require('./commonStatements');
const { getPrimaryKeySampleByStructure } = require('./getPrimaryKeySampleByStructure');

/**
*
Expand Down Expand Up @@ -38,21 +39,14 @@ const getInsertScriptForCollection = ({ jsonData, collection }) => {
const isKeyGeneratedWithFakerFunction = collection?.properties?.[keyPropertyName]?.fakerFunction;
const parseJsonData = JSON.parse(jsonData);
const sampleValue = collection?.properties?.[keyPropertyName]?.sample;
const keyValue = isKeyGeneratedWithFakerFunction ? parseJsonData[keyPropertyName] : sampleValue;
const keySample = isKeyGeneratedWithFakerFunction ? parseJsonData[keyPropertyName] : sampleValue;
const { [keyPropertyName]: keyProperty, ...jsonDataBody } = parseJsonData;

const sampledKey = getKeyFieldSample(keyValue);
const pkSample = getPrimaryKeySampleByStructure({ collection, jsonData: parseJsonData });
const sampledKey = pkSample || keySample || uuid.v4();

return `INSERT INTO ${insertionPath} (KEY, VALUE)\n\tVALUES("${sampledKey}",${JSON.stringify(jsonDataBody, null, '\t')});`;
};

/**
*
* @param {string} jsonDataKey
* @returns {string}
*/
const getKeyFieldSample = jsonDataKey => jsonDataKey || uuid.v4();

module.exports = {
getInsertScripts,
getInsertScriptForCollection,
Expand Down
29 changes: 29 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@
"package": "node esbuild.package.js"
},
"dependencies": {
"antlr4": "4.9.2",
"async": "3.2.5",
"exponential-backoff": "3.1.1",
"lodash": "4.17.21",
"uuid": "9.0.1",
"antlr4": "4.9.2"
"randexp": "0.5.3",
"uuid": "9.0.1"
},
"devDependencies": {
"@hackolade/hck-esbuild-plugins-pack": "0.0.1",
Expand All @@ -54,4 +55,4 @@
"prettier": "3.2.5",
"simple-git-hooks": "2.11.1"
}
}
}
93 changes: 93 additions & 0 deletions properties_pane/field_level/fieldLevelConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,99 @@ making sure that you maintain a proper JSON format.
"required",
"dependencies",
"primaryKey",
{
"propertyName": "PK Structure",
"propertyKeyword": "primaryKeyStructure",
"propertyTooltip": "For user-defined key structure, describe the different segments for the PK",
"propertyType": "group",
"structure": [
{
"propertyName": "Segment type",
"propertyKeyword": "segmentType",
"propertyTooltip": "Select from list of options",
"propertyType": "select",
"parentType": "primaryKeyStructure",
"options": ["constant", "separator", "field", "pattern"]
},
{
"propertyName": "Meaning",
"propertyKeyword": "segmentMeaning",
"propertyTooltip": "Keyword describing the segment",
"propertyType": "text",
"parentType": "primaryKeyStructure",
"dependency": {
"type": "or",
"values": [
{
"key": "segmentType",
"value": "constant"
},
{
"key": "segmentType",
"value": "pattern"
}
]
}
},
{
"propertyName": "Keys",
"propertyKeyword": "segmentKey",
"propertyType": "fieldList",
"template": "orderedList",
"parentType": "primaryKeyStructure",
"dependency": {
"key": "segmentType",
"value": "field"
}
},
{
"propertyName": "Value",
"propertyKeyword": "segmentValue",
"propertyTooltip": "Value for constants and separators",
"propertyType": "text",
"parentType": "primaryKeyStructure",
"dependency": {
"type": "or",
"values": [
{
"key": "segmentType",
"value": "constant"
},
{
"key": "segmentType",
"value": "separator"
}
]
}
},
{
"propertyName": "Regex",
"propertyKeyword": "segmentRegex",
"propertyTooltip": "",
"propertyType": "text",
"parentType": "primaryKeyStructure",
"dependency": {
"key": "segmentType",
"value": "pattern"
}
},
{
"propertyName": "Sample",
"propertyKeyword": "segmentSample",
"propertyTooltip": "",
"propertyType": "text",
"parentType": "primaryKeyStructure",
"dependency": {
"key": "segmentType",
"value": "pattern"
}
}
],
"dependency": {
"key": "containerLevelKey",
"value": true
}
},
"foreignCollection",
"foreignField",
"relationshipType",
Expand Down
11 changes: 11 additions & 0 deletions shared/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ const GET_META_REGEXP = /\(meta\(\)\.(.*?)\)/;
const GET_NODES_REGEXP = /"nodes":(\[.*?\])/;
const GET_PARTITION_HASH_REGEXP = /(HASH|hash)\((.*?)\)$/;

/**
* @enum {string}
*/
const PK_SEGMENT_TYPE = {
constant: 'constant',
field: 'field',
pattern: 'pattern',
separator: 'separator',
};

module.exports = {
AUTH_TYPE,
COUCHBASE_ERROR_CODE,
Expand All @@ -75,4 +85,5 @@ module.exports = {
GET_PARTITION_HASH_REGEXP,
HOSTING,
STATUS,
PK_SEGMENT_TYPE,
};
13 changes: 12 additions & 1 deletion shared/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Cluster, Scope, Bucket } from 'couchbase';
import { STATUS } from './constants';
import { PK_SEGMENT_TYPE } from './constants';

type UUID = string;

Expand Down Expand Up @@ -112,6 +112,16 @@ type InferenceProperty = {
type: string | Array<string>
}

type PkSegment = {
segmentType: Values<PK_SEGMENT_TYPE>;
segmentValue: string;
segmentPattern?: string;
segmentSample?: string;
segmentMeaning?: string;
segmentRegex?: string;
segmentKey?: Array<{ keyId: UUID }>;
};

export {
App,
AppLogger,
Expand All @@ -132,4 +142,5 @@ export {
Scope,
UUID,
InferenceProperty,
PkSegment,
};

0 comments on commit ac87bac

Please sign in to comment.