Repository: ignite Updated Branches: refs/heads/ignite-843-rc1 738b2b595 -> 3523917dd
IGNITE-1806 WIP rework UI and code generation to new queries API. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3523917d Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3523917d Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3523917d Branch: refs/heads/ignite-843-rc1 Commit: 3523917dd103535a44b24c2128b5893a0a7c2e39 Parents: 738b2b5 Author: vsisko <[email protected]> Authored: Fri Oct 30 16:14:39 2015 +0700 Committer: Alexey Kuznetsov <[email protected]> Committed: Fri Oct 30 16:14:39 2015 +0700 ---------------------------------------------------------------------- .../src/main/js/controllers/common-module.js | 28 +- .../main/js/controllers/metadata-controller.js | 264 +++++++++---------- .../main/js/controllers/models/metadata.json | 82 ++---- modules/control-center-web/src/main/js/db.js | 8 +- .../main/js/routes/generator/generator-java.js | 111 +++++--- .../main/js/routes/generator/generator-xml.js | 100 +++++-- .../src/main/js/views/includes/controls.jade | 89 ++++--- 7 files changed, 358 insertions(+), 324 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/controllers/common-module.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js index 6038732..8c62ca2 100644 --- a/modules/control-center-web/src/main/js/controllers/common-module.js +++ b/modules/control-center-web/src/main/js/controllers/common-module.js @@ -671,11 +671,9 @@ consoleModule.service('$common', [ return true; }, metadataForQueryConfigured: function (meta) { - var isEmpty = !isDefined(meta) || (isEmptyArray(meta.queryFields) - && isEmptyArray(meta.ascendingFields) - && isEmptyArray(meta.descendingFields) - && isEmptyArray(meta.textFields) - && isEmptyArray(meta.groups)); + var isEmpty = !isDefined(meta) || (isEmptyArray(meta.fields) + && isEmptyArray(meta.aliases) + && isEmptyArray(meta.indexes)); return !isEmpty; }, @@ -1121,11 +1119,12 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus) _tableFocus('DatabaseName' + field.focusId, index); } - else if (ui == 'table-query-groups') { - field.curGroupName = val.name; - field.curFields = val.fields; + else if (ui == 'table-indexes') { + field.curIndexName = val.name; + field.curIndexType = val.type; + field.curIndexFields = val.fields; - _tableFocus('GroupName', index); + _tableFocus(field.focusId, index); } } @@ -1153,13 +1152,14 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus) _tableFocus('DatabaseName' + field.focusId, -1); } - else if (ui == 'table-query-groups') { - field.newGroupName = null; - field.newFields = null; + else if (ui == 'table-indexes') { + field.newIndexName = null; + field.newIndexType = null; + field.newIndexFields = null; - _tableFocus('GroupName', -1); + _tableFocus(field.focusId, -1); } - else if (ui == 'table-query-group-fields') { + else if (ui == 'table-index-fields') { _tableFocus('FieldName', -1); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/controllers/metadata-controller.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/metadata-controller.js b/modules/control-center-web/src/main/js/controllers/metadata-controller.js index 8768bfe..d0f3f92 100644 --- a/modules/control-center-web/src/main/js/controllers/metadata-controller.js +++ b/modules/control-center-web/src/main/js/controllers/metadata-controller.js @@ -89,6 +89,8 @@ consoleModule.controller('metadataController', [ store: {xml: '', java: '', allDefaults: true} }; + $scope.indexType = $common.mkOptions(['SORTED', 'FULLTEXT', 'GEOSPATIAL']); + var presets = [ { db: 'oracle', @@ -184,8 +186,8 @@ consoleModule.controller('metadataController', [ $scope.supportedJavaTypes = $common.mkOptions($common.javaBuildInClasses); $scope.sortDirections = [ - {value: false, label: 'ASC'}, - {value: true, label: 'DESC'} + {value: true, label: 'ASC'}, + {value: false, label: 'DESC'} ]; $scope.panels = {activePanels: [0, 1]}; @@ -474,9 +476,7 @@ consoleModule.controller('metadataController', [ _.forEach($scope.loadMeta.tables, function (table) { if (table.use) { var qryFields = []; - var ascFields = []; - var descFields = []; - var groups = []; + var indexes = []; var keyFields = []; var valFields = []; @@ -498,17 +498,6 @@ consoleModule.controller('metadataController', [ javaName: toJavaName(name), javaType: jdbcType.javaType} } - function colType(colName) { - var col = _.find(table.cols, function (col) { - return col.name == colName; - }); - - if (col) - return $common.findJdbcType(col.type).javaType; - - return 'Unknown'; - } - var _containKey = false; _.forEach(table.cols, function (col) { @@ -518,12 +507,6 @@ consoleModule.controller('metadataController', [ if (!fieldIndexed(colName, table)) qryFields.push(queryField(colName, jdbcType)); - if (_.includes(table.ascCols, colName)) - ascFields.push(queryField(colName, jdbcType)); - - if (_.includes(table.descCols, colName)) - descFields.push(queryField(colName, jdbcType)); - if (col.key) { keyFields.push(dbField(colName, jdbcType)); @@ -538,22 +521,20 @@ consoleModule.controller('metadataController', [ var idxs = table.idxs; if (table.idxs) { - var indexes = Object.keys(idxs); + var tblIndexes = Object.keys(idxs); - _.forEach(indexes, function (indexName) { + _.forEach(tblIndexes, function (indexName) { var index = idxs[indexName]; var fields = Object.keys(index); - if (fields.length > 1) - groups.push( - {name: indexName, fields: _.map(fields, function (fieldName) { - return { - name: toJavaName(fieldName), - className: colType(fieldName), - direction: index[fieldName] - }; - })}); + indexes.push( + {name: indexName, type: 'SORTED', fields: _.map(fields, function (fieldName) { + return { + name: toJavaName(fieldName), + direction: !index[fieldName] + }; + })}); }); } @@ -580,10 +561,8 @@ consoleModule.controller('metadataController', [ meta.valueType = valType + dupSfx; meta.databaseSchema = table.schema; meta.databaseTable = tableName; - meta.queryFields = qryFields; - meta.ascendingFields = ascFields; - meta.descendingFields = descFields; - meta.groups = groups; + meta.fields = qryFields; + meta.indexes = indexes; meta.keyFields = keyFields; meta.valueFields = valFields; @@ -848,20 +827,13 @@ consoleModule.controller('metadataController', [ var qry = $common.metadataForQueryConfigured(item); if (qry) { - var groups = item.groups; - - if (groups && groups.length > 0) { - for (var i = 0; i < groups.length; i++) { - var group = groups[i]; - var fields = group.fields; - - if ($common.isEmptyArray(fields)) - return showPopoverMessage($scope.panels, 'query', 'groups' + i, 'Group fields are not specified'); + var indexes = item.indexes; - if (fields.length == 1) { - return showPopoverMessage($scope.panels, 'query', 'groups' + i, 'Group has only one field. Consider to use ascending or descending fields.'); - } - } + if (indexes && indexes.length > 0) { + _.forEach(indexes, function(index) { + if ($common.isEmptyArray(index.fields)) + return showPopoverMessage($scope.panels, 'query', 'indexes' + i, 'Group fields are not specified'); + }); } } @@ -1020,9 +992,8 @@ consoleModule.controller('metadataController', [ }; var pairFields = { - queryFields: {msg: 'Query field class', id: 'QryField'}, - ascendingFields: {msg: 'Ascending field class', id: 'AscField'}, - descendingFields: {msg: 'Descending field class', id: 'DescField'} + fields: {msg: 'Query field class', id: 'QryField', checkValidClass: true}, + aliases: {msg: 'Ascending field class', id: 'Alias', keyCol: 'field', valCol: 'alias', valColName: 'alias', checkEqualsSecondField: true} }; $scope.tablePairValid = function (item, field, index) { @@ -1031,20 +1002,30 @@ consoleModule.controller('metadataController', [ var pairValue = $table.tablePairValue(field, index); if (pairField) { - if (!$common.isValidJavaClass(pairField.msg, pairValue.value, true, $table.tableFieldId(index, 'Value' + pairField.id))) - return $table.tableFocusInvalidField(index, 'Value' + pairField.id); - var model = item[field.model]; if ($common.isDefined(model)) { var idx = _.findIndex(model, function (pair) { - return pair.name == pairValue.key + return pair[pairField.keyCol || 'name'] == pairValue.key; }); - // Found duplicate. + // Found duplicate by key. if (idx >= 0 && idx != index) return showPopoverMessage(null, null, $table.tableFieldId(index, 'Key' + pairField.id), 'Field with such name already exists!'); + + if (pairField.checkEqualsSecondField) { + idx = _.findIndex(model, function (pair) { + return pair[pairField.valCol || 'className'].toUpperCase() === pairValue.value.toUpperCase(); + }); + + // Found duplicate by value. + if (idx >= 0 && idx != index) + return showPopoverMessage(null, null, $table.tableFieldId(index, 'Value' + pairField.id), 'Field with such ' + pairField.valColName + ' already exists!'); + } } + + if (pairField.checkValidClass && !$common.isValidJavaClass(pairField.msg, pairValue.value, true, $table.tableFieldId(index, 'Value' + pairField.id))) + return $table.tableFocusInvalidField(index, 'Value' + pairField.id); } return true; @@ -1125,167 +1106,158 @@ consoleModule.controller('metadataController', [ } }; - function tableGroupValue(field, index) { - return index < 0 ? field.newGroupName : field.curGroupName; + function tableIndexName(field, index) { + return index < 0 ? field.newIndexName : field.curIndexName; } - $scope.tableGroupSaveVisible = function (field, index) { - return !$common.isEmptyString(tableGroupValue(field, index)); + function tableIndexType(field, index) { + return index < 0 ? field.newIndexType : field.curIndexType; + } + + $scope.tableIndexSaveVisible = function (field, index) { + return !$common.isEmptyString(tableIndexName(field, index)) && $common.isDefined(tableIndexType(field, index)); }; - $scope.tableGroupSave = function (field, index) { - var groupName = tableGroupValue(field, index); + $scope.tableIndexSave = function (field, curIdx) { + var indexName = tableIndexName(field, curIdx); + var indexType = tableIndexType(field, curIdx); + + var item = $scope.backupItem; - var groups = $scope.backupItem.groups; + var indexes = item.indexes; - if ($common.isDefined(groups)) { - var idx = _.findIndex(groups, function (group) { - return group.name == groupName; + if ($common.isDefined(indexes)) { + var idx = _.findIndex(indexes, function (index) { + return index.name == indexName; }); // Found duplicate. - if (idx >= 0 && idx != index) - return showPopoverMessage(null, null, $table.tableFieldId(index, 'GroupName'), 'Group with such name already exists!'); + if (idx >= 0 && idx != curIdx) + return showPopoverMessage(null, null, $table.tableFieldId(curIdx, 'IndexName'), 'Index with such name already exists!'); } - var item = $scope.backupItem; + if (curIdx < 0) { + var newIndex = {name: indexName, type: indexType}; - if (index < 0) { - var newGroup = {name: groupName}; - - if (item.groups) - item.groups.push(newGroup); + if (item.indexes) + item.indexes.push(newIndex); else - item.groups = [newGroup]; + item.indexes = [newIndex]; + } + else { + item.indexes[curIdx].name = indexName; + item.indexes[curIdx].type = indexType; } - else - item.groups[index].name = groupName; - if (index < 0) - $scope.tableGroupNewItem(field, item.groups.length - 1); + if (curIdx < 0) + $scope.tableIndexNewItem(field, item.indexes.length - 1); else { - var group = item.groups[index]; + var index = item.indexes[curIdx]; - if (group.fields || group.fields.length > 0) - $scope.tableGroupItemStartEdit(field, index, 0); + if (index.fields && index.fields.length > 0) + $scope.tableIndexItemStartEdit(field, curIdx, 0); else - $scope.tableGroupNewItem(field, index); + $scope.tableIndexNewItem(field, curIdx); } }; - $scope.tableGroupNewItem = function (field, groupIndex) { - var groupName = $scope.backupItem.groups[groupIndex].name; + $scope.tableIndexNewItem = function (field, indexIdx) { + var indexName = $scope.backupItem.indexes[indexIdx].name; - $table.tableNewItem({ui: 'table-query-group-fields', model: groupName}); + $table.tableNewItem({ui: 'table-index-fields', model: indexName}); field.newFieldName = null; - field.newClassName = null; - field.newDirection = false; + field.newDirection = true; }; - $scope.tableGroupNewItemActive = function (groupIndex) { - var groups = $scope.backupItem.groups; - - if (groups) { - var group = groups[groupIndex]; + $scope.tableIndexNewItemActive = function (itemIndex) { + var indexes = $scope.backupItem.indexes; - if (group) { - var groupName = group.name; + if (indexes) { + var index = indexes[itemIndex]; - return $table.tableNewItemActive({model: groupName}); - } + if (index) + return $table.tableNewItemActive({model: index.name}); } return false; }; - $scope.tableGroupItemEditing = function (groupIndex, index) { - var groups = $scope.backupItem.groups; + $scope.tableIndexItemEditing = function (itemIndex, curIdx) { + var indexes = $scope.backupItem.indexes; - if (groups) { - var group = groups[groupIndex]; + if (indexes) { + var index = indexes[itemIndex]; - if (group) - return $table.tableEditing({model: group.name}, index); + if (index) + return $table.tableEditing({model: index.name}, curIdx); } return false; }; - function tableGroupItemValue(field, index) { + function tableIndexItemValue(field, index) { return index < 0 - ? {name: field.newFieldName, className: field.newClassName, direction: field.newDirection} - : {name: field.curFieldName, className: field.curClassName, direction: field.curDirection}; + ? {name: field.newFieldName, direction: field.newDirection} + : {name: field.curFieldName, direction: field.curDirection}; } - $scope.tableGroupItemStartEdit = function (field, groupIndex, index) { - var groups = $scope.backupItem.groups; - - var group = groups[groupIndex]; + $scope.tableIndexItemStartEdit = function (field, indexIdx, curIdx) { + var index = $scope.backupItem.indexes[indexIdx]; - $table.tableState(group.name, index); + $table.tableState(index.name, curIdx); - var groupItem = group.fields[index]; + var indexItem = index.fields[curIdx]; - field.curFieldName = groupItem.name; - field.curClassName = groupItem.className; - field.curDirection = groupItem.direction; + field.curFieldName = indexItem.name; + field.curDirection = indexItem.direction; $focus('curFieldName'); }; - $scope.tableGroupItemSaveVisible = function (field, index) { - var groupItemValue = tableGroupItemValue(field, index); - - return !$common.isEmptyString(groupItemValue.name) && !$common.isEmptyString(groupItemValue.className); + $scope.tableIndexItemSaveVisible = function (field, index) { + return !$common.isEmptyString(tableIndexItemValue(field, index).name); }; - $scope.tableGroupItemSave = function (field, groupIndex, index) { - var groupItemValue = tableGroupItemValue(field, index); - - if (!$common.isValidJavaClass('Group field', groupItemValue.className, true, $table.tableFieldId(index, 'ClassName'))) - return $table.tableFocusInvalidField(index, 'ClassName'); + $scope.tableIndexItemSave = function (field, indexIdx, curIdx) { + var indexItemValue = tableIndexItemValue(field, curIdx); - var fields = $scope.backupItem.groups[groupIndex].fields; + var fields = $scope.backupItem.indexes[indexIdx].fields; if ($common.isDefined(fields)) { var idx = _.findIndex(fields, function (field) { - return field.name == groupItemValue.name; + return field.name == indexItemValue.name; }); // Found duplicate. - if (idx >= 0 && idx != index) - return showPopoverMessage(null, null, $table.tableFieldId(index, 'FieldName'), 'Field with such name already exists in group!'); + if (idx >= 0 && idx != curIdx) + return showPopoverMessage(null, null, $table.tableFieldId(curIdx, 'FieldName'), 'Field with such name already exists in index!'); } - var group = $scope.backupItem.groups[groupIndex]; + var index = $scope.backupItem.indexes[indexIdx]; - if (index < 0) { - if (group.fields) - group.fields.push(groupItemValue); + if (curIdx < 0) { + if (index.fields) + index.fields.push(indexItemValue); else - group.fields = [groupItemValue]; + index.fields = [indexItemValue]; - $scope.tableGroupNewItem(field, groupIndex); + $scope.tableIndexNewItem(field, indexIdx); } else { - var groupItem = group.fields[index]; - - groupItem.name = groupItemValue.name; - groupItem.className = groupItemValue.className; - groupItem.direction = groupItemValue.direction; + index.fields[curIdx] = indexItemValue; - if (index < group.fields.length - 1) - $scope.tableGroupItemStartEdit(field, groupIndex, index + 1); + if (curIdx < index.fields.length - 1) + $scope.tableIndexItemStartEdit(field, indexIdx, curIdx + 1); else - $scope.tableGroupNewItem(field, groupIndex); + $scope.tableIndexNewItem(field, indexIdx); } }; - $scope.tableRemoveGroupItem = function (group, index) { + $scope.tableRemoveIndexItem = function (index, curIdx) { $table.tableReset(); - group.fields.splice(index, 1); + index.fields.splice(curIdx, 1); }; $scope.resetItem = function (group) { http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/controllers/models/metadata.json ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/models/metadata.json b/modules/control-center-web/src/main/js/controllers/models/metadata.json index f56af9b..0f38b9f 100644 --- a/modules/control-center-web/src/main/js/controllers/models/metadata.json +++ b/modules/control-center-web/src/main/js/controllers/models/metadata.json @@ -76,77 +76,49 @@ ], "fields": [ { - "label": "Not indexed fields", - "id": "queryFields", + "label": "Fields", + "id": "fields", "ui": "table-pair", - "type": "queryFieldsFirst", - "model": "queryFields", + "type": "fields", + "model": "fields", "keyName": "name", "valueName": "className", "focusId": "QryField", - "addTip": "Add not indexed field to query", + "addTip": "Add field to query", "removeTip": "Remove field", "tip": [ "Collection of name-to-type mappings to be queried, in addition to indexed fields" ] }, { - "label": "Ascending indexed fields", - "id": "ascendingFields", + "label": "Aliases", + "id": "aliases", "ui": "table-pair", - "type": "queryFields", - "model": "ascendingFields", - "keyName": "name", - "valueName": "className", - "focusId": "AscField", - "addTip": "Add field to index in ascending order", - "removeTip": "Remove field", - "tip": [ - "Collection of name-to-type mappings to index in ascending order" - ] - }, - { - "label": "Descending indexed fields", - "id": "descendingFields", - "ui": "table-pair", - "type": "queryFields", - "model": "descendingFields", - "keyName": "name", - "valueName": "className", - "focusId": "DescField", - "addTip": "Add field to index in descending order", - "removeTip": "Remove field", - "tip": [ - "Collection of name-to-type mappings to index in descending order" - ] - }, - { - "label": "Text indexed fields", - "id": "textFields", - "type": "table-simple", - "model": "textFields", - "placeholder": "Field name", - "focusId": "TextField", - "addTip": "Add field to index as text", - "removeTip": "Remove field", - "tableTip": [ - "Fields to index as text" - ], + "type": "aliases", + "model": "aliases", + "keyName": "field", + "valueName": "alias", + "focusId": "Alias", + "addTip": "Add alias to query", + "removeTip": "Remove alias", "tip": [ - "Field to index as text" + "Mapping from full property name in dot notation to an alias that will be used as SQL column name", + "For example: {\"parent.name\" -> \"parentName\"}" ] }, { - "label": "Group indexes", - "id": "groups", - "type": "table-query-groups", - "model": "groups", - "addTip": "Add new group", - "removeTip": "Remove group", - "addItemTip": "Add new field to group", - "removeItemTip": "Remove field from group", + "label": "Indexes", + "id": "indexes", + "ui": "table-indexes", + "type": "indexes", + "model": "indexes", + "addTip": "Add new index", + "removeTip": "Remove index", + "addItemTip": "Add new field to index", + "removeItemTip": "Remove field from index", + "focusId": "IndexName", "tip": [ - "Collection of group indexes" + "Collection of indexes" ] } ] http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/db.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/db.js b/modules/control-center-web/src/main/js/db.js index eecc34c..ff63d3b 100644 --- a/modules/control-center-web/src/main/js/db.js +++ b/modules/control-center-web/src/main/js/db.js @@ -80,11 +80,9 @@ var CacheTypeMetadataSchema = new Schema({ valueType: String, keyFields: [{databaseName: String, databaseType: String, javaName: String, javaType: String}], valueFields: [{databaseName: String, databaseType: String, javaName: String, javaType: String}], - queryFields: [{name: String, className: String}], - ascendingFields: [{name: String, className: String}], - descendingFields: [{name: String, className: String}], - textFields: [String], - groups: [{name: String, fields: [{name: String, className: String, direction: Boolean}]}] + fields: [{name: String, className: String}], + aliases: [{field: String, alias: String}], + indexes: [{name: String, type: {type: String, enum: ['SORTED', 'FULLTEXT', 'GEOSPATIAL']}, fields: [{name: String, direction: Boolean}]}] }); // Define Cache type metadata model. http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/routes/generator/generator-java.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/routes/generator/generator-java.js b/modules/control-center-web/src/main/js/routes/generator/generator-java.js index 5ff7537..656e7b1 100644 --- a/modules/control-center-web/src/main/js/routes/generator/generator-java.js +++ b/modules/control-center-web/src/main/js/routes/generator/generator-java.js @@ -992,73 +992,82 @@ $generatorJava.cacheStatistics = function (cache, varName, res) { }; // Generate metadata query fields. -$generatorJava.metadataQueryFields = function (res, meta, fieldProperty) { - var fields = meta[fieldProperty]; +$generatorJava.metadataQueryFields = function (res, meta) { + var fields = meta.fields; if (fields && fields.length > 0) { - $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, fieldProperty), fieldProperty, 'java.util.Map', 'java.util.LinkedHashMap', 'java.lang.String', 'java.lang.Class<?>'); + $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, 'fields'), 'fields', 'java.util.LinkedHashMap', 'java.util.LinkedHashMap', 'java.lang.String', 'java.lang.String'); _.forEach(fields, function (field) { - res.line(fieldProperty + '.put("' + field.name + '", ' + res.importClass(field.className) + '.class);'); + res.line('fields.put("' + field.name + '", "' + $dataStructures.fullClassName(field.className) + '");'); }); res.needEmptyLine = true; - res.line('typeMeta.' + $commonUtils.toJavaName('set', fieldProperty) + '(' + fieldProperty + ');'); + res.line('queryMeta.setFields(fields);'); res.needEmptyLine = true; } }; -// Generate metadata groups. -$generatorJava.metadataGroups = function (res, meta) { - var groups = meta.groups; +// Generate metadata query aliases. +$generatorJava.metadataQueryAliases = function (res, meta) { + var aliases = meta.aliases; - if (groups && groups.length > 0) { - _.forEach(groups, function (group) { - var fields = group.fields; + if (aliases && aliases.length > 0) { + $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, 'aliases'), 'aliases', 'java.util.Map', 'java.util.HashMap', 'java.lang.String', 'java.lang.String'); - if (fields && fields.length > 0) { - res.importClass('java.util.Map'); - res.importClass('java.util.LinkedHashMap'); - res.importClass('org.apache.ignite.lang.IgniteBiTuple'); + _.forEach(aliases, function (alias) { + res.line('aliases.put("' + alias.field + '", "' + alias.alias + '");'); + }); - var varNew = !res.groups; + res.needEmptyLine = true; - res.needEmptyLine = true; + res.line('queryMeta.setAliases(aliases);'); - res.line((varNew ? 'Map<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> ' : '') + - "groups = new LinkedHashMap<>();"); + res.needEmptyLine = true; + } +}; - res.needEmptyLine = true; +// Generate metadata indexes. +$generatorJava.metadataQueryIndexes = function (res, meta) { + var indexes = meta.indexes; - if (varNew) - res.groups = true; + if (indexes && indexes.length > 0) { + res.needEmptyLine = true; - varNew = !res.groupItems; + $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, 'indexes'), 'indexes', 'java.util.Map', 'java.util.LinkedHashMap', 'String', 'org.apache.ignite.cache.store.QueryEntityIndex'); - res.line((varNew ? 'LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>> ' : '') + - 'groupItems = new LinkedHashMap<>();'); + _.forEach(indexes, function (index) { + res.needEmptyLine = true; - res.needEmptyLine = true; + $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, 'index'), 'index', 'org.apache.ignite.cache.store.QueryEntityIndex'); + + $generatorJava.property(res, 'index', index, 'name'); + $generatorJava.property(res, 'index', index, 'type', 'org.apache.ignite.cache.store.QueryEntityIndex.Type'); - if (varNew) - res.groupItems = true; + var fields = index.fields; + + if (fields && fields.length > 0) { + $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, 'indFlds'), 'indFlds', 'java.util.LinkedHashMap', 'java.util.LinkedHashMap', 'String', 'Boolean'); - _.forEach(fields, function (field) { - res.line('groupItems.put("' + field.name + '", ' + - 'new IgniteBiTuple<Class<?>, Boolean>(' + res.importClass(field.className) + '.class, ' + field.direction + '));'); + _.forEach(fields, function(field) { + res.line('indFlds.put("' + field.name + '", ' + field.direction + ');'); }); res.needEmptyLine = true; - res.line('groups.put("' + group.name + '", groupItems);'); + res.line('index.setFields(indFlds);'); + + res.needEmptyLine = true; } + + res.line('indexes.add(index);'); }); res.needEmptyLine = true; - res.line('typeMeta.setGroups(groups);'); + res.line('queryMeta.setIndexes(indexes);'); res.needEmptyLine = true; } @@ -1106,13 +1115,11 @@ $generatorJava.metadataQuery = function (meta, res) { if (!res) res = $generatorCommon.builder(); - $generatorJava.metadataQueryFields(res, meta, 'queryFields'); - $generatorJava.metadataQueryFields(res, meta, 'ascendingFields'); - $generatorJava.metadataQueryFields(res, meta, 'descendingFields'); + $generatorJava.metadataQueryFields(res, meta); - $generatorJava.listProperty(res, 'typeMeta', meta, 'textFields'); + $generatorJava.metadataQueryAliases(res, meta); - $generatorJava.metadataGroups(res, meta); + $generatorJava.metadataQueryIndexes(res, meta); res.needEmptyLine = true; @@ -1142,7 +1149,6 @@ $generatorJava.cacheMetadata = function(meta, res) { $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, 'typeMeta'), 'typeMeta', 'org.apache.ignite.cache.CacheTypeMetadata'); $generatorJava.metadataGeneral(meta, res); - $generatorJava.metadataQuery(meta, res); $generatorJava.metadataStore(meta, res); res.emptyLineIfNeeded(); @@ -1151,6 +1157,23 @@ $generatorJava.cacheMetadata = function(meta, res) { res.needEmptyLine = true; }; +// Generate cache type metadata config. +$generatorJava.cacheQueryMetadata = function(meta, res) { + $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, 'queryMeta'), 'queryMeta', 'org.apache.ignite.cache.store.QueryEntity'); + + $generatorJava.classNameProperty(res, 'queryMeta', meta, 'keyType'); + $generatorJava.classNameProperty(res, 'queryMeta', meta, 'valueType'); + + res.needEmptyLine = true; + + $generatorJava.metadataQuery(meta, res); + + res.emptyLineIfNeeded(); + res.line('queryEntities.add(queryMeta);'); + + res.needEmptyLine = true; +}; + // Generate cache type metadata configs. $generatorJava.cacheMetadatas = function (metadatas, varName, res) { if (!res) @@ -1167,6 +1190,16 @@ $generatorJava.cacheMetadatas = function (metadatas, varName, res) { res.line(varName + '.setTypeMetadata(types);'); res.needEmptyLine = true; + + $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, 'queryEntities'), 'queryEntities', 'java.util.Collection', 'java.util.ArrayList', 'org.apache.ignite.cache.store.QueryEntity'); + + _.forEach(metadatas, function (meta) { + $generatorJava.cacheQueryMetadata(meta, res); + }); + + res.line(varName + '.setQueryEntities(queryEntities);'); + + res.needEmptyLine = true; } return res; http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/routes/generator/generator-xml.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/routes/generator/generator-xml.js b/modules/control-center-web/src/main/js/routes/generator/generator-xml.js index 127e551..7c39150 100644 --- a/modules/control-center-web/src/main/js/routes/generator/generator-xml.js +++ b/modules/control-center-web/src/main/js/routes/generator/generator-xml.js @@ -846,13 +846,13 @@ $generatorXml.cacheStatistics = function(cache, res) { }; // Generate metadata query fields. -$generatorXml.metadataQueryFields = function (res, meta, fieldProp) { - var fields = meta[fieldProp]; +$generatorXml.metadataQueryFields = function (res, meta) { + var fields = meta.fields; if (fields && fields.length > 0) { res.emptyLineIfNeeded(); - res.startBlock('<property name="' + fieldProp + '">'); + res.startBlock('<property name="fields">'); res.startBlock('<map>'); _.forEach(fields, function (field) { @@ -866,40 +866,61 @@ $generatorXml.metadataQueryFields = function (res, meta, fieldProp) { } }; -// Generate metadata groups. -$generatorXml.metadataGroups = function (res, meta) { - var groups = meta.groups; +// Generate metadata query fields. +$generatorXml.metadataQueryAliases = function (res, meta) { + var aliases = meta.aliases; - if (groups && groups.length > 0) { + if (aliases && aliases.length > 0) { res.emptyLineIfNeeded(); - res.startBlock('<property name="groups">'); + res.startBlock('<property name="aliases">'); res.startBlock('<map>'); - _.forEach(groups, function (group) { - var fields = group.fields; + _.forEach(aliases, function (alias) { + $generatorXml.element(res, 'entry', 'key', alias.field, 'value', alias.alias); + }); + + res.endBlock('</map>'); + res.endBlock('</property>'); + + res.needEmptyLine = true; + } +}; + +// Generate metadata indexes. +$generatorXml.metadataQueryIndexes = function (res, meta) { + var indexes = meta.indexes; + + if (indexes && indexes.length > 0) { + res.emptyLineIfNeeded(); + + res.startBlock('<property name="indexes">'); + res.startBlock('<list>'); + + _.forEach(indexes, function (index) { + res.startBlock('<bean class="org.apache.ignite.cache.store.QueryEntityIndex">'); + + $generatorXml.property(res, index, 'name'); + $generatorXml.property(res, index, 'type'); + + var fields = index.fields; if (fields && fields.length > 0) { - res.startBlock('<entry key="' + group.name + '">'); + res.startBlock('<property name="fields">'); res.startBlock('<map>'); _.forEach(fields, function (field) { - res.startBlock('<entry key="' + field.name.toUpperCase() + '">'); - - res.startBlock('<bean class="org.apache.ignite.lang.IgniteBiTuple">'); - res.line('<constructor-arg value="' + $dataStructures.fullClassName(field.className) + '"/>'); - res.line('<constructor-arg value="' + field.direction + '"/>'); - res.endBlock('</bean>'); - - res.endBlock('</entry>'); + $generatorXml.element(res, 'entry', 'key', field.name, 'value', field.direction); }); res.endBlock('</map>'); - res.endBlock('</entry>'); + res.endBlock('</property>'); } + + res.endBlock('</bean>'); }); - res.endBlock('</map>'); + res.endBlock('</list>'); res.endBlock('</property>'); res.needEmptyLine = true; @@ -958,13 +979,11 @@ $generatorXml.metadataQuery = function(meta, res) { if (!res) res = $generatorCommon.builder(); - $generatorXml.metadataQueryFields(res, meta, 'queryFields'); - $generatorXml.metadataQueryFields(res, meta, 'ascendingFields'); - $generatorXml.metadataQueryFields(res, meta, 'descendingFields'); + $generatorXml.metadataQueryFields(res, meta); - $generatorXml.listProperty(res, meta, 'textFields'); + $generatorXml.metadataQueryAliases(res, meta); - $generatorXml.metadataGroups(res, meta); + $generatorXml.metadataQueryIndexes(res, meta); res.needEmptyLine = true; @@ -1001,7 +1020,6 @@ $generatorXml.cacheMetadata = function(meta, res) { res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeMetadata">'); $generatorXml.metadataGeneral(meta, res); - $generatorXml.metadataQuery(meta, res); $generatorXml.metadataStore(meta, res); res.endBlock('</bean>'); @@ -1011,6 +1029,24 @@ $generatorXml.cacheMetadata = function(meta, res) { return res; }; +$generatorXml.cacheQueryMetadata = function(meta, res) { + if (!res) + res = $generatorCommon.builder(); + + res.startBlock('<bean class="org.apache.ignite.cache.store.QueryEntity">'); + + $generatorXml.classNameProperty(res, meta, 'keyType'); + $generatorXml.property(res, meta, 'valueType'); + + $generatorXml.metadataQuery(meta, res); + + res.endBlock('</bean>'); + + res.needEmptyLine = true; + + return res; +}; + // Generate cache type metadata configs. $generatorXml.cacheMetadatas = function(metadatas, res) { if (!res) @@ -1030,6 +1066,16 @@ $generatorXml.cacheMetadatas = function(metadatas, res) { res.endBlock('</property>'); res.needEmptyLine = true; + + res.startBlock('<property name="queryEntities">'); + res.startBlock('<list>'); + + _.forEach(metadatas, function (meta) { + $generatorXml.cacheQueryMetadata(meta, res); + }); + + res.endBlock('</list>'); + res.endBlock('</property>'); } return res; http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/views/includes/controls.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/includes/controls.jade b/modules/control-center-web/src/main/js/views/includes/controls.jade index 68fdd7a..9c7af9b 100644 --- a/modules/control-center-web/src/main/js/views/includes/controls.jade +++ b/modules/control-center-web/src/main/js/views/includes/controls.jade @@ -277,34 +277,32 @@ mixin table-db-field-edit(prefix, focusId, index) .input-tip button.form-control(id=javaTypeId ng-model=javaTypeModel data-placeholder='Java type' ng-class='{placeholder: !#{javaTypeModel}}' bs-select bs-options='item.value as item.label for item in {{supportedJavaTypes}}' on-enter=btnVisibleAndSave on-escape='tableReset()' tabindex='0') -mixin table-group-item-edit(prefix, index) +mixin table-index-item-edit(prefix, index, sortAvailable) -var fieldName = prefix + 'FieldName' - -var className = prefix + 'ClassName' -var direction = prefix + 'Direction' -var fieldNameModel = 'field.' + fieldName - -var classNameModel = 'field.' + className -var directionModel = 'field.' + direction - -var btnVisible = 'tableGroupItemSaveVisible(field, ' + index + ')' - -var btnSave = 'tableGroupItemSave(field, groupIndex, ' + index + ')' + -var btnVisible = 'tableIndexItemSaveVisible(field, ' + index + ')' + -var btnSave = 'tableIndexItemSave(field, itemIndex, ' + index + ')' -var btnVisibleAndSave = btnVisible + ' && ' + btnSave - .col-xs-4.col-sm-4.col-md-4 + .col-xs-8.col-sm-8.col-md-8(ng-show=sortAvailable) label.placeholder Field name label.fieldSep / .input-tip - input.form-control(id=fieldName enter-focus-next=className type='text' ng-model=fieldNameModel placeholder='Field name' on-escape='tableReset()') - .col-xs-5.col-sm-5.col-md-5 - label.placeholder Class name - label.fieldSep / - .input-tip - input.form-control(id=className enter-focus-next=direction type='text' ng-model=classNameModel placeholder='Class name' bs-typeahead container='body' retain-selection data-min-length='1' bs-options='javaClass for javaClass in javaBuildInClasses' on-escape='tableReset()') - .col-xs-3.col-sm-3.col-md-3 + input.form-control(id=fieldName enter-focus-next=direction type='text' ng-model=fieldNameModel placeholder='Field name' on-escape='tableReset()') + .col-xs-4.col-sm-4.col-md-4(ng-show=sortAvailable) label.placeholder Sort order +btn-save(btnVisible, btnSave) .input-tip button.form-control(id=direction ng-model=directionModel bs-select bs-options='item.value as item.label for item in {{sortDirections}}' on-enter=btnVisibleAndSave on-escape='tableReset()' tabindex='0') + .col-xs-12(ng-show='!(#{sortAvailable})') + label.placeholder Field name + +btn-save(btnVisible, btnSave) + .input-tip + input.form-control(id=fieldName enter-focus-next=direction type='text' ng-model=fieldNameModel placeholder='Field name' on-escape='tableReset()') mixin form-row(dataSource) +form-row-custom(['col-xs-4 col-sm-4 col-md-4'], ['col-xs-8 col-sm-8 col-md-8'], dataSource) @@ -417,10 +415,10 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource) input.form-control(id='new{{::field.focusId}}' type='text' ng-model='field.newValue' placeholder='{{::field.placeholder}}' on-enter='tableSimpleSaveVisible(field, -1) && tableSimpleSave(tableSimpleValid, backupItem, field, -1)' on-escape='tableReset()') .group-section(ng-switch-when='indexedTypes') +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 'valueClass', 'Key full class name', 'Value class full name', true, true) - div(ng-switch-when='queryFieldsFirst' ng-hide=fieldHide) - +table-pair('{{::field.label}}', fieldMdl, 'name', 'className', 'Field name', 'Field full class name', false, true) - .group-section(ng-switch-when='queryFields' ng-hide=fieldHide) + div(ng-switch-when='fields' ng-hide=fieldHide) +table-pair('{{::field.label}}', fieldMdl, 'name', 'className', 'Field name', 'Field full class name', false, true) + .group-section(ng-switch-when='aliases' ng-hide=fieldHide) + +table-pair('{{::field.label}}', fieldMdl, 'field', 'alias', 'Field name', 'Field Alias', false, false) .group-section(ng-switch-when='pathModes' ng-hide=fieldHide) +table-igfs-path-mode('{{::field.label}}', fieldMdl, 'path', 'mode', 'Path', 'Mode') .group-section(ng-switch-when='table-db-fields' ng-hide=fieldHide) @@ -444,7 +442,7 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource) tr td +table-db-field-edit('new', '{{::field.focusId}}', '-1') - .group-section(ng-switch-when='table-query-groups' ng-hide=fieldHide) + .group-section(ng-switch-when='indexes' ng-hide=fieldHide) .col-sm-12.group .group-legend label {{::field.label}} @@ -452,40 +450,55 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource) +group-btn-add('tableNewItem(field)', 'field.addTip') .group-content-empty(id='{{::field.id + "-add"}}' ng-show='!((#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field))') Not defined .group-content(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)') + -var btnVisibleAndSave = 'tableIndexSaveVisible(field, $index) && tableIndexSave(field, $index)' + table.links-edit(st-table=fieldMdl ng-init='newDirection = false') tbody - tr(ng-repeat='group in #{fieldMdl}') + tr(ng-repeat='item in #{fieldMdl}') td .col-sm-12(ng-show='!tableEditing(field, $index)') - a.labelFormField(id='{{field.id + $index}}' ng-click='tableStartEdit(backupItem, field, $index)') {{$index + 1}}) {{group.name}} + a.labelFormField(id='{{field.id + $index}}' ng-click='tableStartEdit(backupItem, field, $index)') {{$index + 1}}) {{item.name}} [{{item.type}}] +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip') - +btn-add('tableGroupNewItem(field, $index)', 'field.addItemTip') - div(ng-if='tableEditing(field, $index)') - label.labelField {{$index + 1}}) - +btn-save('tableGroupSaveVisible(field, $index)', 'tableGroupSave(field, $index)') - .input-tip - input#curGroupName.form-control(type='text' ng-model='field.curGroupName' placeholder='Index name' on-enter='tableGroupSaveVisible(field, $index) && tableGroupSave(field, $index)' on-escape='tableReset()') + +btn-add('tableIndexNewItem(field, $index)', 'field.addItemTip') + div(ng-show='tableEditing(field, $index)') + .col-sm-7 + label.placeholder Index name + label.fieldSep / + .input-tip + input#curIndexName.form-control(type='text' enter-focus-next="curIndexType" ng-model='field.curIndexName' placeholder='Index name' on-enter=btnVisibleAndSave on-escape='tableReset()') + .col-sm-5 + label.placeholder Index type + +btn-save('tableIndexSaveVisible(field, $index)', 'tableIndexSave(field, $index)') + .input-tip + button#curIndexType.form-control(bs-select ng-model='field.curIndexType' data-placeholder='Select index type' bs-options="item.value as item.label for item in indexType" tabindex='0' on-enter=btnVisibleAndSave on-escape='tableReset()') .margin-left-dflt - table.links-edit-sub(st-table='group.fields' ng-init='groupIndex = $index') + table.links-edit-sub(st-table='item.fields' ng-init='itemIndex = $index') tbody - tr(ng-repeat='groupItem in group.fields') + tr(ng-repeat='itemItem in item.fields') td - div(ng-show='!tableGroupItemEditing(groupIndex, $index)') - a.labelFormField(ng-click='tableGroupItemStartEdit(field, groupIndex, $index)') {{$index + 1}}) {{groupItem.name}} / {{groupItem.className}} / {{groupItem.direction ? "DESC" : "ASC"}} - +btn-remove('tableRemoveGroupItem(group, $index)', 'field.removeItemTip') - div(ng-if='tableGroupItemEditing(groupIndex, $index)') - +table-group-item-edit('cur', '$index') - tfoot(ng-if='tableGroupNewItemActive(groupIndex)') + div(ng-show='!tableIndexItemEditing(itemIndex, $index)') + a.labelFormField(ng-if='item.type == "SORTED"' ng-click='tableIndexItemStartEdit(field, itemIndex, $index)') {{$index + 1}}) {{itemItem.name}} / {{itemItem.direction ? "ASC" : "DESC"}} + a.labelFormField(ng-if='item.type != "SORTED"' ng-click='tableIndexItemStartEdit(field, itemIndex, $index)') {{$index + 1}}) {{itemItem.name}} + +btn-remove('tableRemoveIndexItem(item, $index)', 'field.removeItemTip') + div(ng-show='tableIndexItemEditing(itemIndex, $index)') + +table-index-item-edit('cur', '$index', '{{item.type == "SORTED"}}') + tfoot(ng-show='tableIndexNewItemActive(itemIndex)') tr(style='padding-left: 18px') td - +table-group-item-edit('new', '-1') + +table-index-item-edit('new', '-1', '{{item.type == "SORTED"}}') tfoot(ng-show='tableNewItemActive(field)') tr td - label.placeholder Group name - +btn-save('tableGroupSaveVisible(field, -1)', 'tableGroupSave(field, -1)') - .input-tip - input#newGroupName.form-control(type='text' ng-model='field.newGroupName' placeholder='Group name' on-enter='tableGroupSaveVisible(field, -1) && tableGroupSave(field, -1)' on-escape='tableReset()') + .col-sm-7 + label.placeholder Index name + label.fieldSep / + .input-tip + input#newIndexName.form-control(type='text' enter-focus-next="newIndexType" ng-model='field.newIndexName' placeholder='Index name' on-enter='tableIndexSaveVisible(field, -1) && tableIndexSave(field, -1)' on-escape='tableReset()') + .col-sm-5 + label.placeholder Index type + +btn-save('tableIndexSaveVisible(field, -1)', 'tableIndexSave(field, -1)') + .input-tip + button#newIndexType.form-control(bs-select ng-model='field.newIndexType' data-placeholder='Select index type' bs-options="item.value as item.label for item in indexType" tabindex='0' on-enter=btnVisibleAndSave on-escape='tableReset()') mixin main-table(title, rows, focusId, click, rowTemplate) .padding-bottom-dflt(ng-show='#{rows} && #{rows}.length > 0')
