Commit aabded03 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Add value for handlepid field on publish to coe repository #133.

parent 4d821dd8
Pipeline #47792 passed with stages
in 16 minutes and 52 seconds
......@@ -41,11 +41,12 @@ To load an entity from the database use :data:`nomad.infrastructure.repository_d
.. autoclass:: Calc
:members:
:undoc-members:
.. autofunction:: create_handle
.. autoclass:: DataSet
:members:
:undoc-members:
"""
from .user import User, ensure_test_user, admin_user, LoginException
from .calc import Calc, DataSet
from .calc import Calc, DataSet, create_handle
from .upload import UploadMetaData, Upload
......@@ -19,7 +19,7 @@ from sqlalchemy.orm import relationship, aliased
from sqlalchemy.sql.expression import literal
from datetime import datetime
from nomad import infrastructure, utils
from nomad import infrastructure, utils, config
from nomad.datamodel import DFTCalcWithMetadata
from . import base
......@@ -29,6 +29,25 @@ from .base import Base, calc_citation_association, ownership, co_authorship, sha
CodeVersion, StructRatio, UserMetaData
handle_base = '0123456789abcdefghijklmnopqrstuvwxyz'
def create_handle(pid: int) -> str:
"""
Create a handle for the given pid. The pid is an autoincrement number. The handle
a 'base32' encoded string of that number. Therefore, its string representation is a
little shorter. The handle is prefixed with the configured handle prefix.
"""
value = pid
result = ''
while value > 0:
result += handle_base[value & 31]
value = value >> 5
return config.repository_db.handle_prefix + result[::-1]
class PublishContext:
"""
Utilities necessary during adding calculations to the repo db.
......@@ -58,6 +77,7 @@ class Calc(Base):
__tablename__ = 'calculations'
coe_calc_id = Column('calc_id', Integer, primary_key=True, autoincrement=True)
handlepid = Column(String)
origin_id = Column(Integer, ForeignKey('uploads.upload_id'))
upload = relationship('Upload', lazy='joined')
checksum = Column(String)
......
......@@ -54,7 +54,7 @@ from sqlalchemy import exc as sa_exc
from nomad import utils, infrastructure, config
from nomad.datamodel import UploadWithMetadata, DFTCalcWithMetadata
from .calc import Calc, PublishContext
from .calc import Calc, PublishContext, create_handle
from .base import Base
from .user import User
......@@ -186,6 +186,7 @@ class Upload(Base): # type: ignore
# reuse the cache for the whole transaction to profit from repeating
# star schema entries for users, ds, topics, etc.
context = PublishContext(upload_id=upload.upload_id)
coe_calcs = []
for calc in upload.calcs:
has_calcs = True
coe_calc = Calc(
......@@ -193,6 +194,7 @@ class Upload(Base): # type: ignore
checksum=calc.calc_id,
upload=coe_upload)
repo_db.add(coe_calc)
coe_calcs.append(coe_calc)
coe_calc.apply_calc_with_metadata(
cast(DFTCalcWithMetadata, calc), context=context)
......@@ -203,6 +205,11 @@ class Upload(Base): # type: ignore
result = None
if has_calcs:
repo_db.flush()
for coe_calc in coe_calcs:
coe_calc.handlepid = create_handle(coe_calc.coe_calc_id)
logger.debug('created all handlepids')
repo_db.commit()
logger.info('committed publish transaction')
result = coe_upload
......
......@@ -97,7 +97,8 @@ repository_db = NomadConfig(
port=5432,
dbname='nomad_fairdi_repo_db',
user='postgres',
password='nomad'
password='nomad',
handle_prefix='21.11132/'
)
mongo = NomadConfig(
......
......@@ -17,7 +17,7 @@ from typing import cast
from passlib.hash import bcrypt
from datetime import datetime
from nomad.coe_repo import User, Calc, Upload
from nomad.coe_repo import User, Calc, Upload, create_handle
from nomad.coe_repo.calc import PublishContext
from nomad import processing, parsing, datamodel
......@@ -65,15 +65,18 @@ def assert_coe_upload(upload_id: str, upload: datamodel.UploadWithMetadata = Non
if user_metadata is not None:
calc.apply_user_metadata(user_metadata)
assert_coe_calc(coe_calc, cast(datamodel.DFTCalcWithMetadata, calc))
assert_coe_calc(coe_calc, cast(datamodel.DFTCalcWithMetadata, calc), has_handle=True)
if upload is not None and upload.upload_time is not None:
assert coe_upload.created.isoformat()[:26] == upload.upload_time.isoformat()
def assert_coe_calc(coe_calc: Calc, calc: datamodel.DFTCalcWithMetadata):
def assert_coe_calc(coe_calc: Calc, calc: datamodel.DFTCalcWithMetadata, has_handle: bool = False):
if calc.pid is not None:
assert coe_calc.pid == calc.pid
elif has_handle:
assert coe_calc.pid is not None
assert create_handle(coe_calc.pid) == coe_calc.handlepid
# calc data
assert len(coe_calc.files) == len(calc.files)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment