@@ -1316,6 +1316,40 @@ DataSource.prototype.discoverPrimaryKeys = function(modelName, options, cb) {
13161316 return cb . promise ;
13171317} ;
13181318
1319+ /**
1320+ * Discover unique keys for a given modelName.
1321+ * Callback function return value is an object that can have the following properties:
1322+ *
1323+ *| Key | Type | Description |
1324+ *|-----|------|-------------|
1325+ *| owner |String | Table schema or owner (may be null). Owner defaults to current user.
1326+ *| tableName |String| Table name
1327+ *| columnName |String| Column name
1328+ * See [ID Properties](./Model-definition-JSON-file.html#id-properties) for more
1329+ * information.
1330+ * @param {String } modelName The model name
1331+ * @options {Object} options The options
1332+ * @param {Function } [cb] The callback function
1333+ * @returns {Promise } A promise with an array of Primary Keys (Property[])
1334+ */
1335+ DataSource . prototype . discoverUniqueKeys = function ( modelName , options , cb ) {
1336+ this . freeze ( ) ;
1337+
1338+ if ( cb === undefined && typeof options === 'function' ) {
1339+ cb = options ;
1340+ options = { } ;
1341+ }
1342+ options = options || { } ;
1343+ cb = cb || utils . createPromiseCallback ( ) ;
1344+
1345+ if ( this . connector . discoverUniqueKeys ) {
1346+ this . connector . discoverUniqueKeys ( modelName , options , cb ) ;
1347+ } else if ( cb ) {
1348+ process . nextTick ( cb ) ;
1349+ }
1350+ return cb . promise ;
1351+ } ;
1352+
13191353/*! Method will be completely removed in LoopBack.next
13201354*/
13211355/**
@@ -1627,7 +1661,8 @@ DataSource.prototype.discoverSchemas = function(tableName, options, cb) {
16271661
16281662 const tasks = [
16291663 this . discoverModelProperties . bind ( this , tableName , options ) ,
1630- this . discoverPrimaryKeys . bind ( this , tableName , options ) ] ;
1664+ this . discoverPrimaryKeys . bind ( this , tableName , options ) ,
1665+ this . discoverUniqueKeys . bind ( this , tableName , options ) ] ;
16311666
16321667 const followingRelations = options . associations || options . relations ;
16331668 if ( followingRelations ) {
@@ -1641,6 +1676,14 @@ DataSource.prototype.discoverSchemas = function(tableName, options, cb) {
16411676 }
16421677
16431678 const columns = results [ 0 ] ;
1679+ const uniqueKeyArray = results [ 2 ] || [ ] ;
1680+
1681+ let uniqueKeys = [ ] ;
1682+
1683+ uniqueKeyArray . forEach ( key => {
1684+ uniqueKeys . push ( key [ 'columnName' ] ) ;
1685+ } ) ;
1686+
16441687 if ( ! columns || columns . length === 0 ) {
16451688 cb ( new Error ( g . f ( 'Table \'%s\' does not exist.' , tableName ) ) ) ;
16461689 return cb . promise ;
@@ -1657,6 +1700,7 @@ DataSource.prototype.discoverSchemas = function(tableName, options, cb) {
16571700 debug ( 'Primary keys: ' , pks ) ;
16581701 }
16591702
1703+ uniqueKeys = uniqueKeys . filter ( item => ! pks . hasOwnProperty ( item ) ) ;
16601704 const schema = {
16611705 name : nameMapper ( 'table' , tableName ) ,
16621706 options : {
@@ -1686,6 +1730,9 @@ DataSource.prototype.discoverSchemas = function(tableName, options, cb) {
16861730 if ( pks [ item . columnName ] ) {
16871731 schema . properties [ propName ] . id = pks [ item . columnName ] ;
16881732 }
1733+ if ( uniqueKeys . includes ( propName ) ) {
1734+ schema . properties [ propName ] [ 'index' ] = { unique : true } ;
1735+ }
16891736 const dbSpecific = schema . properties [ propName ] [ dbType ] = {
16901737 columnName : item . columnName ,
16911738 dataType : item . dataType ,
0 commit comments