Skip to content

Commit

Permalink
Merge branch 'master' into ci/validateMD
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanFreestone authored Sep 18, 2024
2 parents 0a11ad0 + 28d8d4c commit eb5a1f7
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 53 deletions.
9 changes: 8 additions & 1 deletion service/grails-app/domain/org/olf/erm/Entitlement.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import java.time.LocalDate
import javax.persistence.Transient

import org.hibernate.Hibernate

import org.olf.general.DocumentAttachment

import org.olf.kb.ErmResource
import org.olf.kb.PackageContentItem
import org.olf.kb.Pkg
Expand All @@ -30,7 +33,8 @@ import groovy.util.logging.Slf4j
public class Entitlement implements MultiTenant<Entitlement>, Clonable<Entitlement> {
public static final Class<? extends ErmResource>[] ALLOWED_RESOURCES = [Pkg, PackageContentItem, PlatformTitleInstance] as Class[]


static copyByCloning = ['docs'];

/**
* Need to resolve the conflict manually and add the call to the clonable method here.
*/
Expand Down Expand Up @@ -286,6 +290,7 @@ public class Entitlement implements MultiTenant<Entitlement>, Clonable<Entitleme
coverage: HoldingsCoverage,
poLines: OrderLine,
tags: Tag,
docs: DocumentAttachment
]

Set<HoldingsCoverage> coverage = []
Expand Down Expand Up @@ -340,13 +345,15 @@ suppressFromDiscovery column: 'ent_suppress_discovery'
poLines cascade: 'all-delete-orphan'
coverage cascade: 'all-delete-orphan'
tags cascade: 'save-update'
docs cascade: 'all-delete-orphan', joinTable: [name: 'entitlement_document_attachment', key: 'entitlement_docs_id', column: 'document_attachment_id']
}

