Copyright Messages Cleanup
[optf/has.git] / conductor / conductor / common / music / model / search.py
1 #
2 # -------------------------------------------------------------------------
3 #   Copyright (c) 2015-2017 AT&T Intellectual Property
4 #
5 #   Licensed under the Apache License, Version 2.0 (the "License");
6 #   you may not use this file except in compliance with the License.
7 #   You may obtain a copy of the License at
8 #
9 #       http://www.apache.org/licenses/LICENSE-2.0
10 #
11 #   Unless required by applicable law or agreed to in writing, software
12 #   distributed under the License is distributed on an "AS IS" BASIS,
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 #   See the License for the specific language governing permissions and
15 #   limitations under the License.
16 #
17 # -------------------------------------------------------------------------
18 #
19
20 """Music ORM - Search"""
21
22 import inspect
23
24 from oslo_config import cfg
25 from oslo_log import log as logging
26
27 from conductor.common.music import api
28
29 # FIXME(jdandrea): Keep for the __init__
30 # from conductor.common.classes import get_class
31
32 LOG = logging.getLogger(__name__)
33
34 CONF = cfg.CONF
35
36
37 class Query(object):
38     """Data Query"""
39     model = None
40
41     def __init__(self, model):
42         """Initializer"""
43         if inspect.isclass(model):
44             self.model = model
45         # FIXME(jdandrea): Bring this back so it's path-agnostic.
46         # elif isinstance(model, basestring):
47         #     self.model = get_class('conductor_api.models.' + model)
48         assert inspect.isclass(self.model)
49
50     def __kwargs(self):
51         """Return common keyword args"""
52         kwargs = {
53             'keyspace': self.model.__keyspace__,
54             'table': self.model.__tablename__,  # pylint: disable=E1101
55         }
56         return kwargs
57
58     def __rows_to_objects(self, rows):
59         """Convert query response rows to objects"""
60         results = []
61         pk_name = self.model.pk_name()  # pylint: disable=E1101
62         for row_id, row in rows.items():  # pylint: disable=W0612
63             the_id = row.pop(pk_name)
64             result = self.model(_insert=False, **row)
65             setattr(result, pk_name, the_id)
66             results.append(result)
67         return Results(results)
68
69     def one(self, pk_value):
70         """Return object with pk_name matching pk_value"""
71         pk_name = self.model.pk_name()
72         kwargs = self.__kwargs()
73         rows = api.MUSIC_API.row_read(
74             pk_name=pk_name, pk_value=pk_value, **kwargs)
75         return self.__rows_to_objects(rows).first()
76
77     def all(self):
78         """Return all objects"""
79         kwargs = self.__kwargs()
80         rows = api.MUSIC_API.row_read(**kwargs)
81         return self.__rows_to_objects(rows)
82
83     def filter_by(self, **kwargs):
84         """Filter objects"""
85         # Music doesn't allow filtering on anything but the primary key.
86         # We need to get all items and then go looking for what we want.
87         all_items = self.all()
88         filtered_items = Results([])
89
90         # For every candidate ...
91         for item in all_items:
92             passes = True
93             # All filters are AND-ed.
94             for key, value in kwargs.items():
95                 if getattr(item, key) != value:
96                     passes = False
97                     break
98             if passes:
99                 filtered_items.append(item)
100         return filtered_items
101
102     def first(self):
103         """Return first object"""
104         return self.all().first()
105
106
107 class Results(list):
108     """Query results"""
109
110     def __init__(self, *args, **kwargs):  # pylint: disable=W0613
111         """Initializer"""
112         super(Results, self).__init__(args[0])
113
114     def all(self):
115         """Return all"""
116         return self
117
118     def first(self):
119         """Return first"""
120         if len(self) > 0:
121             return self[0]