~drizzle-trunk/drizzle/development

971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
19
20
#ifndef DRIZZLED_REGISTRY_H
21
#define DRIZZLED_REGISTRY_H
22
23
#include <map>
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
24
#include <set>
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
25
#include <string>
1022.2.37 by Monty Taylor
Moved more tolower calls to setup rather than during runtime.
26
#include <functional>
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
27
28
namespace drizzled {
29
1022.2.37 by Monty Taylor
Moved more tolower calls to setup rather than during runtime.
30
namespace internal {
31
32
template<class T>
33
struct RegistryMapCompare
34
{
35
  bool operator() (const T& a, const T& b) const
36
  {
37
    return a.getName() < b.getName();
38
  }
39
};
40
41
template<class T>
42
struct RegistryMapCompare<T *>
43
{
44
  bool operator() (const T* a, const T* b) const
45
  {
46
    return a->getName() < b->getName();
47
  }
48
};
49
50
} /* namespace internal */
51
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
52
template<class T>
53
class Registry
54
{
55
  std::map<std::string, T> item_map;
1022.2.37 by Monty Taylor
Moved more tolower calls to setup rather than during runtime.
56
  std::set<T,internal::RegistryMapCompare<T> > item_set;
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
57
58
  bool addItemEntry(std::string name, T item)
59
  {
60
    if (item_map.count(name) == 0)
61
    {
62
      item_map[name]= item;
63
      return false;
64
    }
65
    return true;
66
  }
67
68
  bool addItem(std::string name, T item)
69
  {
70
71
    /* First, add with no transform */
72
    if (addItemEntry(name, item))
73
      return true;
74
75
    /* Transform to lower, then add */ 
76
    transform(name.begin(), name.end(),
77
              name.begin(), ::tolower);
1022.2.37 by Monty Taylor
Moved more tolower calls to setup rather than during runtime.
78
971.1.24 by Monty Taylor
Fixed a bug in the original impl.
79
    /* Ignore failures here - the original name could be all lower */
80
    addItemEntry(name, item);
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
81
1022.2.39 by Monty Taylor
Added toupper to registry.
82
    /* Transform to upper, then add */ 
83
    transform(name.begin(), name.end(),
84
              name.begin(), ::toupper);
85
86
    /* Ignore failures here - the original name could be all upper */
87
    addItemEntry(name, item);
88
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
89
    return false;
90
  }
91
92
  void removeItem(std::string name)
93
  {
94
95
    /* First, remove with no transform */
96
    item_map.erase(name);
97
98
    /* Transform to lower, then remove */ 
99
    transform(name.begin(), name.end(),
100
              name.begin(), ::tolower);
101
    item_map.erase(name);
102
  }
103
104
public:
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
105
971.1.27 by Monty Taylor
Moved first storage engine plugin_foreach.
106
  typedef typename std::set<T>::const_iterator const_iterator;
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
107
  typedef typename std::set<T>::iterator iterator;
994.2.2 by Monty Taylor
Store a Registry of SchedulerFactories and set one of them at startup for better error messages earlier.
108
  typedef size_t size_type;
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
109
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
110
  T find(const char *name, size_t length)
111
  {
112
    std::string find_str(name, length);
113
    return find(find_str);
114
  }
115
994.2.2 by Monty Taylor
Store a Registry of SchedulerFactories and set one of them at startup for better error messages earlier.
116
  T find(const std::string &name)
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
117
  {
118
119
    typename std::map<std::string, T>::iterator find_iter;
120
    find_iter=  item_map.find(name);
121
    if (find_iter != item_map.end())
122
      return (*find_iter).second;
123
    
994.2.2 by Monty Taylor
Store a Registry of SchedulerFactories and set one of them at startup for better error messages earlier.
124
    /* We must look for lower case, so we make a copy of the input name */
125
    std::string lower_name(name);
126
    transform(lower_name.begin(), lower_name.end(),
127
              lower_name.begin(), ::tolower);
128
    find_iter=  item_map.find(lower_name);
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
129
    if (find_iter != item_map.end())
130
      return (*find_iter).second;
131
132
    return NULL;
133
  }
134
135
  /**
136
   * True == failure
137
   */
138
  bool add(T item)
139
  {
140
    bool failed= false;
141
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
142
    if (item_set.insert(item).second == false)
143
      return true;
144
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
145
    if (addItem(item->getName(), item))
146
      failed= true;
147
148
    const std::vector<std::string>& aliases= item->getAliases();
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
149
    if (!(failed) && (aliases.size() > 0))
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
150
    {
151
      typename std::vector<std::string>::const_iterator iter= aliases.begin();
152
      while (iter != aliases.end())
153
      {
154
        if(addItem(*iter, item))
155
          failed= true;
156
        ++iter;
157
      }
158
    }
159
   
160
    if (failed == true)
161
      remove(item);
162
    return failed; 
163
  }
164
165
  /**
166
   * Remove an item from the registry. We don't care about failure
167
   */
168
  void remove(T item)
169
  {
170
    removeItem(item->getName());
171
172
    const std::vector<std::string>& aliases= item->getAliases();
173
    if (aliases.size() > 0)
174
    {
175
      std::vector<std::string>::const_iterator iter= aliases.begin();
176
      while (iter != aliases.end())
177
      {
178
        removeItem(*iter);
179
        ++iter;
180
      }
181
    }
182
  }
183
971.1.29 by Monty Taylor
This should really be a const_iterator. No?
184
  const_iterator begin()
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
185
  {
186
    return item_set.begin();
187
  }
188
971.1.29 by Monty Taylor
This should really be a const_iterator. No?
189
  const_iterator end()
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
190
  {
191
    return item_set.end();
192
  }
193
994.2.2 by Monty Taylor
Store a Registry of SchedulerFactories and set one of them at startup for better error messages earlier.
194
  size_type count(std::string name) const
195
  {
196
    /* Transform to lower, then add */
197
    transform(name.begin(), name.end(),
198
              name.begin(), ::tolower);
199
    return item_map.count(name);
200
  }
1022.2.37 by Monty Taylor
Moved more tolower calls to setup rather than during runtime.
201
202
  size_type size() const
203
  {
204
    return item_set.size();
205
  }
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
206
};
207
208
} /* namespace drizzled */
209
210
#endif /* DRIZZLED_REGISTRY_H */
211