~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>
1093.1.30 by Jay Pipes
Fix for compile failure...std::transform is in <algorithm>, so it's helpful to actually #include <algorithm>...
26
#include <algorithm>
1022.2.37 by Monty Taylor
Moved more tolower calls to setup rather than during runtime.
27
#include <functional>
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
28
29
namespace drizzled {
30
1022.2.37 by Monty Taylor
Moved more tolower calls to setup rather than during runtime.
31
namespace internal {
32
33
template<class T>
34
struct RegistryMapCompare
35
{
36
  bool operator() (const T& a, const T& b) const
37
  {
38
    return a.getName() < b.getName();
39
  }
40
};
41
42
template<class T>
43
struct RegistryMapCompare<T *>
44
{
45
  bool operator() (const T* a, const T* b) const
46
  {
47
    return a->getName() < b->getName();
48
  }
49
};
50
51
} /* namespace internal */
52
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
53
template<class T>
54
class Registry
55
{
56
  std::map<std::string, T> item_map;
1022.2.37 by Monty Taylor
Moved more tolower calls to setup rather than during runtime.
57
  std::set<T,internal::RegistryMapCompare<T> > item_set;
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
58
59
  bool addItemEntry(std::string name, T item)
60
  {
61
    if (item_map.count(name) == 0)
62
    {
63
      item_map[name]= item;
64
      return false;
65
    }
66
    return true;
67
  }
68
69
  bool addItem(std::string name, T item)
70
  {
71
72
    /* First, add with no transform */
73
    if (addItemEntry(name, item))
74
      return true;
75
76
    /* Transform to lower, then add */ 
77
    transform(name.begin(), name.end(),
78
              name.begin(), ::tolower);
1022.2.37 by Monty Taylor
Moved more tolower calls to setup rather than during runtime.
79
971.1.24 by Monty Taylor
Fixed a bug in the original impl.
80
    /* Ignore failures here - the original name could be all lower */
81
    addItemEntry(name, item);
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
82
1022.2.39 by Monty Taylor
Added toupper to registry.
83
    /* Transform to upper, then add */ 
84
    transform(name.begin(), name.end(),
85
              name.begin(), ::toupper);
86
87
    /* Ignore failures here - the original name could be all upper */
88
    addItemEntry(name, item);
89
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
90
    return false;
91
  }
92
93
  void removeItem(std::string name)
94
  {
95
96
    /* First, remove with no transform */
97
    item_map.erase(name);
98
99
    /* Transform to lower, then remove */ 
100
    transform(name.begin(), name.end(),
101
              name.begin(), ::tolower);
102
    item_map.erase(name);
103
  }
104
105
public:
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
106
971.1.27 by Monty Taylor
Moved first storage engine plugin_foreach.
107
  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.
108
  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.
109
  typedef size_t size_type;
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
110
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
111
  T find(const char *name, size_t length)
112
  {
113
    std::string find_str(name, length);
114
    return find(find_str);
115
  }
116
994.2.2 by Monty Taylor
Store a Registry of SchedulerFactories and set one of them at startup for better error messages earlier.
117
  T find(const std::string &name)
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
118
  {
119
120
    typename std::map<std::string, T>::iterator find_iter;
121
    find_iter=  item_map.find(name);
122
    if (find_iter != item_map.end())
123
      return (*find_iter).second;
124
    
994.2.2 by Monty Taylor
Store a Registry of SchedulerFactories and set one of them at startup for better error messages earlier.
125
    /* We must look for lower case, so we make a copy of the input name */
126
    std::string lower_name(name);
127
    transform(lower_name.begin(), lower_name.end(),
128
              lower_name.begin(), ::tolower);
129
    find_iter=  item_map.find(lower_name);
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
130
    if (find_iter != item_map.end())
131
      return (*find_iter).second;
132
133
    return NULL;
134
  }
135
136
  /**
137
   * True == failure
138
   */
139
  bool add(T item)
140
  {
141
    bool failed= false;
142
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
143
    if (item_set.insert(item).second == false)
144
      return true;
145
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
146
    if (addItem(item->getName(), item))
147
      failed= true;
148
149
    const std::vector<std::string>& aliases= item->getAliases();
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
150
    if (!(failed) && (aliases.size() > 0))
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
151
    {
152
      typename std::vector<std::string>::const_iterator iter= aliases.begin();
153
      while (iter != aliases.end())
154
      {
155
        if(addItem(*iter, item))
156
          failed= true;
157
        ++iter;
158
      }
159
    }
160
   
161
    if (failed == true)
162
      remove(item);
163
    return failed; 
164
  }
165
166
  /**
167
   * Remove an item from the registry. We don't care about failure
168
   */
169
  void remove(T item)
170
  {
171
    removeItem(item->getName());
172
173
    const std::vector<std::string>& aliases= item->getAliases();
174
    if (aliases.size() > 0)
175
    {
176
      std::vector<std::string>::const_iterator iter= aliases.begin();
177
      while (iter != aliases.end())
178
      {
179
        removeItem(*iter);
180
        ++iter;
181
      }
182
    }
183
  }
184
971.1.29 by Monty Taylor
This should really be a const_iterator. No?
185
  const_iterator begin()
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
186
  {
187
    return item_set.begin();
188
  }
189
971.1.29 by Monty Taylor
This should really be a const_iterator. No?
190
  const_iterator end()
971.1.26 by Monty Taylor
Added a set to Registry and an iterator over it.
191
  {
192
    return item_set.end();
193
  }
194
994.2.2 by Monty Taylor
Store a Registry of SchedulerFactories and set one of them at startup for better error messages earlier.
195
  size_type count(std::string name) const
196
  {
197
    /* Transform to lower, then add */
198
    transform(name.begin(), name.end(),
199
              name.begin(), ::tolower);
200
    return item_map.count(name);
201
  }
1022.2.37 by Monty Taylor
Moved more tolower calls to setup rather than during runtime.
202
203
  size_type size() const
204
  {
205
    return item_set.size();
206
  }
971.1.23 by Monty Taylor
Add generalized registry to be used for case-insensitive mappings.
207
};
208
209
} /* namespace drizzled */
210
211
#endif /* DRIZZLED_REGISTRY_H */
212