@@ -301,41 +301,47 @@ function smartCommentConstraints(introspectionResults) {
301301 } ) ;
302302 } ;
303303
304- // First: primary keys
304+ // First: primary and unique keys
305305 introspectionResults . class . forEach ( klass => {
306306 const namespace = introspectionResults . namespace . find (
307307 n => n . id === klass . namespaceId
308308 ) ;
309309 if ( ! namespace ) {
310310 return ;
311311 }
312- if ( klass . tags . primaryKey ) {
313- if ( typeof klass . tags . primaryKey !== "string" ) {
312+ function addKey ( key : string , isPrimary = false ) {
313+ const tag = isPrimary ? "@primaryKey" : "@unique" ;
314+ if ( typeof key !== "string" ) {
315+ if ( isPrimary ) {
316+ throw new Error (
317+ `${ tag } configuration of '${ klass . namespaceName } .${ klass . name } ' is invalid; please specify just once "${ tag } col1,col2"`
318+ ) ;
319+ }
314320 throw new Error (
315- `@primaryKey configuration of '${ klass . namespaceName } .${ klass . name } ' is invalid; please specify just once "@primaryKey col1,col2"`
321+ `${ tag } configuration of '${ klass . namespaceName } .${
322+ klass . name
323+ } ' is invalid; expected ${
324+ isPrimary ? "a string" : "a string or string array"
325+ } but found ${ typeof key } `
316326 ) ;
317327 }
318- const { spec : pkSpec , tags, description } = parseConstraintSpec (
319- klass . tags . primaryKey
320- ) ;
321- const columns : string [ ] = parseSqlColumnArray ( pkSpec ) ;
322- const attributes = attributesByNames (
323- klass ,
324- columns ,
325- `@primaryKey ${ klass . tags . primaryKey } `
326- ) ;
327- attributes . forEach ( attr => {
328- attr . tags . notNull = true ;
329- } ) ;
328+ const { spec : keySpec , tags, description } = parseConstraintSpec ( key ) ;
329+ const columns : string [ ] = parseSqlColumnArray ( keySpec ) ;
330+ const attributes = attributesByNames ( klass , columns , `${ tag } ${ key } ` ) ;
331+ if ( isPrimary ) {
332+ attributes . forEach ( attr => {
333+ attr . tags . notNull = true ;
334+ } ) ;
335+ }
330336 const keyAttributeNums = attributes . map ( a => a . num ) ;
331337 // Now we need to fake a constraint for this:
332338 const fakeConstraint = {
333339 kind : "constraint" ,
334340 isFake : true ,
335341 isIndexed : true , // otherwise it gets ignored by ignoreIndexes
336342 id : Math . random ( ) ,
337- name : `FAKE_${ klass . namespaceName } _${ klass . name } _primaryKey ` ,
338- type : "p" , // primary key
343+ name : `FAKE_${ klass . namespaceName } _${ klass . name } _ ${ tag } ` ,
344+ type : isPrimary ? "p" : "u" ,
339345 classId : klass . id ,
340346 foreignClassId : null ,
341347 comment : null ,
@@ -346,6 +352,16 @@ function smartCommentConstraints(introspectionResults) {
346352 } ;
347353 introspectionResults . constraint . push ( fakeConstraint ) ;
348354 }
355+ if ( klass . tags . primaryKey ) {
356+ addKey ( klass . tags . primaryKey , true ) ;
357+ }
358+ if ( klass . tags . unique ) {
359+ if ( Array . isArray ( klass . tags . unique ) ) {
360+ klass . tags . unique . forEach ( key => addKey ( key , true ) ) ;
361+ } else {
362+ addKey ( klass . tags . unique ) ;
363+ }
364+ }
349365 } ) ;
350366 // Now primary keys are in place, we can apply foreign keys
351367 introspectionResults . class . forEach ( klass => {
0 commit comments