From 834a586d3f07f16bff06a20c81199bc4aa3e7957 Mon Sep 17 00:00:00 2001 From: Ira Cooke Date: Mon, 7 Jul 2014 11:16:09 +1000 Subject: [PATCH] Add sqlite datatype and corresponding dataprovider --- datatypes_conf.xml.sample | 2 + lib/galaxy/datatypes/binary.py | 43 +++++++++++++++++++ lib/galaxy/datatypes/dataproviders/dataset.py | 27 ++++++++++++ 3 files changed, 72 insertions(+) diff --git a/datatypes_conf.xml.sample b/datatypes_conf.xml.sample index 4ff7d638a21..e2c845278d7 100644 --- a/datatypes_conf.xml.sample +++ b/datatypes_conf.xml.sample @@ -177,6 +177,7 @@ + @@ -262,6 +263,7 @@ --> + diff --git a/lib/galaxy/datatypes/binary.py b/lib/galaxy/datatypes/binary.py index a6aa0e1ec03..b6b7dbca433 100644 --- a/lib/galaxy/datatypes/binary.py +++ b/lib/galaxy/datatypes/binary.py @@ -12,6 +12,7 @@ import struct import subprocess import tempfile import zipfile +import sqlite3 from urllib import urlencode, quote_plus from galaxy import eggs @@ -545,3 +546,45 @@ class TwoBit (Binary): return "Binary TwoBit format nucleotide file (%s)" % (data.nice_size(dataset.get_size())) Binary.register_sniffable_binary_format("twobit", "twobit", TwoBit) + + +@dataproviders.decorators.has_dataproviders +class SQlite ( Binary ): + file_ext = "sqlite" + + # Connects and runs a query that should work on any real database + # If the file is not sqlite, an exception will be thrown and the sniffer will return false + def sniff( self, filename ): + try: + conn = sqlite3.connect(filename) + schema_version=conn.cursor().execute("pragma schema_version").fetchone() + conn.close() + if schema_version is not None: + return True + return False + except: + return False + + def set_peek( self, dataset, is_multi_byte=False ): + if not dataset.dataset.purged: + dataset.peek = "SQLite Database" + dataset.blurb = data.nice_size( dataset.get_size() ) + else: + dataset.peek = 'file does not exist' + dataset.blurb = 'file purged from disk' + + def display_peek( self, dataset ): + try: + return dataset.peek + except: + return "SQLite Database (%s)" % ( data.nice_size( dataset.get_size() ) ) + + + @dataproviders.decorators.dataprovider_factory( 'sqlite', dataproviders.dataset.SQliteDataProvider.settings ) + def sqlite_dataprovider( self, dataset, **settings ): + dataset_source = dataproviders.dataset.DatasetDataProvider( dataset ) + return dataproviders.dataset.SQliteDataProvider( dataset_source, **settings ) + + +Binary.register_sniffable_binary_format("sqlite","sqlite",SQlite) + diff --git a/lib/galaxy/datatypes/dataproviders/dataset.py b/lib/galaxy/datatypes/dataproviders/dataset.py index 88dab3c102a..cb5c38fd2f3 100644 --- a/lib/galaxy/datatypes/dataproviders/dataset.py +++ b/lib/galaxy/datatypes/dataproviders/dataset.py @@ -11,6 +11,7 @@ import base import line import column import external +import sqlite3 from galaxy import eggs eggs.require( 'bx-python' ) @@ -700,3 +701,29 @@ class BGzipTabixDataProvider( base.DataProvider ): #TODO: as samtools - need more info on output format raise NotImplementedError() super( BGzipTabixDataProvider, self ).__init__( dataset, **kwargs ) + + + +class SQliteDataProvider ( base.DataProvider ): + """ + Data provider that uses a sqlite database file as its source. + + Allows any query to be run and returns the resulting rows as sqlite3 row objects + """ + settings = { + 'query' : 'str' + } + + def __init__( self, source, query=None, **kwargs ): + self.query=query + self.connection = sqlite3.connect(source.dataset.file_name); + self.connection.row_factory = sqlite3.Row + super( SQliteDataProvider, self ).__init__( source, **kwargs ) + + def __iter__( self ): + if self.query is not None: + for row in self.connection.cursor().execute(self.query): + yield row + else: + yield +