mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Change database schema to separate Dataset and HistoryDatasetAssociation. This is a significant change, be sure to follow the migration notes exactly.
Make sure to backup your database before updating.
Also fix a long standing bug in the async controller dealing with updating output datasets upon job completion.
Credit for database migration directions go to Greg.
*** This is a significant change, be sure to follow the migration steps below exactly and in order: ***
---------------
0. Stop Galaxy server
---------------
1. Backup database and galaxy_root/database directory
---------------
2. The current validation_error table is not being used, it is left over from Ian's work that was not made functional. However, if we want to keep it around, we should drop the old version of the table so it will get re-created correctly when the Galaxy server is restarted:
any database - sql command(s):
------------------------------
DROP TABLE validation_error;
---------------
3. Stop server, perform svn update to get latest code, start server to create new history_dataset_association and implicitly_converted_dataset_association tables
---------------
4. Add new columns to dataset table:
postgres sql command(s):
------------------------
ALTER TABLE dataset ADD COLUMN purgable boolean DEFAULT 't';
ALTER TABLE dataset ADD COLUMN external_filename text;
ALTER TABLE dataset ADD COLUMN _extra_files_path text;
mysql sql command(s):
---------------------
ALTER TABLE dataset ADD COLUMN purgable boolean DEFAULT TRUE;
ALTER TABLE dataset ADD COLUMN external_filename text;
ALTER TABLE dataset ADD COLUMN _extra_files_path text;
sqlite sql command(s):
----------------------
ALTER TABLE dataset ADD COLUMN purgable boolean DEFAULT 0;
ALTER TABLE dataset ADD COLUMN external_filename text;
ALTER TABLE dataset ADD COLUMN _extra_files_path text;
---------------
5. Populate new columns:
postgres sql command(s):
------------------------
UPDATE
dataset
SET
external_filename = dataset_filename.filename,
_extra_files_path = dataset_filename.extra_files_path
FROM
dataset_filename
WHERE
dataset.filename_id = dataset_filename.id;
mysql or sqlite sql command(s):
-------------------------------
UPDATE
dataset,
dataset_filename
SET
dataset.external_filename = dataset_filename.filename,
dataset._extra_files_path = dataset_filename.extra_files_path
WHERE
dataset.filename_id = dataset_filename.id;
---------------
6. Populate dataset table with info from dataset_child_association table:
postgres sql command(s):
------------------------
UPDATE
dataset
SET
parent_id = dataset_child_association.parent_dataset_id
FROM
dataset_child_association
WHERE
dataset.id = dataset_child_association.child_dataset_id;
mysql or sqlite sql command(s):
-------------------------------
UPDATE
dataset,
dataset_child_association
SET
dataset.parent_id = dataset_child_association.parent_dataset_id
WHERE
dataset.id = dataset_child_association.child_dataset_id;
---------------
7. Drop dataset_child_association table:
any database - sql command(s):
------------------------------
DROP TABLE dataset_child_association;
---------------
8. Copy parts of the current dataset table to the new history_dataset_association table:
postgres sql command(s):
------------------------
INSERT INTO history_dataset_association
SELECT
id,
history_id,
id AS dataset_id,
create_time,
update_time,
hid,
name,
info,
blurb,
peek,
extension,
metadata,
parent_id,
designation,
deleted,
visible
FROM dataset
ORDER BY id;
mysql or sqlite sql command(s):
-------------------------------
INSERT INTO
history_dataset_association
(
history_id,
dataset_id,
create_time,
update_time,
hid,
name,
info,
blurb,
peek,
extension,
metadata,
parent_id,
designation,
deleted,
visible
)
SELECT
history_id,
id,
create_time,
update_time,
hid,
name,
info,
blurb,
peek,
extension,
metadata,
parent_id,
designation,
deleted,
visible
FROM
dataset
ORDER BY
id;
---------------
9. Update the nextval value of the primary key sequence in the history_dataset_association table
NOTE: THIS IS NOT NECESSARY FOR MYSQL OR SQLITE!
postgres sql command(s):
------------------------
SELECT
setval('history_dataset_association_id_seq', max(id))
FROM
history_dataset_association;
---------------
10. Update dataset table to mark dataset_associated_file dataset as deleted:
postgres sql command(s):
------------------------
UPDATE dataset
SET
deleted = 't'
WHERE
id IN
(SELECT dataset_id FROM dataset_associated_file ORDER BY dataset_id DESC);
mysql or sqlite sql command(s):
-------------------------------
UPDATE dataset
SET
deleted = TRUE
WHERE
id IN
(SELECT dataset_id FROM dataset_associated_file ORDER BY dataset_id DESC);
---------------
11. Drop the dataset_associated_file table:
any database - sql command(s):
------------------------------
DROP TABLE dataset_associated_file;
---------------
12. Alter foreign keys on job_to_input_dataset table:
postgres or sqlite sql command(s):
------------------------
ALTER TABLE
job_to_input_dataset
DROP CONSTRAINT
job_to_input_dataset_dataset_id_fkey;
ALTER TABLE
job_to_input_dataset
ADD CONSTRAINT job_to_input_dataset_dataset_id_fkey
FOREIGN KEY
(dataset_id)
REFERENCES
history_dataset_association(id);
mysql sql command(s):
-------------------------------
ALTER TABLE
job_to_input_dataset
DROP FOREIGN KEY
ix_job_to_input_dataset_dataset_id;
ALTER TABLE
job_to_input_dataset
ADD FOREIGN KEY
ix_job_to_input_dataset_dataset_id (dataset_id)
REFERENCES
history_dataset_association(id);
---------------
13. Alter foreign keys on job_to_output_dataset table:
postgres or sqlite sql command(s):
------------------------
ALTER TABLE
job_to_output_dataset
DROP CONSTRAINT
job_to_output_dataset_dataset_id_fkey;
ALTER TABLE
job_to_output_dataset
ADD CONSTRAINT
job_to_output_dataset_dataset_id_fkey
FOREIGN KEY (dataset_id)
REFERENCES history_dataset_association(id);
mysql sql command(s):
-------------------------------
ALTER TABLE
job_to_output_dataset
DROP FOREIGN KEY
ix_job_to_output_dataset_dataset_id;
ALTER TABLE
job_to_output_dataset
ADD FOREIGN KEY
ix_job_to_output_dataset_dataset_id
FOREIGN KEY (dataset_id)
REFERENCES history_dataset_association(id);
---------------
14. Eliminate columns from the dataset table previously copied to history_dataset_association:
any database - sql command(s):
------------------------------
ALTER TABLE dataset DROP COLUMN hid;
ALTER TABLE dataset DROP COLUMN history_id;
ALTER TABLE dataset DROP COLUMN name;
ALTER TABLE dataset DROP COLUMN info;
ALTER TABLE dataset DROP COLUMN blurb;
ALTER TABLE dataset DROP COLUMN peek;
ALTER TABLE dataset DROP COLUMN extension;
ALTER TABLE dataset DROP COLUMN dbkey;
ALTER TABLE dataset DROP COLUMN metadata;
ALTER TABLE dataset DROP COLUMN parent_id;
ALTER TABLE dataset DROP COLUMN designation;
ALTER TABLE dataset DROP COLUMN visible;
ALTER TABLE dataset DROP COLUMN filename_id;
This commit is contained in:
+41
-27
@@ -369,6 +369,7 @@ class JobWrapper( object ):
|
||||
idata = dataset_assoc.dataset
|
||||
if not idata: continue
|
||||
idata.refresh()
|
||||
idata.dataset.refresh() #we need to refresh the base Dataset, since that is where 'state' is stored
|
||||
# don't run jobs for which the input dataset was deleted
|
||||
if idata.deleted == True:
|
||||
self.fail( "input data %d was deleted before this job ran" % idata.hid )
|
||||
@@ -398,30 +399,36 @@ class JobWrapper( object ):
|
||||
if job.state == job.states.DELETED:
|
||||
self.cleanup()
|
||||
return
|
||||
job.state = 'ok'
|
||||
if stderr:
|
||||
job.state = "error"
|
||||
else:
|
||||
job.state = 'ok'
|
||||
for dataset_assoc in job.output_datasets:
|
||||
dataset = dataset_assoc.dataset
|
||||
dataset.refresh()
|
||||
dataset.state = model.Dataset.states.OK
|
||||
dataset.blurb = 'done'
|
||||
dataset.peek = 'no peek'
|
||||
dataset.info = stdout + stderr
|
||||
dataset.set_size()
|
||||
if dataset.has_data():
|
||||
# Only set metadata values if they are missing...
|
||||
if dataset.missing_meta():
|
||||
dataset.set_meta()
|
||||
else:
|
||||
# ...however, some tools add / remove columns,
|
||||
# so we have to reset the readonly metadata values
|
||||
dataset.set_readonly_meta()
|
||||
dataset.set_peek()
|
||||
else:
|
||||
dataset.blurb = "empty"
|
||||
if stderr:
|
||||
dataset.state = model.Dataset.states.ERROR
|
||||
dataset.blurb = "error"
|
||||
job.state = "error"
|
||||
dataset_assoc.dataset.dataset.state = model.Dataset.states.ERROR
|
||||
else:
|
||||
dataset_assoc.dataset.dataset.state = model.Dataset.states.OK
|
||||
dataset_assoc.dataset.dataset.flush()
|
||||
for dataset in dataset_assoc.dataset.dataset.history_associations: #need to update all associated output hdas, i.e. history was shared with job running
|
||||
dataset.blurb = 'done'
|
||||
dataset.peek = 'no peek'
|
||||
dataset.info = stdout + stderr
|
||||
dataset.set_size()
|
||||
if stderr:
|
||||
dataset.blurb = "error"
|
||||
elif dataset.has_data():
|
||||
# Only set metadata values if they are missing...
|
||||
if dataset.missing_meta():
|
||||
dataset.set_meta()
|
||||
else:
|
||||
# ...however, some tools add / remove columns,
|
||||
# so we have to reset the readonly metadata values
|
||||
dataset.set_readonly_meta()
|
||||
dataset.set_peek()
|
||||
else:
|
||||
dataset.blurb = "empty"
|
||||
dataset.flush()
|
||||
|
||||
# Save stdout and stderr
|
||||
if len( stdout ) > 32768:
|
||||
log.error( "stdout for job %d is greater than 32K, only first part will be logged to database" % job.id )
|
||||
@@ -588,6 +595,8 @@ class JobStopQueue( object ):
|
||||
for dataset_assoc in job.output_datasets:
|
||||
dataset = dataset_assoc.dataset
|
||||
dataset.refresh()
|
||||
#only the originator of the job can delete a dataset to cause
|
||||
#cancellation of the job, no need to loop through history_associations
|
||||
if not dataset.deleted:
|
||||
return False
|
||||
return True
|
||||
@@ -601,11 +610,16 @@ class JobStopQueue( object ):
|
||||
for dataset_assoc in job.output_datasets:
|
||||
dataset = dataset_assoc.dataset
|
||||
dataset.refresh()
|
||||
dataset.state = model.Dataset.states.DELETED
|
||||
dataset.blurb = 'deleted'
|
||||
dataset.peek = 'Job deleted'
|
||||
dataset.info = 'Job deleted by user before it completed'
|
||||
dataset.flush()
|
||||
dataset.deleted = True
|
||||
dataset.state = dataset.states.DISCARDED
|
||||
dataset.dataset.flush()
|
||||
for dataset in dataset.dataset.history_associations:
|
||||
#propagate info across shared datasets
|
||||
dataset.deleted = True
|
||||
dataset.blurb = 'deleted'
|
||||
dataset.peek = 'Job deleted'
|
||||
dataset.info = 'Job deleted by user before it completed'
|
||||
dataset.flush()
|
||||
|
||||
def put( self, job ):
|
||||
self.queue.put( job )
|
||||
|
||||
+210
-223
@@ -99,92 +99,11 @@ class JobToOutputDatasetAssociation( object ):
|
||||
def __init__( self, name, dataset ):
|
||||
self.name = name
|
||||
self.dataset = dataset
|
||||
|
||||
class History( object ):
|
||||
def __init__( self, id=None, name=None, user=None ):
|
||||
self.id = id
|
||||
self.name = name or "Unnamed history"
|
||||
self.deleted = False
|
||||
self.purged = False
|
||||
self.genome_build = None
|
||||
# Relationships
|
||||
self.user = user
|
||||
self.datasets = []
|
||||
self.galaxy_sessions = []
|
||||
|
||||
def _next_hid( self ):
|
||||
# TODO: override this with something in the database that ensures
|
||||
# better integrity
|
||||
if len( self.datasets ) == 0:
|
||||
return 1
|
||||
else:
|
||||
last_hid = 0
|
||||
for dataset in self.datasets:
|
||||
if dataset.hid > last_hid:
|
||||
last_hid = dataset.hid
|
||||
return last_hid + 1
|
||||
|
||||
def add_galaxy_session( self, galaxy_session, association=None ):
|
||||
if association is None:
|
||||
self.galaxy_sessions.append( GalaxySessionToHistoryAssociation( galaxy_session, self ) )
|
||||
else:
|
||||
self.galaxy_sessions.append( association )
|
||||
|
||||
def add_dataset( self, dataset, parent_id=None, genome_build=None, set_hid = True ):
|
||||
if parent_id:
|
||||
for data in self.datasets:
|
||||
if data.id == parent_id:
|
||||
dataset.hid = data.hid
|
||||
break
|
||||
else:
|
||||
if set_hid: dataset.hid = self._next_hid()
|
||||
else:
|
||||
if set_hid: dataset.hid = self._next_hid()
|
||||
self.genome_build = genome_build
|
||||
self.datasets.append( dataset )
|
||||
|
||||
def copy(self):
|
||||
des = History()
|
||||
des.flush()
|
||||
des.name = self.name
|
||||
des.user_id = self.user_id
|
||||
for data in self.datasets:
|
||||
new_data = data.copy()
|
||||
des.add_dataset(new_data)
|
||||
new_data.hid = data.hid
|
||||
new_data.flush()
|
||||
for child_assoc in data.children:
|
||||
new_child = child_assoc.child.copy()
|
||||
new_assoc = DatasetChildAssociation( child_assoc.designation )
|
||||
new_assoc.child = new_child
|
||||
new_assoc.parent = new_data
|
||||
new_child.flush()
|
||||
des.hid_counter = self.hid_counter
|
||||
des.flush()
|
||||
return des
|
||||
|
||||
# class Query( object ):
|
||||
# def __init__( self, name=None, state=None, tool_parameters=None, history=None ):
|
||||
# self.name = name or "Unnamed query"
|
||||
# self.state = state
|
||||
# self.tool_parameters = tool_parameters
|
||||
# # Relationships
|
||||
# self.history = history
|
||||
# self.datasets = []
|
||||
|
||||
class Dataset( object ):
|
||||
states = Bunch( NEW = 'new',
|
||||
QUEUED = 'queued',
|
||||
RUNNING = 'running',
|
||||
OK = 'ok',
|
||||
EMPTY = 'empty',
|
||||
ERROR = 'error',
|
||||
DELETED = 'deleted')
|
||||
file_path = "/tmp/"
|
||||
engine = None
|
||||
class HistoryDatasetAssociation( object ):
|
||||
def __init__( self, id=None, hid=None, name=None, info=None, blurb=None, peek=None, extension=None,
|
||||
dbkey=None, state=None, metadata=None, history=None, parent_id=None, designation=None,
|
||||
validation_errors=None, visible=True, filename_id = None, file_size=None ):
|
||||
dbkey=None, metadata=None, history=None, dataset=None, deleted=False, designation=None,
|
||||
parent_id=None, validation_errors=None, visible=True, create_dataset = False ):
|
||||
self.name = name or "Unnamed dataset"
|
||||
self.id = id
|
||||
self.hid = hid
|
||||
@@ -193,71 +112,44 @@ class Dataset( object ):
|
||||
self.peek = peek
|
||||
self.extension = extension
|
||||
self.dbkey = dbkey
|
||||
self.state = state
|
||||
self._metadata = metadata or dict()
|
||||
self.parent_id = parent_id
|
||||
self.designation = designation
|
||||
self.deleted = False
|
||||
self.purged = False
|
||||
self._metadata = metadata or dict()
|
||||
self.deleted = deleted
|
||||
self.visible = visible
|
||||
self.filename_id = filename_id
|
||||
self.file_size = file_size
|
||||
# Relationships
|
||||
self.history = history
|
||||
if not dataset and create_dataset:
|
||||
dataset = Dataset()
|
||||
dataset.flush()
|
||||
self.dataset = dataset
|
||||
self.parent_id = parent_id
|
||||
self.validation_errors = validation_errors
|
||||
|
||||
|
||||
@property
|
||||
def ext( self ):
|
||||
return self.extension
|
||||
|
||||
@property
|
||||
def states( self ):
|
||||
return self.dataset.states
|
||||
|
||||
def get_dataset_state( self ):
|
||||
return self.dataset.state
|
||||
def set_dataset_state ( self, state ):
|
||||
self.dataset.state = state
|
||||
state = property( get_dataset_state, set_dataset_state )
|
||||
|
||||
def get_file_name( self ):
|
||||
if self.filename_id is None:
|
||||
assert self.id is not None, "ID must be set before filename used (commit the object)"
|
||||
# First try filename directly under file_path
|
||||
filename = os.path.join( self.file_path, "dataset_%d.dat" % self.id )
|
||||
# Only use that filename if it already exists (backward compatibility),
|
||||
# otherwise construct hashed path
|
||||
if not os.path.exists( filename ):
|
||||
dir = os.path.join( self.file_path, *directory_hash_id( self.id ) )
|
||||
# Create directory if it does not exist
|
||||
try:
|
||||
os.makedirs( dir )
|
||||
except OSError, e:
|
||||
# File Exists is okay, otherwise reraise
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
# Return filename inside hashed directory
|
||||
return os.path.abspath( os.path.join( dir, "dataset_%d.dat" % self.id ) )
|
||||
else:
|
||||
filename = self.dataset_file.filename
|
||||
# Make filename absolute
|
||||
return os.path.abspath( filename )
|
||||
return self.dataset.get_file_name()
|
||||
|
||||
def set_file_name (self, filename):
|
||||
if filename is None:
|
||||
self.filename_id = None
|
||||
else:
|
||||
filename_obj = DatasetFileName.get_by(filename=filename)
|
||||
if filename_obj is None:
|
||||
filename_obj = DatasetFileName(filename=filename, extra_files_path=self.extra_files_path)
|
||||
filename_obj.flush()
|
||||
self.filename_id = filename_obj.id
|
||||
self.flush()
|
||||
self.refresh()
|
||||
return self.dataset.set_file_name( filename )
|
||||
|
||||
file_name = property( get_file_name, set_file_name )
|
||||
|
||||
@property
|
||||
def extra_files_path( self ):
|
||||
if self.dataset_file and self.dataset_file.extra_files_path:
|
||||
path = self.dataset_file.extra_files_path
|
||||
else:
|
||||
path = os.path.join( self.file_path, "dataset_%d_files" % self.id )
|
||||
#only use path directly under self.file_path if it exists
|
||||
if not os.path.exists( path ):
|
||||
path = os.path.join( os.path.join( self.file_path, *directory_hash_id( self.id ) ), "dataset_%d_files" % self.id )
|
||||
# Make path absolute
|
||||
return os.path.abspath( path )
|
||||
return self.dataset.extra_files_path
|
||||
|
||||
@property
|
||||
def datatype( self ):
|
||||
@@ -279,7 +171,7 @@ class Dataset( object ):
|
||||
def get_dbkey( self ):
|
||||
dbkey = self.metadata.dbkey
|
||||
if not isinstance(dbkey, list): dbkey = [dbkey]
|
||||
if dbkey in [["?"], [None], []]: dbkey = [self.old_dbkey]
|
||||
#if dbkey in [["?"], [None], []]: dbkey = [self.old_dbkey]
|
||||
if dbkey in [[None], []]: return "?"
|
||||
return dbkey[0]
|
||||
def set_dbkey( self, value ):
|
||||
@@ -288,10 +180,10 @@ class Dataset( object ):
|
||||
self.metadata.dbkey = [value]
|
||||
else:
|
||||
self.metadata.dbkey = value
|
||||
if isinstance(value, list):
|
||||
self.old_dbkey = value[0]
|
||||
else:
|
||||
self.old_dbkey = value
|
||||
#if isinstance(value, list):
|
||||
# self.old_dbkey = value[0]
|
||||
#else:
|
||||
# self.old_dbkey = value
|
||||
dbkey = property( get_dbkey, set_dbkey )
|
||||
|
||||
def change_datatype( self, new_ext ):
|
||||
@@ -299,22 +191,13 @@ class Dataset( object ):
|
||||
datatypes_registry.change_datatype( self, new_ext )
|
||||
def get_size( self ):
|
||||
"""Returns the size of the data on disk"""
|
||||
if self.file_size:
|
||||
return self.file_size
|
||||
else:
|
||||
try:
|
||||
return os.path.getsize( self.file_name )
|
||||
except OSError:
|
||||
return 0
|
||||
return self.dataset.get_size()
|
||||
def set_size( self ):
|
||||
"""Returns the size of the data on disk"""
|
||||
try:
|
||||
self.file_size = os.path.getsize( self.file_name )
|
||||
except OSError:
|
||||
self.file_size = 0
|
||||
return self.dataset.set_size()
|
||||
def has_data( self ):
|
||||
"""Detects whether there is any data"""
|
||||
return self.get_size() > 0
|
||||
return self.dataset.has_data()
|
||||
def get_raw_data( self ):
|
||||
"""Returns the full data. To stream it open the file_name and read/write as needed"""
|
||||
return self.datatype.get_raw_data( self )
|
||||
@@ -346,55 +229,33 @@ class Dataset( object ):
|
||||
return self.datatype.display_name( self )
|
||||
def display_info( self ):
|
||||
return self.datatype.display_info( self )
|
||||
def get_associated_files_by_type( self, file_type ):
|
||||
def get_converted_files_by_type( self, file_type ):
|
||||
valid = []
|
||||
for assoc in self.associated_files:
|
||||
for assoc in self.implicitly_converted_datasets:
|
||||
if not assoc.deleted and assoc.type == file_type:
|
||||
valid.append( assoc )
|
||||
valid.append( assoc.dataset )
|
||||
return valid
|
||||
def clear_associated_files( self, metadata_safe = False, purge = False ):
|
||||
#metadata_safe = True means to only clear when assoc.metadata_safe == False
|
||||
for assoc in self.associated_files:
|
||||
for assoc in self.implicitly_converted_datasets:
|
||||
if not metadata_safe or not assoc.metadata_safe:
|
||||
assoc.clear( purge = purge )
|
||||
def get_child_by_designation(self, designation):
|
||||
# if self.history:
|
||||
# for data in self.history.datasets:
|
||||
# if data.parent_id and data.parent_id == self.id:
|
||||
# if designation == data.designation:
|
||||
# return data
|
||||
for child_association in self.children:
|
||||
if child_association.designation == designation:
|
||||
return child_association.child
|
||||
for child in self.children:
|
||||
if child.designation == designation:
|
||||
return child
|
||||
return None
|
||||
|
||||
def get_converter_types(self):
|
||||
return self.datatype.get_converter_types( self, datatypes_registry)
|
||||
|
||||
def copy(self, parent_id=None):
|
||||
des = Dataset(extension=self.ext)
|
||||
def copy( self, copy_children = False, parent_id = None ):
|
||||
des = HistoryDatasetAssociation( hid=self.hid, name=self.name, info=self.info, blurb=self.blurb, peek=self.peek, extension=self.extension, dbkey=self.dbkey, metadata=self._metadata, dataset = self.dataset, visible=self.visible, deleted=self.deleted, parent_id=parent_id )
|
||||
des.flush()
|
||||
des.name = self.name
|
||||
des.info = self.info
|
||||
des.blurb = self.blurb
|
||||
des.peek = self.peek
|
||||
des.extension = self.extension
|
||||
des.dbkey = str( self.dbkey )
|
||||
des.state = self.state
|
||||
des.metadata = self.metadata
|
||||
des.hid = self.hid
|
||||
des.deleted = self.deleted
|
||||
des.purged = self.purged
|
||||
# Make sure source is using filename table, so purge works properly
|
||||
if not self.dataset_file:
|
||||
self.set_file_name(self.file_name)
|
||||
self.flush()
|
||||
self.refresh()
|
||||
self.dataset_file.extra_files_path = self.extra_files_path
|
||||
self.flush()
|
||||
# Don't copy file contents, share original file
|
||||
des.file_name = self.file_name
|
||||
des.hid = self.hid
|
||||
des.designation = self.designation
|
||||
if copy_children:
|
||||
for child in self.children:
|
||||
child_copy = child.copy( copy_children = copy_children, parent_id = des.id )
|
||||
des.set_peek() #in some instances peek relies on dataset_id, i.e. gmaj.zip for viewing MAFs
|
||||
des.flush()
|
||||
return des
|
||||
|
||||
@@ -407,9 +268,166 @@ class Dataset( object ):
|
||||
def mark_deleted( self, include_children=True ):
|
||||
self.deleted = True
|
||||
if include_children:
|
||||
for child_assoc in self.children:
|
||||
child_assoc.child.mark_deleted()
|
||||
for child in self.children:
|
||||
child.mark_deleted()
|
||||
|
||||
|
||||
|
||||
class History( object ):
|
||||
def __init__( self, id=None, name=None, user=None ):
|
||||
self.id = id
|
||||
self.name = name or "Unnamed history"
|
||||
self.deleted = False
|
||||
self.purged = False
|
||||
self.genome_build = None
|
||||
# Relationships
|
||||
self.user = user
|
||||
self.datasets = []
|
||||
self.galaxy_sessions = []
|
||||
|
||||
def _next_hid( self ):
|
||||
# TODO: override this with something in the database that ensures
|
||||
# better integrity
|
||||
if len( self.datasets ) == 0:
|
||||
return 1
|
||||
else:
|
||||
last_hid = 0
|
||||
for dataset in self.datasets:
|
||||
if dataset.hid > last_hid:
|
||||
last_hid = dataset.hid
|
||||
return last_hid + 1
|
||||
|
||||
def add_galaxy_session( self, galaxy_session, association=None ):
|
||||
if association is None:
|
||||
self.galaxy_sessions.append( GalaxySessionToHistoryAssociation( galaxy_session, self ) )
|
||||
else:
|
||||
self.galaxy_sessions.append( association )
|
||||
|
||||
def add_dataset( self, dataset, parent_id=None, genome_build=None, set_hid = True ):
|
||||
if isinstance( dataset, Dataset ):
|
||||
dataset = HistoryDatasetAssociation( dataset = dataset )
|
||||
dataset.flush()
|
||||
elif not isinstance( dataset, HistoryDatasetAssociation ):
|
||||
raise TypeError, "You can only add Dataset and HistoryDatasetAssociation instances to a history."
|
||||
if parent_id:
|
||||
for data in self.datasets:
|
||||
if data.id == parent_id:
|
||||
dataset.hid = data.hid
|
||||
break
|
||||
else:
|
||||
if set_hid: dataset.hid = self._next_hid()
|
||||
else:
|
||||
if set_hid: dataset.hid = self._next_hid()
|
||||
dataset.history = self
|
||||
if genome_build not in [None, '?']:
|
||||
self.genome_build = genome_build
|
||||
self.datasets.append( dataset )
|
||||
|
||||
def copy(self):
|
||||
des = History()
|
||||
des.flush()
|
||||
des.name = self.name
|
||||
des.user_id = self.user_id
|
||||
for data in self.datasets:
|
||||
new_data = data.copy( copy_children = True )
|
||||
des.add_dataset( new_data )
|
||||
new_data.flush()
|
||||
des.hid_counter = self.hid_counter
|
||||
des.flush()
|
||||
return des
|
||||
|
||||
# class Query( object ):
|
||||
# def __init__( self, name=None, state=None, tool_parameters=None, history=None ):
|
||||
# self.name = name or "Unnamed query"
|
||||
# self.state = state
|
||||
# self.tool_parameters = tool_parameters
|
||||
# # Relationships
|
||||
# self.history = history
|
||||
# self.datasets = []
|
||||
|
||||
class Dataset( object ):
|
||||
states = Bunch( NEW = 'new',
|
||||
QUEUED = 'queued',
|
||||
RUNNING = 'running',
|
||||
OK = 'ok',
|
||||
EMPTY = 'empty',
|
||||
ERROR = 'error',
|
||||
DISCARDED = 'discarded' )
|
||||
file_path = "/tmp/"
|
||||
engine = None
|
||||
def __init__( self, id=None, state=None, external_filename=None, extra_files_path=None, file_size=None, purgable=True ):
|
||||
self.id = id
|
||||
self.state = state
|
||||
self.deleted = False
|
||||
self.purged = False
|
||||
self.purgable = purgable
|
||||
self.external_filename = external_filename
|
||||
self._extra_files_path = extra_files_path
|
||||
self.file_size = file_size
|
||||
|
||||
def get_file_name( self ):
|
||||
if not self.external_filename:
|
||||
assert self.id is not None, "ID must be set before filename used (commit the object)"
|
||||
# First try filename directly under file_path
|
||||
filename = os.path.join( self.file_path, "dataset_%d.dat" % self.id )
|
||||
# Only use that filename if it already exists (backward compatibility),
|
||||
# otherwise construct hashed path
|
||||
if not os.path.exists( filename ):
|
||||
dir = os.path.join( self.file_path, *directory_hash_id( self.id ) )
|
||||
# Create directory if it does not exist
|
||||
try:
|
||||
os.makedirs( dir )
|
||||
except OSError, e:
|
||||
# File Exists is okay, otherwise reraise
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
# Return filename inside hashed directory
|
||||
return os.path.abspath( os.path.join( dir, "dataset_%d.dat" % self.id ) )
|
||||
else:
|
||||
filename = self.external_filename
|
||||
# Make filename absolute
|
||||
return os.path.abspath( filename )
|
||||
|
||||
def set_file_name ( self, filename ):
|
||||
if not filename:
|
||||
self.external_filename = None
|
||||
else:
|
||||
self.external_filename = filename
|
||||
|
||||
file_name = property( get_file_name, set_file_name )
|
||||
|
||||
@property
|
||||
def extra_files_path( self ):
|
||||
if self._extra_files_path:
|
||||
path = self._extra_files_path
|
||||
else:
|
||||
path = os.path.join( self.file_path, "dataset_%d_files" % self.id )
|
||||
#only use path directly under self.file_path if it exists
|
||||
if not os.path.exists( path ):
|
||||
path = os.path.join( os.path.join( self.file_path, *directory_hash_id( self.id ) ), "dataset_%d_files" % self.id )
|
||||
# Make path absolute
|
||||
return os.path.abspath( path )
|
||||
|
||||
def get_size( self ):
|
||||
"""Returns the size of the data on disk"""
|
||||
if self.file_size:
|
||||
return self.file_size
|
||||
else:
|
||||
try:
|
||||
return os.path.getsize( self.file_name )
|
||||
except OSError:
|
||||
return 0
|
||||
def set_size( self ):
|
||||
"""Returns the size of the data on disk"""
|
||||
try:
|
||||
self.file_size = os.path.getsize( self.file_name )
|
||||
except OSError:
|
||||
self.file_size = 0
|
||||
def has_data( self ):
|
||||
"""Detects whether there is any data"""
|
||||
return self.get_size() > 0
|
||||
def mark_deleted( self, include_children=True ):
|
||||
self.deleted = True
|
||||
|
||||
# FIXME: sqlalchemy will replace this
|
||||
def _delete(self):
|
||||
@@ -419,12 +437,6 @@ class Dataset( object ):
|
||||
except OSError, e:
|
||||
log.critical('%s delete error %s' % (self.__class__.__name__, e))
|
||||
|
||||
class DatasetFileName( object ):
|
||||
def __init__( self, filename=None, readonly=False, extra_files_path=None ):
|
||||
self.filename = filename
|
||||
self.readonly = readonly
|
||||
self.extra_files_path = extra_files_path
|
||||
|
||||
class Old_Dataset( Dataset ):
|
||||
pass
|
||||
|
||||
@@ -439,47 +451,22 @@ class DatasetToValidationErrorAssociation( object ):
|
||||
self.dataset = dataset
|
||||
self.validation_error = validation_error
|
||||
|
||||
class DatasetChildAssociation( object ):
|
||||
def __init__( self, designation=None ):
|
||||
self.designation = designation
|
||||
self.parent = None
|
||||
self.child = None
|
||||
|
||||
class DatasetAssociatedFile( object ):
|
||||
def __init__( self, id = None, dataset_id = None, file_type = None, parent_id = None, filename = None, deleted = False, purged = False, metadata_safe = True ):
|
||||
class ImplicitlyConvertedDatasetAssociation( object ):
|
||||
def __init__( self, id = None, parent = None, dataset = None, file_type = None, deleted = False, purged = False, metadata_safe = True ):
|
||||
self.id = id
|
||||
self.dataset_id = dataset_id
|
||||
self.dataset = dataset
|
||||
self.parent = parent
|
||||
self.type = file_type
|
||||
self.parent_id = parent_id
|
||||
self.filename = filename
|
||||
self.deleted = deleted
|
||||
self.purged = purged
|
||||
self.metadata_safe = metadata_safe
|
||||
|
||||
def get_file_name( self ):
|
||||
#return absolute path of the filename
|
||||
if self.filename:
|
||||
return os.path.abspath( self.filename )
|
||||
if self.dataset_id is not None:
|
||||
return self.dataset.file_name
|
||||
else:
|
||||
assert self.id is not None, "ID must be set before filename used (commit the object)"
|
||||
assert self.parent_id is not None, "Parent ID must be set before filename used"
|
||||
return os.path.abspath( "%s_accociated_%s" % ( self.parent.file_name, self.id ) )
|
||||
def set_file_name ( self, filename ):
|
||||
self.filename = filename
|
||||
if self.dataset:
|
||||
self.dataset.deleted = True
|
||||
self.dataset = None
|
||||
self.dataset_id = None
|
||||
file_name = property( get_file_name, set_file_name )
|
||||
|
||||
def clear( self, purge = False ):
|
||||
self.deleted = True
|
||||
if self.dataset:
|
||||
self.dataset.deleted = True
|
||||
self.dataset.purged = purge
|
||||
if purge:
|
||||
if purge: #do something with purging
|
||||
self.purged = True
|
||||
try: os.unlink( self.file_name )
|
||||
except Exception, e: print "Failed to purge associated file (%s) from disk: %s" % ( self.file_name, e )
|
||||
|
||||
+61
-67
@@ -63,62 +63,54 @@ History.table = Table( "history", metadata,
|
||||
# Column( "state", String( 64 ) ),
|
||||
# Column( "tool_parameters", Pickle() ) )
|
||||
|
||||
Dataset.table = Table( "dataset", metadata,
|
||||
|
||||
HistoryDatasetAssociation.table = Table( "history_dataset_association", metadata,
|
||||
Column( "id", Integer, primary_key=True ),
|
||||
Column( "create_time", DateTime, default=now ),
|
||||
Column( "update_time", DateTime, index=True, default=now, onupdate=now ),
|
||||
Column( "hid", Integer ),
|
||||
Column( "history_id", Integer, ForeignKey( "history.id" ), index=True ),
|
||||
Column( "dataset_id", Integer, ForeignKey( "dataset.id" ), index=True ),
|
||||
Column( "create_time", DateTime, default=now ),
|
||||
Column( "update_time", DateTime, default=now, onupdate=now ),
|
||||
Column( "hid", Integer ),
|
||||
Column( "name", TrimmedString( 255 ) ),
|
||||
Column( "info", TrimmedString( 255 ) ),
|
||||
Column( "blurb", TrimmedString( 255 ) ),
|
||||
Column( "peek" , TEXT ),
|
||||
Column( "extension", TrimmedString( 64 ) ),
|
||||
Column( "dbkey", TrimmedString( 64 ), key="old_dbkey" ), # maps to old_dbkey, see __init__.py
|
||||
Column( "state", TrimmedString( 64 ) ),
|
||||
Column( "metadata", MetadataType(), key="_metadata" ),
|
||||
Column( "parent_id", Integer, nullable=True ),
|
||||
Column( "parent_id", Integer, ForeignKey( "history_dataset_association.id" ), nullable=True ),
|
||||
Column( "designation", TrimmedString( 255 ) ),
|
||||
Column( "deleted", Boolean, index=True, default=False ),
|
||||
Column( "purged", Boolean, index=True, default=False ),
|
||||
Column( "visible", Boolean ),
|
||||
Column( "filename_id", Integer, ForeignKey( "dataset_filename.id" ), index=True, nullable=True ),
|
||||
Column( 'file_size', Numeric( 15, 0 ) ),
|
||||
ForeignKeyConstraint(['parent_id'],['dataset.id'], ondelete="CASCADE") )
|
||||
Column( "visible", Boolean ) )
|
||||
|
||||
DatasetAssociatedFile.table = Table( "dataset_associated_file", metadata,
|
||||
Dataset.table = Table( "dataset", metadata,
|
||||
Column( "id", Integer, primary_key=True ),
|
||||
Column( "create_time", DateTime, default=now ),
|
||||
Column( "update_time", DateTime, index=True, default=now, onupdate=now ),
|
||||
Column( "state", TrimmedString( 64 ) ),
|
||||
Column( "deleted", Boolean, index=True, default=False ),
|
||||
Column( "purged", Boolean, index=True, default=False ),
|
||||
Column( "purgable", Boolean, default=True ),
|
||||
Column( "external_filename" , TEXT ),
|
||||
Column( "_extra_files_path", TEXT ),
|
||||
Column( 'file_size', Numeric( 15, 0 ) ) )
|
||||
|
||||
ImplicitlyConvertedDatasetAssociation.table = Table( "implicitly_converted_dataset_association", metadata,
|
||||
Column( "id", Integer, primary_key=True ),
|
||||
Column( "create_time", DateTime, default=now ),
|
||||
Column( "update_time", DateTime, default=now, onupdate=now ),
|
||||
Column( "dataset_id", Integer, ForeignKey( "dataset.id" ), index=True, nullable=True ),
|
||||
Column( "parent_id", Integer, ForeignKey( "dataset.id" ), index=True ),
|
||||
Column( "filename", TEXT ),
|
||||
Column( "hda_id", Integer, ForeignKey( "history_dataset_association.id" ), index=True, nullable=True ),
|
||||
Column( "hda_parent_id", Integer, ForeignKey( "history_dataset_association.id" ), index=True ),
|
||||
Column( "deleted", Boolean, index=True, default=False ),
|
||||
Column( "purged", Boolean, index=True, default=False ),
|
||||
Column( "metadata_safe", Boolean, index=True, default=True ),
|
||||
Column( "type", TrimmedString( 255 ) ) )
|
||||
|
||||
DatasetFileName.table = Table( "dataset_filename", metadata,
|
||||
Column( "id", Integer, primary_key=True ),
|
||||
Column( "create_time", DateTime, default=now ),
|
||||
Column( "update_time", DateTime, default=now, onupdate=now ),
|
||||
Column( "filename", TEXT ),
|
||||
Column( "extra_files_path", TEXT, nullable=True, default=None ),
|
||||
Column( "readonly", Boolean, default=False ) )
|
||||
|
||||
ValidationError.table = Table( "validation_error", metadata,
|
||||
Column( "id", Integer, primary_key=True ),
|
||||
Column( "dataset_id", Integer, ForeignKey( "dataset.id" ), index=True ),
|
||||
Column( "dataset_id", Integer, ForeignKey( "history_dataset_association.id" ), index=True ),
|
||||
Column( "message", TrimmedString( 255 ) ),
|
||||
Column( "err_type", TrimmedString( 64 ) ),
|
||||
Column( "attributes", TEXT ) )
|
||||
|
||||
DatasetChildAssociation.table = Table( "dataset_child_association", metadata,
|
||||
Column( "id", Integer, primary_key=True ),
|
||||
Column( "parent_dataset_id", Integer, ForeignKey( "dataset.id" ), index=True ),
|
||||
Column( "child_dataset_id", Integer, ForeignKey( "dataset.id" ), index=True ),
|
||||
Column( "designation", TrimmedString( 255 ) ) )
|
||||
|
||||
Job.table = Table( "job", metadata,
|
||||
Column( "id", Integer, primary_key=True ),
|
||||
Column( "create_time", DateTime, default=now ),
|
||||
@@ -147,13 +139,13 @@ JobParameter.table = Table( "job_parameter", metadata,
|
||||
JobToInputDatasetAssociation.table = Table( "job_to_input_dataset", metadata,
|
||||
Column( "id", Integer, primary_key=True ),
|
||||
Column( "job_id", Integer, ForeignKey( "job.id" ), index=True ),
|
||||
Column( "dataset_id", Integer, ForeignKey( "dataset.id" ), index=True ),
|
||||
Column( "dataset_id", Integer, ForeignKey( "history_dataset_association.id" ), index=True ),
|
||||
Column( "name", String(255) ) )
|
||||
|
||||
JobToOutputDatasetAssociation.table = Table( "job_to_output_dataset", metadata,
|
||||
Column( "id", Integer, primary_key=True ),
|
||||
Column( "job_id", Integer, ForeignKey( "job.id" ), index=True ),
|
||||
Column( "dataset_id", Integer, ForeignKey( "dataset.id" ), index=True ),
|
||||
Column( "dataset_id", Integer, ForeignKey( "history_dataset_association.id" ), index=True ),
|
||||
Column( "name", String(255) ) )
|
||||
|
||||
Event.table = Table( "event", metadata,
|
||||
@@ -236,57 +228,59 @@ WorkflowStepConnection.table = Table( "workflow_step_connection", metadata,
|
||||
|
||||
assign_mapper( context, ValidationError, ValidationError.table )
|
||||
|
||||
# assign_mapper( context, Dataset, Dataset.table,
|
||||
# properties=dict( children=relation( DatasetChildAssociation, primaryjoin=( DatasetChildAssociation.table.c.parent_dataset_id == Dataset.table.c.id ),
|
||||
# lazy=False ),
|
||||
# validation_errors=relation( ValidationError, lazy=False ) ) )
|
||||
|
||||
assign_mapper( context, Dataset, Dataset.table,
|
||||
assign_mapper( context, HistoryDatasetAssociation, HistoryDatasetAssociation.table,
|
||||
properties=dict(
|
||||
dataset=relation(
|
||||
Dataset,
|
||||
primaryjoin=( Dataset.table.c.id == HistoryDatasetAssociation.table.c.dataset_id ) ),
|
||||
history=relation(
|
||||
History,
|
||||
primaryjoin=( History.table.c.id == HistoryDatasetAssociation.table.c.history_id ) ),
|
||||
implicitly_converted_datasets=relation(
|
||||
ImplicitlyConvertedDatasetAssociation,
|
||||
primaryjoin=( ImplicitlyConvertedDatasetAssociation.table.c.hda_parent_id == HistoryDatasetAssociation.table.c.id ) ),
|
||||
children=relation(
|
||||
DatasetChildAssociation,
|
||||
primaryjoin=( DatasetChildAssociation.table.c.parent_dataset_id == Dataset.table.c.id ),
|
||||
lazy=False,
|
||||
backref="parent" ),
|
||||
dataset_file=relation(
|
||||
DatasetFileName,
|
||||
primaryjoin=( DatasetFileName.table.c.id == Dataset.table.c.filename_id ) ),
|
||||
associated_files=relation(
|
||||
DatasetAssociatedFile,
|
||||
primaryjoin=( DatasetAssociatedFile.table.c.parent_id == Dataset.table.c.id ) )
|
||||
HistoryDatasetAssociation,
|
||||
primaryjoin=( HistoryDatasetAssociation.table.c.parent_id == HistoryDatasetAssociation.table.c.id ),
|
||||
backref=backref( "parent", remote_side=[HistoryDatasetAssociation.table.c.id] ) )
|
||||
) )
|
||||
|
||||
assign_mapper( context, DatasetFileName, DatasetFileName.table )
|
||||
assign_mapper( context, Dataset, Dataset.table,
|
||||
properties=dict(
|
||||
history_associations=relation(
|
||||
HistoryDatasetAssociation,
|
||||
primaryjoin=( Dataset.table.c.id == HistoryDatasetAssociation.table.c.dataset_id ) )
|
||||
) )
|
||||
|
||||
assign_mapper( context, DatasetChildAssociation, DatasetChildAssociation.table,
|
||||
properties=dict( child=relation( Dataset, backref="parent", primaryjoin=( DatasetChildAssociation.table.c.child_dataset_id == Dataset.table.c.id ) ) ) )
|
||||
|
||||
assign_mapper( context, DatasetAssociatedFile, DatasetAssociatedFile.table,
|
||||
properties=dict( parent=relation(
|
||||
Dataset,
|
||||
primaryjoin=( DatasetAssociatedFile.table.c.parent_id == Dataset.table.c.id ) ),
|
||||
|
||||
dataset=relation(
|
||||
Dataset,
|
||||
primaryjoin=( DatasetAssociatedFile.table.c.dataset_id == Dataset.table.c.id ) ) ) )
|
||||
|
||||
# assign_mapper( model.Query, model.Query.table,
|
||||
# properties=dict( datasets=relation( model.Dataset.mapper, backref="query") ) )
|
||||
|
||||
|
||||
assign_mapper( context, ImplicitlyConvertedDatasetAssociation, ImplicitlyConvertedDatasetAssociation.table,
|
||||
properties=dict( parent=relation(
|
||||
HistoryDatasetAssociation,
|
||||
primaryjoin=( ImplicitlyConvertedDatasetAssociation.table.c.hda_parent_id == HistoryDatasetAssociation.table.c.id ) ),
|
||||
|
||||
dataset=relation(
|
||||
HistoryDatasetAssociation,
|
||||
primaryjoin=( ImplicitlyConvertedDatasetAssociation.table.c.hda_id == HistoryDatasetAssociation.table.c.id ) ) ) )
|
||||
|
||||
assign_mapper( context, History, History.table,
|
||||
properties=dict( galaxy_sessions=relation( GalaxySessionToHistoryAssociation ),
|
||||
datasets=relation( Dataset, backref="history", order_by=asc(Dataset.table.c.hid) ),
|
||||
active_datasets=relation( Dataset, primaryjoin=( ( Dataset.c.history_id == History.table.c.id ) & ( not_( Dataset.c.deleted ) ) ), order_by=asc( Dataset.table.c.hid ), lazy=False, viewonly=True ) ) )
|
||||
datasets=relation( HistoryDatasetAssociation, backref="history", order_by=asc(HistoryDatasetAssociation.table.c.hid) ),
|
||||
active_datasets=relation( HistoryDatasetAssociation, primaryjoin=( ( HistoryDatasetAssociation.table.c.history_id == History.table.c.id ) & ( not_( HistoryDatasetAssociation.table.c.deleted ) ) ), order_by=asc( HistoryDatasetAssociation.table.c.hid ), lazy=False, viewonly=True ) ) )
|
||||
|
||||
|
||||
assign_mapper( context, User, User.table,
|
||||
properties=dict( histories=relation( History, backref="user",
|
||||
order_by=desc(History.table.c.update_time) ) ) )
|
||||
|
||||
assign_mapper( context, JobToInputDatasetAssociation, JobToInputDatasetAssociation.table,
|
||||
properties=dict( job=relation( Job ), dataset=relation( Dataset ) ) )
|
||||
properties=dict( job=relation( Job ), dataset=relation( HistoryDatasetAssociation ) ) )
|
||||
|
||||
assign_mapper( context, JobToOutputDatasetAssociation, JobToOutputDatasetAssociation.table,
|
||||
properties=dict( job=relation( Job ), dataset=relation( Dataset ) ) )
|
||||
properties=dict( job=relation( Job ), dataset=relation( HistoryDatasetAssociation ) ) )
|
||||
|
||||
assign_mapper( context, JobParameter, JobParameter.table )
|
||||
|
||||
@@ -310,7 +304,7 @@ assign_mapper( context, GalaxySessionToHistoryAssociation, GalaxySessionToHistor
|
||||
properties=dict( galaxy_session=relation( GalaxySession ),
|
||||
history=relation( History ) ) )
|
||||
|
||||
Dataset.mapper.add_property( "creating_job_associations", relation( JobToOutputDatasetAssociation ) )
|
||||
HistoryDatasetAssociation.mapper.add_property( "creating_job_associations", relation( JobToOutputDatasetAssociation ) )
|
||||
|
||||
assign_mapper( context, Workflow, Workflow.table,
|
||||
properties=dict( steps=relation( WorkflowStep, backref='workflow', order_by=asc(WorkflowStep.table.c.order_index), cascade="all, delete-orphan" ) ) )
|
||||
|
||||
@@ -16,7 +16,7 @@ class MappingTests( unittest.TestCase ):
|
||||
#h1.queries.append( model.Query( "h1->q2" ) )
|
||||
h2 = model.History( name=( "H" * 1024 ) )
|
||||
#q1 = model.Query( "h2->q1" )
|
||||
d1 = model.Dataset( metadata=dict(chromCol=1,startCol=2,endCol=3 ), history=h2 )
|
||||
d1 = model.HistoryDatasetAssociation( metadata=dict(chromCol=1,startCol=2,endCol=3 ), history=h2, create_dataset=True )
|
||||
#h2.queries.append( q1 )
|
||||
#h2.queries.append( model.Query( "h2->q2" ) )
|
||||
model.context.current.flush()
|
||||
|
||||
@@ -970,20 +970,15 @@ class Tool:
|
||||
for name, data in input_datasets.items():
|
||||
param_dict[name] = DatasetFilenameWrapper( data, datatypes_registry = self.app.datatypes_registry, tool = self, name = name )
|
||||
if data:
|
||||
for child_association in data.children:
|
||||
child = child_association.child
|
||||
key = "_CHILD___%s___%s" % ( name, child.designation )
|
||||
param_dict[ key ] = DatasetFilenameWrapper( child )
|
||||
for child in data.children:
|
||||
param_dict[ "_CHILD___%s___%s" % ( name, child.designation ) ] = DatasetFilenameWrapper( child )
|
||||
for name, data in output_datasets.items():
|
||||
param_dict[name] = DatasetFilenameWrapper( data )
|
||||
# Provide access to a path to store additional files
|
||||
# TODO: path munging for cluster/dataset server relocatability
|
||||
param_dict[name].files_path = os.path.abspath(os.path.join(self.app.config.new_file_path, "dataset_%s_files" % (data.id) ))
|
||||
|
||||
for child_association in data.children:
|
||||
child = child_association.child
|
||||
key = "_CHILD___%s___%s" % ( name, child.designation )
|
||||
param_dict[ key ] = DatasetFilenameWrapper( child )
|
||||
for child in data.children:
|
||||
param_dict[ "_CHILD___%s___%s" % ( name, child.designation ) ] = DatasetFilenameWrapper( child )
|
||||
# We add access to app here, this allows access to app.config, etc
|
||||
param_dict['__app__'] = RawObjectWrapper( self.app )
|
||||
# More convienent access to app.config.new_file_path; we don't need to wrap a string
|
||||
@@ -1092,25 +1087,24 @@ class Tool:
|
||||
if visible == "visible": visible = True
|
||||
else: visible = False
|
||||
ext = fields.pop(0).lower()
|
||||
# Create new child dataset
|
||||
child_data = self.app.model.Dataset(extension=ext, parent_id=parent_id, designation=designation, visible=visible, dbkey=outdata.dbkey)
|
||||
child_data.flush()
|
||||
child_dataset = self.app.model.HistoryDatasetAssociation( extension=ext, parent_id=outdata.id, designation=designation, visible=visible, dbkey=outdata.dbkey, create_dataset=True )
|
||||
# Move data from temp location to dataset location
|
||||
shutil.move(filename, child_data.file_name)
|
||||
child_data.name = "Secondary Dataset (%s)" % (designation)
|
||||
child_data.state = child_data.states.OK
|
||||
child_data.init_meta()
|
||||
child_data.set_meta()
|
||||
child_data.set_peek()
|
||||
child_data.set_size()
|
||||
child_data.flush()
|
||||
# Add to child accociation table
|
||||
assoc = self.app.model.DatasetChildAssociation()
|
||||
assoc.child = child_data
|
||||
assoc.designation = child_data.designation
|
||||
outdata.children.append( assoc )
|
||||
shutil.move( filename, child_dataset.file_name )
|
||||
child_dataset.flush()
|
||||
child_dataset.name = "Secondary Dataset (%s)" % ( designation )
|
||||
child_dataset.state = child_dataset.states.OK
|
||||
child_dataset.init_meta()
|
||||
child_dataset.set_meta()
|
||||
child_dataset.set_peek()
|
||||
child_dataset.set_size()
|
||||
child_dataset.flush()
|
||||
# Add child to return dict
|
||||
children[name][designation] = child_data
|
||||
children[name][designation] = child_dataset
|
||||
for dataset in outdata.dataset.history_associations: #need to update all associated output hdas, i.e. history was shared with job running
|
||||
if outdata == dataset: continue
|
||||
# Create new child dataset
|
||||
child_data = child_dataset.copy( parent_id = dataset.id )
|
||||
child_data.flush()
|
||||
return children
|
||||
|
||||
def collect_primary_datasets( self, output):
|
||||
@@ -1129,20 +1123,25 @@ class Tool:
|
||||
else: visible = False
|
||||
ext = fields.pop(0).lower()
|
||||
# Create new primary dataset
|
||||
primary_data = self.app.model.Dataset(extension=ext, designation=designation, visible=visible, dbkey=outdata.dbkey)
|
||||
primary_data = self.app.model.HistoryDatasetAssociation( extension=ext, designation=designation, visible=visible, dbkey=outdata.dbkey, create_dataset=True )
|
||||
primary_data.flush()
|
||||
self.app.model.History.get(outdata.history_id).add_dataset(primary_data)
|
||||
# Move data from temp location to dataset location
|
||||
shutil.move(filename, primary_data.file_name)
|
||||
primary_data.name = outdata.name
|
||||
primary_data.info = outdata.info
|
||||
shutil.move( filename, primary_data.file_name )
|
||||
primary_data.name = dataset.name
|
||||
primary_data.info = dataset.info
|
||||
primary_data.state = primary_data.states.OK
|
||||
primary_data.init_meta(copy_from=outdata)
|
||||
primary_data.init_meta( copy_from=dataset )
|
||||
primary_data.set_peek()
|
||||
primary_data.set_size()
|
||||
primary_data.flush()
|
||||
outdata.history.add_dataset( primary_data )
|
||||
# Add dataset to return dict
|
||||
primary_datasets[name][designation] = primary_data
|
||||
for dataset in outdata.dataset.history_associations: #need to update all associated output hdas, i.e. history was shared with job running
|
||||
if outdata == dataset: continue
|
||||
new_data = primary_data.copy()
|
||||
dataset.history.add( new_data )
|
||||
new_data.flush()
|
||||
return primary_datasets
|
||||
|
||||
|
||||
|
||||
@@ -30,17 +30,18 @@ class DefaultToolAction( object ):
|
||||
for target_ext in input.extensions:
|
||||
if target_ext in data.get_converter_types():
|
||||
data.refresh() #need to refresh incase this conversion just took place, i.e. input above in tool performed the same conversion
|
||||
assoc = data.get_associated_files_by_type( "CONVERTED_%s" % target_ext )
|
||||
if assoc: data = assoc[0].dataset
|
||||
datasets = data.get_converted_files_by_type( target_ext )
|
||||
if datasets: data = datasets[0]
|
||||
elif input.converter_safe( param_values, trans ):
|
||||
#run converter here
|
||||
assoc = trans.app.model.DatasetAssociatedFile( parent_id = data.id, file_type = "CONVERTED_%s" % target_ext, metadata_safe = False )
|
||||
assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = data, file_type = target_ext, metadata_safe = False )
|
||||
new_data = data.datatype.convert_dataset( trans, data, target_ext, return_output = True, visible = False ).values()[0]
|
||||
new_data.hid = data.hid
|
||||
new_data.name = data.name
|
||||
assoc.dataset_id = new_data.id
|
||||
new_data.flush()
|
||||
assoc.dataset = new_data
|
||||
assoc.flush()
|
||||
data = new_data
|
||||
data.flush()
|
||||
break
|
||||
return data
|
||||
if isinstance( input, DataToolParameter ):
|
||||
@@ -122,19 +123,20 @@ class DefaultToolAction( object ):
|
||||
## What is the following hack for? Need to document under what
|
||||
## conditions can the following occur? (james@bx.psu.edu)
|
||||
# HACK: the output data has already been created
|
||||
# this happens i.e. as a result of the async controller
|
||||
if name in incoming:
|
||||
dataid = incoming[name]
|
||||
data = trans.app.model.Dataset.get( dataid )
|
||||
data = trans.app.model.HistoryDatasetAssociation.get( dataid )
|
||||
assert data != None
|
||||
out_data[name] = data
|
||||
continue
|
||||
# the type should match the input
|
||||
ext = output.format
|
||||
if ext == "input":
|
||||
ext = input_ext
|
||||
data = trans.app.model.Dataset(extension=ext)
|
||||
# Commit the dataset immediately so it gets database assigned unique id
|
||||
data.flush()
|
||||
else:
|
||||
# the type should match the input
|
||||
ext = output.format
|
||||
if ext == "input":
|
||||
ext = input_ext
|
||||
data = trans.app.model.HistoryDatasetAssociation( extension=ext, create_dataset=True )
|
||||
# Commit the dataset immediately so it gets database assigned unique id
|
||||
data.flush()
|
||||
# Create an empty file immediately
|
||||
open( data.file_name, "w" ).close()
|
||||
# This may not be neccesary with the new parent/child associations
|
||||
@@ -167,7 +169,7 @@ class DefaultToolAction( object ):
|
||||
|
||||
# Add all the top-level (non-child) datasets to the history
|
||||
for name in out_data.keys():
|
||||
if name not in child_dataset_names:
|
||||
if name not in child_dataset_names and name not in incoming: #don't add children; or already existing datasets, i.e. async created
|
||||
data = out_data[ name ]
|
||||
trans.history.add_dataset( data, set_hid = set_output_hid )
|
||||
data.flush()
|
||||
@@ -176,11 +178,7 @@ class DefaultToolAction( object ):
|
||||
for parent_name, child_name in parent_to_child_pairs:
|
||||
parent_dataset = out_data[ parent_name ]
|
||||
child_dataset = out_data[ child_name ]
|
||||
assoc = trans.app.model.DatasetChildAssociation()
|
||||
assoc.child = child_dataset
|
||||
assoc.designation = child_dataset.designation
|
||||
parent_dataset.children.append( assoc )
|
||||
# FIXME: Child dataset hid
|
||||
parent_dataset.children.append( child_dataset )
|
||||
|
||||
# Store data after custom code runs
|
||||
trans.app.model.flush()
|
||||
|
||||
@@ -65,7 +65,7 @@ class UploadToolAction( object ):
|
||||
return dict( output=data_list[0] )
|
||||
|
||||
def upload_empty(self, trans, err_code, err_msg):
|
||||
data = trans.app.model.Dataset()
|
||||
data = trans.app.model.HistoryDatasetAssociation( create_dataset = True )
|
||||
data.name = err_code
|
||||
data.extension = "txt"
|
||||
data.dbkey = "?"
|
||||
@@ -158,13 +158,12 @@ class UploadToolAction( object ):
|
||||
if info is None:
|
||||
info = 'uploaded %s file' %data_type
|
||||
|
||||
data = trans.app.model.Dataset()
|
||||
data = trans.app.model.HistoryDatasetAssociation( history = trans.history, extension = ext, create_dataset = True )
|
||||
data.name = file_name
|
||||
data.extension = ext
|
||||
data.dbkey = dbkey
|
||||
data.info = info
|
||||
data.flush()
|
||||
shutil.move(temp_name, data.file_name)
|
||||
shutil.move( temp_name, data.file_name )
|
||||
data.state = data.states.OK
|
||||
data.init_meta()
|
||||
if self.line_count is not None:
|
||||
|
||||
@@ -636,11 +636,11 @@ class ColumnListParameter( SelectToolParameter ):
|
||||
# from a twill perspective...
|
||||
|
||||
>>> # Mock up a history (not connected to database)
|
||||
>>> from galaxy.model import History, Dataset
|
||||
>>> from galaxy.model import History, HistoryDatasetAssociation
|
||||
>>> from galaxy.util.bunch import Bunch
|
||||
>>> hist = History()
|
||||
>>> hist.flush()
|
||||
>>> hist.add_dataset( Dataset( id=1, extension='interval' ) )
|
||||
>>> hist.add_dataset( HistoryDatasetAssociation( id=1, extension='interval', create_dataset=True ) )
|
||||
>>> dtp = DataToolParameter( None, XML( '<param name="blah" type="data" format="interval"/>' ) )
|
||||
>>> print dtp.name
|
||||
blah
|
||||
@@ -979,15 +979,15 @@ class DataToolParameter( ToolParameter ):
|
||||
displayed as radio buttons and multiple selects as a set of checkboxes
|
||||
|
||||
>>> # Mock up a history (not connected to database)
|
||||
>>> from galaxy.model import History, Dataset
|
||||
>>> from galaxy.model import History, HistoryDatasetAssociation
|
||||
>>> from galaxy.util.bunch import Bunch
|
||||
>>> hist = History()
|
||||
>>> hist.flush()
|
||||
>>> hist.add_dataset( Dataset( id=1, extension='txt' ) )
|
||||
>>> hist.add_dataset( Dataset( id=2, extension='bed' ) )
|
||||
>>> hist.add_dataset( Dataset( id=3, extension='fasta' ) )
|
||||
>>> hist.add_dataset( Dataset( id=4, extension='png' ) )
|
||||
>>> hist.add_dataset( Dataset( id=5, extension='interval' ) )
|
||||
>>> hist.add_dataset( HistoryDatasetAssociation( id=1, extension='txt', create_dataset=True ) )
|
||||
>>> hist.add_dataset( HistoryDatasetAssociation( id=2, extension='bed', create_dataset=True ) )
|
||||
>>> hist.add_dataset( HistoryDatasetAssociation( id=3, extension='fasta', create_dataset=True ) )
|
||||
>>> hist.add_dataset( HistoryDatasetAssociation( id=4, extension='png', create_dataset=True ) )
|
||||
>>> hist.add_dataset( HistoryDatasetAssociation( id=5, extension='interval', create_dataset=True ) )
|
||||
>>> p = DataToolParameter( None, XML( '<param name="blah" type="data" format="interval"/>' ) )
|
||||
>>> print p.name
|
||||
blah
|
||||
@@ -1056,16 +1056,16 @@ class DataToolParameter( ToolParameter ):
|
||||
else:
|
||||
for target_ext in self.extensions:
|
||||
if target_ext in data.get_converter_types():
|
||||
assoc = data.get_associated_files_by_type( "CONVERTED_%s" % target_ext )
|
||||
if assoc:
|
||||
data = assoc[0].dataset
|
||||
datasets = data.get_converted_files_by_type( target_ext )
|
||||
if datasets:
|
||||
data = datasets[0]
|
||||
elif not self.converter_safe( other_values, trans ):
|
||||
continue
|
||||
selected = ( value and ( data in value ) )
|
||||
field.add_option( "%s: (as %s) %s" % ( hid, target_ext, data.name[:30] ), data.id, selected )
|
||||
break #we only report the first valid converter, assume self.extensions is a priority list
|
||||
# Also collect children via association object
|
||||
dataset_collector( [ assoc.child for assoc in data.children ], hid )
|
||||
dataset_collector( data.children, hid )
|
||||
dataset_collector( history.datasets, None )
|
||||
some_data = bool( field.options )
|
||||
if some_data:
|
||||
@@ -1116,7 +1116,7 @@ class DataToolParameter( ToolParameter ):
|
||||
continue
|
||||
most_recent_dataset[0] = data
|
||||
# Also collect children via association object
|
||||
dataset_collector( [ assoc.child for assoc in data.children ] )
|
||||
dataset_collector( data.children )
|
||||
dataset_collector( history.datasets )
|
||||
most_recent_dataset = most_recent_dataset.pop()
|
||||
if most_recent_dataset is not None:
|
||||
@@ -1133,11 +1133,11 @@ class DataToolParameter( ToolParameter ):
|
||||
if value in [None, "None"]:
|
||||
return None
|
||||
if isinstance( value, list ):
|
||||
return [ trans.app.model.Dataset.get( v ) for v in value ]
|
||||
elif isinstance( value, trans.app.model.Dataset ):
|
||||
return [ trans.app.model.HistoryDatasetAssociation.get( v ) for v in value ]
|
||||
elif isinstance( value, trans.app.model.HistoryDatasetAssociation ):
|
||||
return value
|
||||
else:
|
||||
return trans.app.model.Dataset.get( value )
|
||||
return trans.app.model.HistoryDatasetAssociation.get( value )
|
||||
|
||||
def value_to_basic( self, value, app ):
|
||||
if value is None or isinstance( value, str ):
|
||||
@@ -1152,7 +1152,7 @@ class DataToolParameter( ToolParameter ):
|
||||
if value is None or value == '' or value == 'None':
|
||||
return value
|
||||
try:
|
||||
return app.model.Dataset.get( int( value ) )
|
||||
return app.model.HistoryDatasetAssociation.get( int( value ) )
|
||||
except:
|
||||
if ignore_errors:
|
||||
return value
|
||||
@@ -1221,7 +1221,7 @@ class DataToolParameter( ToolParameter ):
|
||||
# have the history accessable at the job level, it is necessary
|
||||
# I also probably wrote this docstring test thing wrong.
|
||||
#
|
||||
# >>> from galaxy.model import History, Dataset
|
||||
# >>> from galaxy.model import History
|
||||
# >>> from galaxy.util.bunch import Bunch
|
||||
# >>> hist = History( id=1 )
|
||||
# >>> p = HistoryIDParameter( None, XML( '<param name="blah" type="history"/>' ) )
|
||||
|
||||
@@ -104,7 +104,7 @@ class DataMetaFilter( Filter ):
|
||||
return file_value == dataset_value
|
||||
assert self.ref_name in other_values or trans.workflow_building_mode, "Required dependency '%s' not found in incoming values" % self.ref_name
|
||||
ref = other_values.get( self.ref_name, None )
|
||||
if not isinstance( ref, self.dynamic_option.tool_param.tool.app.model.Dataset ):
|
||||
if not isinstance( ref, self.dynamic_option.tool_param.tool.app.model.HistoryDatasetAssociation ):
|
||||
return [] #not a valid dataset
|
||||
meta_value = ref.metadata.get( self.key, None )
|
||||
assert meta_value is not None, "Required metadata value '%s' not found in referenced dataset" % self.key
|
||||
|
||||
@@ -52,7 +52,7 @@ class ASync( BaseController ):
|
||||
if data_id:
|
||||
if not URL:
|
||||
return "No URL parameter was submitted for data %s" % data_id
|
||||
data = trans.model.Dataset.get( data_id )
|
||||
data = trans.model.HistoryDatasetAssociation.get( data_id )
|
||||
|
||||
if not data:
|
||||
return "Data %s does not exist or has already been deleted" % data_id
|
||||
@@ -67,7 +67,8 @@ class ASync( BaseController ):
|
||||
trans.log_event( 'Async executing tool %s' % tool.id, tool_id=tool.id )
|
||||
galaxy_url = trans.request.base + '/async/%s/%s/%s' % ( tool_id, data.id, key )
|
||||
galaxy_url = params.get("GALAXY_URL",galaxy_url)
|
||||
params = dict(url=URL, dataid=data.id, output=data.file_name, GALAXY_URL=galaxy_url)
|
||||
params = dict( url=URL, GALAXY_URL=galaxy_url )
|
||||
params[tool.outputs.keys()[0]] = data.id #assume there is exactly one output file possible
|
||||
#tool.execute( app=self.app, history=history, incoming=params )
|
||||
tool.execute( trans, incoming=params )
|
||||
else:
|
||||
@@ -101,14 +102,14 @@ class ASync( BaseController ):
|
||||
#data.dbkey = GALAXY_BUILD
|
||||
#data.state = jobs.JOB_OK
|
||||
#history.datasets.add_dataset( data )
|
||||
|
||||
data = trans.app.model.Dataset()
|
||||
|
||||
data = trans.app.model.HistoryDatasetAssociation( create_dataset = True, extension = GALAXY_TYPE )
|
||||
data.name = GALAXY_NAME
|
||||
data.extension = GALAXY_TYPE
|
||||
data.dbkey = GALAXY_BUILD
|
||||
data.info = GALAXY_INFO
|
||||
data.state = data.states.NEW
|
||||
data.flush()
|
||||
open( data.file_name, 'wb' ).close() #create the file
|
||||
trans.history.add_dataset( data, genome_build=GALAXY_BUILD )
|
||||
trans.model.flush()
|
||||
trans.log_event( "Added dataset %d to history %d" %(data.id, trans.history.id ), tool_id=tool_id )
|
||||
|
||||
@@ -47,12 +47,12 @@ class DatasetInterface( BaseController ):
|
||||
|
||||
@web.expose
|
||||
def errors( self, trans, id ):
|
||||
dataset = model.Dataset.get( id )
|
||||
dataset = model.HistoryDatasetAssociation.get( id )
|
||||
return trans.fill_template( "dataset/errors.tmpl", dataset=dataset )
|
||||
|
||||
@web.expose
|
||||
def stderr( self, trans, id ):
|
||||
dataset = model.Dataset.get( id )
|
||||
dataset = model.HistoryDatasetAssociation.get( id )
|
||||
job = dataset.creating_job_associations[0].job
|
||||
trans.response.set_content_type( 'text/plain' )
|
||||
return job.stderr
|
||||
@@ -66,7 +66,7 @@ class DatasetInterface( BaseController ):
|
||||
if to_address is None:
|
||||
return trans.show_error_message( "Sorry, error reporting has been disabled for this galaxy instance" )
|
||||
# Get the dataset and associated job
|
||||
dataset = model.Dataset.get( id )
|
||||
dataset = model.HistoryDatasetAssociation.get( id )
|
||||
job = dataset.creating_job_associations[0].job
|
||||
# Build the email message
|
||||
msg = MIMEText( string.Template( error_report_template )
|
||||
@@ -105,7 +105,7 @@ class DatasetInterface( BaseController ):
|
||||
"""Catches the dataset id and displays file contents as directed"""
|
||||
if filename is None or filename.lower() == "index":
|
||||
try:
|
||||
data = trans.app.model.Dataset.get( dataset_id )
|
||||
data = trans.app.model.HistoryDatasetAssociation.get( dataset_id )
|
||||
if data:
|
||||
mime = trans.app.datatypes_registry.get_mimetype_by_extension( data.extension.lower() )
|
||||
trans.response.set_content_type(mime)
|
||||
@@ -120,7 +120,7 @@ class DatasetInterface( BaseController ):
|
||||
else:
|
||||
#display files from directory here
|
||||
try:
|
||||
file_path = os.path.join(trans.app.model.Dataset.get( dataset_id ).extra_files_path, filename)
|
||||
file_path = os.path.join(trans.app.model.HistoryDatasetAssociation.get( dataset_id ).extra_files_path, filename)
|
||||
mime, encoding = mimetypes.guess_type(file_path)
|
||||
if mime is None:
|
||||
mime = trans.app.datatypes_registry.get_mimetype_by_extension(".".split(file_path)[-1])
|
||||
|
||||
@@ -67,7 +67,7 @@ class RootController( BaseController ):
|
||||
def dataset_state ( self, trans, id=None, stamp=None ):
|
||||
if id is not None:
|
||||
try:
|
||||
data = self.app.model.Dataset.get( id )
|
||||
data = self.app.model.HistoryDatasetAssociation.get( id )
|
||||
except:
|
||||
return trans.show_error_message( "Unable to check dataset %s." %str( id ) )
|
||||
trans.response.headers['X-Dataset-State'] = data.state
|
||||
@@ -81,7 +81,7 @@ class RootController( BaseController ):
|
||||
def dataset_code( self, trans, id=None, hid=None, stamp=None ):
|
||||
if id is not None:
|
||||
try:
|
||||
data = self.app.model.Dataset.get( id )
|
||||
data = self.app.model.HistoryDatasetAssociation.get( id )
|
||||
except:
|
||||
return trans.show_error_message( "Unable to check dataset %s." %str( id ) )
|
||||
trans.response.headers['Pragma'] = 'no-cache'
|
||||
@@ -101,7 +101,7 @@ class RootController( BaseController ):
|
||||
ids = map( int, ids.split( "," ) )
|
||||
states = states.split( "," )
|
||||
for id, state in zip( ids, states ):
|
||||
data = self.app.model.Dataset.get( id )
|
||||
data = self.app.model.HistoryDatasetAssociation.get( id )
|
||||
if data.state != state:
|
||||
rval[id] = {
|
||||
"state": data.state,
|
||||
@@ -131,7 +131,7 @@ class RootController( BaseController ):
|
||||
raise Exception( "No dataset with hid '%d'" % hid )
|
||||
else:
|
||||
try:
|
||||
data = self.app.model.Dataset.get( id )
|
||||
data = self.app.model.HistoryDatasetAssociation.get( id )
|
||||
except:
|
||||
return "Dataset id '%s' is invalid" %str( id )
|
||||
if data:
|
||||
@@ -160,7 +160,7 @@ class RootController( BaseController ):
|
||||
Returns child data directly into the browser, based upon parent_id and designation.
|
||||
"""
|
||||
try:
|
||||
data = self.app.model.Dataset.get( parent_id )
|
||||
data = self.app.model.HistoryDatasetAssociation.get( parent_id )
|
||||
if data:
|
||||
child = data.get_child_by_designation(designation)
|
||||
if child:
|
||||
@@ -172,7 +172,7 @@ class RootController( BaseController ):
|
||||
@web.expose
|
||||
def display_as( self, trans, id=None, display_app=None, **kwd ):
|
||||
"""Returns a file in a format that can successfully be displayed in display_app"""
|
||||
data = self.app.model.Dataset.get( id )
|
||||
data = self.app.model.HistoryDatasetAssociation.get( id )
|
||||
if data:
|
||||
trans.response.set_content_type(data.get_mime())
|
||||
trans.log_event( "Formatted dataset id %s for display at %s" % ( str(id), display_app ) )
|
||||
@@ -183,7 +183,7 @@ class RootController( BaseController ):
|
||||
@web.expose
|
||||
def peek(self, trans, id=None):
|
||||
"""Returns a 'peek' at the data"""
|
||||
data = self.app.model.Dataset.get( id )
|
||||
data = self.app.model.HistoryDatasetAssociation.get( id )
|
||||
if data:
|
||||
yield "<html><body><pre>"
|
||||
yield data.peek
|
||||
@@ -201,7 +201,7 @@ class RootController( BaseController ):
|
||||
elif id is None:
|
||||
return trans.show_error_message( "Problem loading dataset id %s with history id %s." % ( str( id ), str( hid ) ) )
|
||||
else:
|
||||
data = self.app.model.Dataset.get( id )
|
||||
data = self.app.model.HistoryDatasetAssociation.get( id )
|
||||
if data is None:
|
||||
return trans.show_error_message( "Problem retrieving dataset id %s with history id %s." % ( str( id ), str( hid ) ) )
|
||||
|
||||
@@ -281,15 +281,12 @@ class RootController( BaseController ):
|
||||
int( id )
|
||||
except:
|
||||
continue
|
||||
data = self.app.model.Dataset.get( id )
|
||||
data = self.app.model.HistoryDatasetAssociation.get( id )
|
||||
if data:
|
||||
# Walk up parent datasets to find the containing history
|
||||
topmost_parent = data
|
||||
while topmost_parent.parent:
|
||||
# data.parent is a list of associations, data.parent.parent
|
||||
# is the actual dataset
|
||||
assert len( data.parent ) == 1, "Dataset should only have one parent"
|
||||
topmost_parent = data.parent[0].parent
|
||||
topmost_parent = topmost_parent.parent
|
||||
assert topmost_parent in history.datasets, "Data does not belong to current history"
|
||||
# Mark deleted and cleanup
|
||||
data.mark_deleted()
|
||||
@@ -311,15 +308,12 @@ class RootController( BaseController ):
|
||||
except:
|
||||
return "Dataset id '%s' is invalid" %str( id )
|
||||
history = trans.get_history()
|
||||
data = self.app.model.Dataset.get( id )
|
||||
data = self.app.model.HistoryDatasetAssociation.get( id )
|
||||
if data:
|
||||
# Walk up parent datasets to find the containing history
|
||||
topmost_parent = data
|
||||
while topmost_parent.parent:
|
||||
# data.parent is a list of associations, data.parent.parent
|
||||
# is the actual dataset
|
||||
assert len( data.parent ) == 1, "Dataset should only have one parent"
|
||||
topmost_parent = data.parent[0].parent
|
||||
topmost_parent = topmost_parent.parent
|
||||
assert topmost_parent in history.datasets, "Data does not belong to current history"
|
||||
# Mark deleted and cleanup
|
||||
data.mark_deleted()
|
||||
@@ -556,7 +550,7 @@ class RootController( BaseController ):
|
||||
"""Adds a POSTed file to a History"""
|
||||
try:
|
||||
history = trans.app.model.History.get( history_id )
|
||||
data = trans.app.model.Dataset( name = name, info = info, extension = ext, dbkey = dbkey )
|
||||
data = trans.app.model.HistoryDatasetAssociation( name = name, info = info, extension = ext, dbkey = dbkey, create_file = True )
|
||||
data.flush()
|
||||
data_file = open( data.file_name, "wb" )
|
||||
file_data.file.seek( 0 )
|
||||
@@ -580,7 +574,7 @@ class RootController( BaseController ):
|
||||
def dataset_make_primary( self, trans, id=None):
|
||||
"""Copies a dataset and makes primary"""
|
||||
try:
|
||||
old_data = self.app.model.Dataset.get( id )
|
||||
old_data = self.app.model.HistoryDatasetAssociation.get( id )
|
||||
new_data = old_data.copy()
|
||||
## new_data.parent = None
|
||||
## history = trans.app.model.History.get( old_data.history_id )
|
||||
@@ -606,7 +600,7 @@ class RootController( BaseController ):
|
||||
@web.expose
|
||||
def dataset_errors( self, trans, id=None, **kwd ):
|
||||
"""View/fix errors associated with dataset"""
|
||||
data = trans.app.model.Dataset.get( id )
|
||||
data = trans.app.model.HistoryDatasetAssociation.get( id )
|
||||
p = kwd
|
||||
if p.get("fix_errors", None):
|
||||
# launch tool to create new, (hopefully) error free dataset
|
||||
|
||||
@@ -263,16 +263,24 @@ def purge_dataset( dataset ):
|
||||
return "# Dataset for deletion ( id %s ) points to a file on disk being shared by another user's history ( dataset id %s )\n" %( str( dataset.id ), str( data.id ) )
|
||||
elif dataset.deleted:
|
||||
# Remove files from disk and update the database
|
||||
purgable = False
|
||||
try:
|
||||
os.unlink( dataset.file_name )
|
||||
dataset.purged = True
|
||||
dataset.file_size = 0
|
||||
dataset.clear_associated_files( purge = True )
|
||||
dataset.flush()
|
||||
if dataset.dataset.purgable:
|
||||
for shared_data in dataset.dataset.history_associations:
|
||||
if not shared_data.purged:
|
||||
break #only purge when not shared
|
||||
else:
|
||||
os.unlink( dataset.file_name )
|
||||
purgable = True
|
||||
except Exception, exc:
|
||||
return "# Error, exception: %s caught attempting to purge %s\n" %( str( exc ), dataset.file_name )
|
||||
try:
|
||||
os.unlink( dataset.extra_files_path )
|
||||
if purgable:
|
||||
os.unlink( dataset.extra_files_path )
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
|
||||
@@ -83,9 +83,9 @@
|
||||
## be a 'visible_children' method on dataset.
|
||||
<%
|
||||
children = []
|
||||
for child_assoc in data.children:
|
||||
if child_assoc.child.visible:
|
||||
children.append( child_assoc.child )
|
||||
for child in data.children:
|
||||
if child.visible:
|
||||
children.append( child )
|
||||
%>
|
||||
%if len( children ) > 0:
|
||||
<div>
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
</inputs>
|
||||
|
||||
<uihints minwidth="800"/>
|
||||
|
||||
<code file="encodedb_filter.py"/>
|
||||
|
||||
<outputs>
|
||||
<data format="bed" name="output" />
|
||||
</outputs>
|
||||
|
||||
<options sanitize="False" refresh="True"/>
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr
|
||||
dbkey = fields[2]
|
||||
filepath = fields[3]
|
||||
file_type = fields[4]
|
||||
newdata = app.model.Dataset()
|
||||
newdata = app.model.HistoryDatasetAssociation( create_dataset = True ) #This import should become a library
|
||||
newdata.extension = file_type
|
||||
newdata.name = basic_name + " (" + description + ")"
|
||||
history.add_dataset( newdata )
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# runs after the job (and after the default post-filter)
|
||||
|
||||
def validate(incoming):
|
||||
"""Validator"""
|
||||
#raise Exception, 'not quite right'
|
||||
pass
|
||||
|
||||
def exec_before_job( app, inp_data, out_data, param_dict, tool=None):
|
||||
"""Sets the name of the data"""
|
||||
dataid = param_dict.get( 'dataid', None )
|
||||
data = app.model.Dataset.get( dataid )
|
||||
if data:
|
||||
data.info = data.states.RUNNING
|
||||
data.flush()
|
||||
|
||||
def exec_after_process( app, inp_data, out_data, param_dict, **kwd):
|
||||
"""Sets the name of the data"""
|
||||
dataid = param_dict.get( 'dataid', None )
|
||||
data = app.model.Dataset.get(dataid)
|
||||
if data:
|
||||
data.state = data.states.OK
|
||||
data.set_peek()
|
||||
data.set_size()
|
||||
data.flush()
|
||||
@@ -124,7 +124,7 @@ def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr
|
||||
dbkey = fields[3]
|
||||
filepath = fields[4]
|
||||
file_type = fields[5]
|
||||
newdata = app.model.Dataset()
|
||||
newdata = app.model.HistoryDatasetAssociation( create_dataset = True ) #This import should become a library
|
||||
newdata.extension = file_type
|
||||
newdata.name = basic_name + " (" + microbe_info[kingdom][org]['chrs'][chr]['data'][description]['feature'] +" for "+microbe_info[kingdom][org]['name']+":"+chr + ")"
|
||||
newdata.flush()
|
||||
|
||||
@@ -28,7 +28,7 @@ def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr
|
||||
dbkey = fields[1]
|
||||
filepath = fields[2]
|
||||
|
||||
newdata = app.model.Dataset()
|
||||
newdata = app.model.HistoryDatasetAssociation( create_dataset = True )
|
||||
newdata.extension = "bed"
|
||||
newdata.name = basic_name + " (" + dbkey + ")"
|
||||
newdata.flush()
|
||||
|
||||
Reference in New Issue
Block a user