static constraints = {
owner(nullable:true, blank:false)
dateCreated(nullable:true, blank: true)
lastUpdated(nullable:true, blank: true)


// Now that resources can be internally or externally defined, the internal resource link CAN be null,
// but if it is, there should be authorty, and reference properties.
resource (nullable:true, validator: { val, inst ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ databaseChangeLog = {
include file: 'correct-gin-indices-pre-quesnalia.groovy'
include file: 'add-quesnalia-indices-and-fk-constraints.groovy'
include file: 'update-mod-agreements-6-1.groovy'
include file: 'update-mod-agreements-7-1.groovy'
}
35 changes: 35 additions & 0 deletions service/grails-app/migrations/update-mod-agreements-7-1.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
databaseChangeLog = {

changeSet(author: "efreestone (manual)", id: "202409161452-001") {
createTable(tableName: "entitlement_document_attachment") {
column(name: "entitlement_docs_id", type: "VARCHAR(36)") {
constraints(nullable: "false")
}
column(name: "document_attachment_id", type: "VARCHAR(36)")
}
}

changeSet(author: "efreestone (manual)", id: "202409161452-004") {
addForeignKeyConstraint(
baseColumnNames: "entitlement_docs_id",
baseTableName: "entitlement_document_attachment",
constraintName: "entitlement_docs_entitlement_docs_id_fk",
deferrable: "false",
initiallyDeferred: "false",
referencedColumnNames: "ent_id",
referencedTableName: "entitlement"
)
}

changeSet(author: "efreestone (manual)", id: "202409161452-005") {
addForeignKeyConstraint(
baseColumnNames: "document_attachment_id",
baseTableName: "entitlement_document_attachment",
constraintName: "entitlement_docs_document_attachment_id_fk",
deferrable: "false",
initiallyDeferred: "false",
referencedColumnNames: "da_id",
referencedTableName: "document_attachment"
)
}
}
111 changes: 60 additions & 51 deletions service/grails-app/services/org/olf/DocumentAttachmentService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -129,64 +129,73 @@ public class DocumentAttachmentService {
}

@Transactional
private void triggerCleanSuppDocs() {

['supplementaryDocs', 'docs', 'externalLicenseDocs'].each { final String prop ->

String tName, saCol, daCol
private triggerCleanDocsByClassAndProp(String domainClass, String prop) {
String tName, saCol, daCol

// SO: Gorm creates in-flight metadata based on our classes to create hibernate domain objects.
// We should be able to get the metadata from the session. We use hibernate directly here...
// I'm not overly pleased with this but it beats hard-coding table and column names for
// references properties.
DocumentAttachment.withSession { Session sess ->
MetamodelImplementor hibMM = sess.getSessionFactory().metamodel
EntityPersister ep = hibMM.locateEntityPersister(SubscriptionAgreement)
AttributeDefinition ad = ep.getAttributes().find { AttributeDefinition theDef ->
theDef.name == prop
}

tName = ad?.getAt('joinable')?.getAt('qualifiedTableName')

String[] cols = ad?.getAt('joinable')?.getAt('elementColumnNames')
(cols?.length ?: 0) > 0 && (daCol = cols[0])

cols = ad?.getAt('joinable')?.getAt('keyColumnNames')
(cols?.length ?: 0) > 0 && (saCol = cols[0])
// SO: Gorm creates in-flight metadata based on our classes to create hibernate domain objects.
// We should be able to get the metadata from the session. We use hibernate directly here...
// I'm not overly pleased with this but it beats hard-coding table and column names for
// references properties.
DocumentAttachment.withSession { Session sess ->
MetamodelImplementor hibMM = sess.getSessionFactory().metamodel
EntityPersister ep = hibMM.locateEntityPersister(SubscriptionAgreement)
AttributeDefinition ad = ep.getAttributes().find { AttributeDefinition theDef ->
theDef.name == prop
}

if (tName && saCol && daCol) {

log.debug "Using relational join table ${tName} with columns ${saCol} and ${daCol}"

final Map<String, List<String>> dupeMapping = [:]
SubscriptionAgreement.executeQuery(

"""
SELECT da.id, sa.id FROM SubscriptionAgreement AS sa INNER JOIN sa.${prop} AS da
WHERE da.id IN (
SELECT da.id FROM SubscriptionAgreement AS sa INNER JOIN sa.${prop} AS da GROUP BY da.id HAVING COUNT(*) > 1
)
ORDER BY da.id, sa.id
""".toString()

).each { final Object[] resultsArr ->
final String[] tuple = resultsArr as String[]
if (!dupeMapping.containsKey(tuple[0])) {
// add List
dupeMapping[tuple[0]] = []
}
dupeMapping[tuple[0]] << tuple[1]
}
tName = ad?.getAt('joinable')?.getAt('qualifiedTableName')

String[] cols = ad?.getAt('joinable')?.getAt('elementColumnNames')
(cols?.length ?: 0) > 0 && (daCol = cols[0])

cols = ad?.getAt('joinable')?.getAt('keyColumnNames')
(cols?.length ?: 0) > 0 && (acCol = cols[0])
}

log.debug "dupeMapping = ${dupeMapping}"
if (tName && acCol && daCol) {

log.debug "Using relational join table ${tName} with columns ${acCol} and ${daCol}"

final Map<String, List<String>> dupeMapping = [:]
DocumentAttachment.executeQuery(
"""
SELECT da.id, ac.id FROM ${domainClass} AS ac INNER JOIN sa.${prop} AS da
WHERE da.id IN (
SELECT da.id FROM ${domainClass} AS ac INNER JOIN ac.${prop} AS da GROUP BY da.id HAVING COUNT(*) > 1
)
ORDER BY da.id, ac.id
""".toString()

dupeMapping.each { final String docId, final List<String> saIds ->
splitDocuments(docId, saIds, prop, tName, saCol, daCol)
).each { final Object[] resultsArr ->
final String[] tuple = resultsArr as String[]
if (!dupeMapping.containsKey(tuple[0])) {
// add List
dupeMapping[tuple[0]] = []
}
} else {
log.debug "Could not get join table for property ${prop}"
dupeMapping[tuple[0]] << tuple[1]
}

log.debug "dupeMapping = ${dupeMapping}"

dupeMapping.each { final String docId, final List<String> saIds ->
splitDocuments(docId, saIds, prop, tName, acCol, daCol)
}
} else {
log.debug "Could not get join table for property ${prop} on domain class ${domainClass}"
}
}

// Does this even actually get called?
private void triggerCleanSuppDocs() {
// On Agreements
['supplementaryDocs', 'docs', 'externalLicenseDocs'].each { final String prop ->
triggerCleanDocsByClassAndProp('SubscriptionAgreement', prop)
}

// On Entitlements
['docs'].each { final String prop ->
triggerCleanDocsByClassAndProp('Entitlement', prop)
}

}
}
2 changes: 1 addition & 1 deletion service/grails-app/views/entitlement/_entitlement.gson
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def should_render_default_coverage = false
if (entitlement.type == 'external') {
json tmpl."externalEntitlement"(entitlement)
} else {
final def should_expand = ['poLines', 'resource', 'tags' ]
final def should_expand = ['poLines', 'resource', 'tags', 'docs' ]

// Anything handled specifically below should always be excluded from the the general render
final def should_exclude = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ json {
'haveAccess' entitlement.getHaveAccess()
'suppressFromDiscovery' entitlement.suppressFromDiscovery
'note' entitlement.note
'docs' g.render(entitlement.docs)

if (renderOwnerSnippet) {
'owner' g.render(entitlement.owner, [includes: ['id', 'name']])
Expand Down

0 comments on commit eb5a1f7

Please sign in to comment.