LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
registries.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 #
4 # LSST Data Management System
5 # Copyright 2008, 2009, 2010 LSST Corporation.
6 #
7 # This product includes software developed by the
8 # LSST Project (http://www.lsst.org/).
9 #
10 # This program is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation, either version 3 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the LSST License Statement and
21 # the GNU General Public License along with this program. If not,
22 # see <http://www.lsstcorp.org/LegalNotices/>.
23 #
24 
25 """This module provides registry classes for maintaining dataset metadata for
26 use by the Data Butler. Currently only a SQLite3-based registry is
27 implemented, but registries based on a text file, a policy file, a MySQL (or
28 other) relational database, and data gathered from scanning a filesystem are
29 all anticipated."""
30 
31 # import glob
32 import os
33 import re
34 try:
35  import sqlite3
36  haveSqlite3 = True
37 except ImportError:
38  try:
39  # try external pysqlite package; deprecated
40  import sqlite as sqlite3
41  haveSqlite3 = True
42  except ImportError:
43  haveSqlite3 = False
44 
45 class Registry(object):
46  """The registry base class."""
47 
48  def __init__(self):
49  pass
50 
51  @staticmethod
52  def create(location):
53  """Create a registry object of an appropriate type.
54  @param location (string) Path or URL for registry, or None if
55  unavailable"""
56 
57  # if re.match(r'.*\.registry', location):
58  # return FileRegistry(location)
59  # if re.match(r'.*\.paf', location):
60  # return CalibRegistry(location)
61  if haveSqlite3 and re.match(r'.*\.sqlite3', location):
62  registry = SqliteRegistry(location)
63  if registry.conn is None:
64  return None
65  return registry
66  # if re.match(r'mysql:', location):
67  # return DbRegistry(location)
68  # return FsRegistry(location)
69  raise RuntimeError, \
70  "Unable to create registry using location: " + location
71 
72  # TODO - flesh out the generic interface as more registry types are
73  # defined.
74 
76  """A SQLite3-based registry."""
77 
78  def __init__(self, location):
79  """Constructor.
80  @param location (string) Path to SQLite3 file"""
81 
82  Registry.__init__(self)
83  if os.path.exists(location):
84  self.conn = sqlite3.connect(location)
85  self.conn.text_factory = str
86  else:
87  self.conn = None
88 
89  def executeQuery(self, returnFields, joinClause, whereFields, range,
90  values):
91  """Extract metadata from the registry.
92  @param returnFields (list of strings) Metadata fields to be extracted.
93  @param joinClause (list of strings) Tables in which metadata fields
94  are located.
95  @param whereFields (list of tuples) First tuple element is metadata
96  field to query; second is the value that field
97  must have (often '?').
98  @param range (tuple) Value, lower limit, and upper limit for a
99  range condition on the metadata. Any of these can
100  be metadata fields.
101  @param values (tuple) Tuple of values to be substituted for '?'
102  characters in the whereFields values or the range
103  values.
104  @return (list of tuples) All sets of field values that meet the
105  criteria"""
106 
107  if not self.conn:
108  return None
109  cmd = "SELECT DISTINCT "
110  cmd += ", ".join(returnFields)
111  cmd += " FROM " + " NATURAL JOIN ".join(joinClause)
112  whereList = []
113  if whereFields:
114  for k, v in whereFields:
115  whereList.append("(%s = %s)" % (k, v))
116  if range is not None:
117  whereList.append("(%s BETWEEN %s AND %s)" % range)
118  if len(whereList) > 0:
119  cmd += " WHERE " + " AND ".join(whereList)
120  c = self.conn.execute(cmd, values)
121  result = []
122  for row in c:
123  result.append(row)
124  return result