~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2003 MySQL AB
2
3
  This program is free software; you can redistribute it and/or modify
4
  it under the terms of the GNU General Public License as published by
5
  the Free Software Foundation; version 2 of the License.
6
7
  This program is distributed in the hope that it will be useful,
8
  but WITHOUT ANY WARRANTY; without even the implied warranty of
9
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
  GNU General Public License for more details.
11
12
  You should have received a copy of the GNU General Public License
13
  along with this program; if not, write to the Free Software
14
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/*
17
  Make sure to look at ha_tina.h for more details.
18
19
  First off, this is a play thing for me, there are a number of things
20
  wrong with it:
21
    *) It was designed for csv and therefore its performance is highly
22
       questionable.
23
    *) Indexes have not been implemented. This is because the files can
24
       be traded in and out of the table directory without having to worry
25
       about rebuilding anything.
26
    *) NULLs and "" are treated equally (like a spreadsheet).
27
    *) There was in the beginning no point to anyone seeing this other
28
       then me, so there is a good chance that I haven't quite documented
29
       it well.
30
    *) Less design, more "make it work"
31
32
  Now there are a few cool things with it:
33
    *) Errors can result in corrupted data files.
34
    *) Data files can be read by spreadsheets directly.
35
36
TODO:
37
 *) Move to a block system for larger files
38
 *) Error recovery, its all there, just need to finish it
39
 *) Document how the chains work.
40
41
 -Brian
42
*/
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
43
#include "config.h"
584.1.14 by Monty Taylor
Removed field.h from common_includes.
44
#include <drizzled/field.h>
584.5.1 by Monty Taylor
Removed field includes from field.h.
45
#include <drizzled/field/blob.h>
46
#include <drizzled/field/timestamp.h>
549 by Monty Taylor
Took gettext.h out of header files.
47
#include <drizzled/error.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
48
#include <drizzled/table.h>
49
#include <drizzled/session.h>
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
50
#include "drizzled/internal/my_sys.h"
1 by brian
clean slate
51
992.1.31 by Monty Taylor
Moved csv.
52
#include "ha_tina.h"
53
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
54
#include <fcntl.h>
55
1608.3.1 by Zimin
refactor CSV engine's tina_set
56
#include <algorithm>
57
#include <vector>
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
58
#include <string>
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
59
#include <map>
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
60
61
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
62
using namespace drizzled;
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
63
1 by brian
clean slate
64
/*
481 by Brian Aker
Remove all of uchar.
65
  unsigned char + unsigned char + uint64_t + uint64_t + uint64_t + uint64_t + unsigned char
1 by brian
clean slate
66
*/
481 by Brian Aker
Remove all of uchar.
67
#define META_BUFFER_SIZE sizeof(unsigned char) + sizeof(unsigned char) + sizeof(uint64_t) \
68
  + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(unsigned char)
1 by brian
clean slate
69
#define TINA_CHECK_HEADER 254 // The number we use to determine corruption
70
#define BLOB_MEMROOT_ALLOC_SIZE 8192
71
72
/* The file extension */
73
#define CSV_EXT ".CSV"               // The data file
74
#define CSN_EXT ".CSN"               // Files used during repair and update
75
#define CSM_EXT ".CSM"               // Meta file
76
77
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
78
static int read_meta_file(int meta_file, ha_rows *rows);
79
static int write_meta_file(int meta_file, ha_rows rows, bool dirty);
1 by brian
clean slate
80
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
81
void tina_get_status(void* param, int concurrent_insert);
82
void tina_update_status(void* param);
83
bool tina_check_status(void* param);
1 by brian
clean slate
84
85
/* Stuff for shares */
86
pthread_mutex_t tina_mutex;
87
88
/*****************************************************************************
89
 ** TINA tables
90
 *****************************************************************************/
91
92
/*
1039.3.1 by Stewart Smith
move bas_ext to StorageEngine instead of handler
93
  If frm_error() is called in table.cc this is called to find out what file
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
94
  extensions exist for this Cursor.
1039.3.1 by Stewart Smith
move bas_ext to StorageEngine instead of handler
95
*/
96
static const char *ha_tina_exts[] = {
97
  CSV_EXT,
98
  CSM_EXT,
99
  NULL
100
};
101
1208 by Brian Aker
Merge Jay
102
class Tina : public drizzled::plugin::StorageEngine
960.2.30 by Monty Taylor
Tina done.
103
{
1240.2.2 by Monty Taylor
Turned TINA_SHARE into TinaShare.
104
  typedef std::map<string, TinaShare*> TinaMap;
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
105
  TinaMap tina_open_tables;
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
106
public:
964.1.4 by Monty Taylor
Moved flags into private area.
107
  Tina(const string& name_arg)
1233.1.5 by Brian Aker
More table_flags converted.
108
   : drizzled::plugin::StorageEngine(name_arg,
109
                                     HTON_TEMPORARY_ONLY |
110
                                     HTON_NO_AUTO_INCREMENT |
1461.1.1 by Stewart Smith
remove HTON_FILE_BASED: it's unused now.
111
                                     HTON_SKIP_STORE_LOCK),
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
112
    tina_open_tables()
113
  {}
1324.2.3 by Monty Taylor
Remove plugin deinit.
114
  virtual ~Tina()
115
  {
116
    pthread_mutex_destroy(&tina_mutex);
117
  }
118
1208.3.2 by brian
Update for Cursor renaming.
119
  virtual Cursor *create(TableShare &table,
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
120
                         drizzled::memory::Root *mem_root)
960.2.30 by Monty Taylor
Tina done.
121
  {
1208.3.2 by brian
Update for Cursor renaming.
122
    return new (mem_root) ha_tina(*this, table);
960.2.30 by Monty Taylor
Tina done.
123
  }
1039.3.1 by Stewart Smith
move bas_ext to StorageEngine instead of handler
124
125
  const char **bas_ext() const {
126
    return ha_tina_exts;
127
  }
128
1413 by Brian Aker
doCreateTable() was still taking a pointer instead of a session reference.
129
  int doCreateTable(Session &,
130
                    Table &table_arg,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
131
                    const drizzled::TableIdentifier &identifier,
1222.1.7 by Brian Aker
Remove HA_CREATE_INFO from createTable()
132
                    drizzled::message::Table&);
1039.3.3 by Stewart Smith
Move handler::create to StorageEngine::create_table
133
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
134
  int doGetTableDefinition(Session& session,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
135
                           const drizzled::TableIdentifier &identifier,
1354.1.1 by Brian Aker
Modify ptr to reference.
136
                           drizzled::message::Table &table_message);
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
137
138
  /* Temp only engine, so do not return values. */
1642 by Brian Aker
This adds const to SchemaIdentifier.
139
  void doGetTableNames(drizzled::CachedDirectory &, const SchemaIdentifier&, set<string>&) { };
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
140
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
141
  int doDropTable(Session&, const drizzled::TableIdentifier &identifier);
1240.2.2 by Monty Taylor
Turned TINA_SHARE into TinaShare.
142
  TinaShare *findOpenTable(const string table_name);
143
  void addOpenTable(const string &table_name, TinaShare *);
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
144
  void deleteOpenTable(const string &table_name);
145
1233.1.9 by Brian Aker
Move max key stuff up to engine.
146
147
  uint32_t max_keys()          const { return 0; }
148
  uint32_t max_key_parts()     const { return 0; }
149
  uint32_t max_key_length()    const { return 0; }
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
150
  bool doDoesTableExist(Session& session, const drizzled::TableIdentifier &identifier);
151
  int doRenameTable(Session&, const drizzled::TableIdentifier &from, const drizzled::TableIdentifier &to);
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
152
153
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
1642 by Brian Aker
This adds const to SchemaIdentifier.
154
                             const drizzled::SchemaIdentifier &schema_identifier,
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
155
                             drizzled::TableIdentifiers &set_of_identifiers);
960.2.30 by Monty Taylor
Tina done.
156
};
157
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
158
void Tina::doGetTableIdentifiers(drizzled::CachedDirectory&,
1642 by Brian Aker
This adds const to SchemaIdentifier.
159
                                 const drizzled::SchemaIdentifier&,
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
160
                                 drizzled::TableIdentifiers&)
161
{
162
}
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
163
1391 by Brian Aker
Updating interface.
164
int Tina::doRenameTable(Session &session,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
165
                        const drizzled::TableIdentifier &from, const drizzled::TableIdentifier &to)
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
166
{
167
  int error= 0;
168
  for (const char **ext= bas_ext(); *ext ; ext++)
169
  {
1390 by Brian Aker
Update interface to use Identifiers directly.
170
    if (rename_file_ext(from.getPath().c_str(), to.getPath().c_str(), *ext))
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
171
    {
172
      if ((error=errno) != ENOENT)
173
        break;
174
      error= 0;
175
    }
176
  }
1391 by Brian Aker
Updating interface.
177
1395.1.1 by Brian Aker
Fixes for alter table to make sure that the proto on disk is valid.
178
  session.renameTableMessage(from, to);
1391 by Brian Aker
Updating interface.
179
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
180
  return error;
181
}
182
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
183
bool Tina::doDoesTableExist(Session &session, const drizzled::TableIdentifier &identifier)
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
184
{
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
185
  return session.doesTableMessageExist(identifier);
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
186
}
187
188
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
189
int Tina::doDropTable(Session &session,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
190
                      const drizzled::TableIdentifier &identifier)
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
191
{
192
  int error= 0;
193
  int enoent_or_zero= ENOENT;                   // Error if no file was deleted
194
  char buff[FN_REFLEN];
195
196
  for (const char **ext= bas_ext(); *ext ; ext++)
197
  {
1358.1.9 by Brian Aker
Update for std::string
198
    internal::fn_format(buff, identifier.getPath().c_str(), "", *ext,
199
                        MY_UNPACK_FILENAME|MY_APPEND_EXT);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
200
    if (internal::my_delete_with_symlink(buff, MYF(0)))
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
201
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
202
      if ((error= errno) != ENOENT)
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
203
	break;
204
    }
205
    else
206
      enoent_or_zero= 0;                        // No error for ENOENT
207
    error= enoent_or_zero;
208
  }
209
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
210
  session.removeTableMessage(identifier);
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
211
212
  return error;
213
}
214
1240.2.2 by Monty Taylor
Turned TINA_SHARE into TinaShare.
215
TinaShare *Tina::findOpenTable(const string table_name)
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
216
{
217
  TinaMap::iterator find_iter=
218
    tina_open_tables.find(table_name);
219
220
  if (find_iter != tina_open_tables.end())
221
    return (*find_iter).second;
222
  else
223
    return NULL;
224
}
225
1240.2.2 by Monty Taylor
Turned TINA_SHARE into TinaShare.
226
void Tina::addOpenTable(const string &table_name, TinaShare *share)
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
227
{
228
  tina_open_tables[table_name]= share;
229
}
230
231
void Tina::deleteOpenTable(const string &table_name)
232
{
233
  tina_open_tables.erase(table_name);
234
}
235
236
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
237
int Tina::doGetTableDefinition(Session &session,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
238
                               const drizzled::TableIdentifier &identifier,
1354.1.1 by Brian Aker
Modify ptr to reference.
239
                               drizzled::message::Table &table_message)
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
240
{
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
241
  if (session.getTableMessage(identifier, table_message))
242
    return EEXIST;
243
244
  return ENOENT;
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
245
}
246
247
971.1.51 by Monty Taylor
New-style plugin registration now works.
248
static Tina *tina_engine= NULL;
249
1530.2.6 by Monty Taylor
Moved plugin::Context to module::Context.
250
static int tina_init_func(drizzled::module::Context &context)
1 by brian
clean slate
251
{
960.2.30 by Monty Taylor
Tina done.
252
1192.5.8 by Monty Taylor
Made csv dynamic
253
  tina_engine= new Tina("CSV");
1324.2.2 by Monty Taylor
Use the plugin::Context everywhere.
254
  context.add(tina_engine);
960.2.30 by Monty Taylor
Tina done.
255
398.1.10 by Monty Taylor
Actually removed VOID() this time.
256
  pthread_mutex_init(&tina_mutex,MY_MUTEX_INIT_FAST);
1 by brian
clean slate
257
  return 0;
258
}
259
260
261
1240.2.2 by Monty Taylor
Turned TINA_SHARE into TinaShare.
262
TinaShare::TinaShare(const char *table_name_arg)
263
  : table_name(table_name_arg), use_count(0), saved_data_file_length(0),
264
    update_file_opened(false), tina_write_opened(false),
265
    crashed(false), rows_recorded(0), data_file_version(0)
266
{
1240.2.3 by Monty Taylor
Fixed blackhole crashses on Spare - made Blackhole follow the pattern of CSV and Archive.
267
  thr_lock_init(&lock);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
268
  internal::fn_format(data_file_name, table_name_arg, "", CSV_EXT,
1240.2.2 by Monty Taylor
Turned TINA_SHARE into TinaShare.
269
            MY_REPLACE_EXT|MY_UNPACK_FILENAME);
270
}
271
272
TinaShare::~TinaShare()
273
{
274
  thr_lock_delete(&lock);
275
  pthread_mutex_destroy(&mutex);
276
}
277
1 by brian
clean slate
278
/*
279
  Simple lock controls.
280
*/
1240.2.2 by Monty Taylor
Turned TINA_SHARE into TinaShare.
281
TinaShare *ha_tina::get_share(const char *table_name)
1 by brian
clean slate
282
{
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
283
  pthread_mutex_lock(&tina_mutex);
284
285
  Tina *a_tina= static_cast<Tina *>(engine);
286
  share= a_tina->findOpenTable(table_name);
287
1 by brian
clean slate
288
  char meta_file_name[FN_REFLEN];
15 by brian
Fix for stat, NETWARE removal
289
  struct stat file_stat;
1 by brian
clean slate
290
291
  /*
292
    If share is not present in the hash, create a new share and
293
    initialize its members.
294
  */
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
295
  if (! share)
1 by brian
clean slate
296
  {
1240.2.2 by Monty Taylor
Turned TINA_SHARE into TinaShare.
297
    share= new TinaShare(table_name);
298
299
    if (share == NULL)
1 by brian
clean slate
300
    {
301
      pthread_mutex_unlock(&tina_mutex);
302
      return NULL;
303
    }
304
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
305
    internal::fn_format(meta_file_name, table_name, "", CSM_EXT,
1 by brian
clean slate
306
              MY_REPLACE_EXT|MY_UNPACK_FILENAME);
307
15 by brian
Fix for stat, NETWARE removal
308
    if (stat(share->data_file_name, &file_stat))
1240.2.2 by Monty Taylor
Turned TINA_SHARE into TinaShare.
309
    {
310
      pthread_mutex_unlock(&tina_mutex);
311
      delete share;
312
      return NULL;
313
    }
314
  
1 by brian
clean slate
315
    share->saved_data_file_length= file_stat.st_size;
316
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
317
    a_tina->addOpenTable(share->table_name, share);
318
1 by brian
clean slate
319
    pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
320
321
    /*
322
      Open or create the meta file. In the latter case, we'll get
323
      an error during read_meta_file and mark the table as crashed.
324
      Usually this will result in auto-repair, and we will get a good
325
      meta-file in the end.
326
    */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
327
    if ((share->meta_file= internal::my_open(meta_file_name,
1309.1.3 by Brian Aker
Cache for Schema.
328
                                             O_RDWR|O_CREAT, MYF(0))) == -1)
163 by Brian Aker
Merge Monty's code.
329
      share->crashed= true;
1 by brian
clean slate
330
331
    /*
332
      If the meta file will not open we assume it is crashed and
333
      mark it as such.
334
    */
335
    if (read_meta_file(share->meta_file, &share->rows_recorded))
163 by Brian Aker
Merge Monty's code.
336
      share->crashed= true;
1 by brian
clean slate
337
  }
338
  share->use_count++;
339
  pthread_mutex_unlock(&tina_mutex);
340
341
  return share;
342
}
343
344
345
/*
346
  Read CSV meta-file
347
348
  SYNOPSIS
349
    read_meta_file()
350
    meta_file   The meta-file filedes
351
    ha_rows     Pointer to the var we use to store rows count.
352
                These are read from the meta-file.
353
354
  DESCRIPTION
355
356
    Read the meta-file info. For now we are only interested in
357
    rows counf, crashed bit and magic number.
358
359
  RETURN
360
    0 - OK
361
    non-zero - error occurred
362
*/
363
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
364
static int read_meta_file(int meta_file, ha_rows *rows)
1 by brian
clean slate
365
{
481 by Brian Aker
Remove all of uchar.
366
  unsigned char meta_buffer[META_BUFFER_SIZE];
367
  unsigned char *ptr= meta_buffer;
1 by brian
clean slate
368
656.1.39 by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek.
369
  lseek(meta_file, 0, SEEK_SET);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
370
  if (internal::my_read(meta_file, (unsigned char*)meta_buffer, META_BUFFER_SIZE, 0)
1 by brian
clean slate
371
      != META_BUFFER_SIZE)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
372
    return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
373
374
  /*
375
    Parse out the meta data, we ignore version at the moment
376
  */
377
481 by Brian Aker
Remove all of uchar.
378
  ptr+= sizeof(unsigned char)*2; // Move past header
1 by brian
clean slate
379
  *rows= (ha_rows)uint8korr(ptr);
380
  ptr+= sizeof(uint64_t); // Move past rows
381
  /*
382
    Move past check_point, auto_increment and forced_flushes fields.
383
    They are present in the format, but we do not use them yet.
384
  */
385
  ptr+= 3*sizeof(uint64_t);
386
387
  /* check crashed bit and magic number */
481 by Brian Aker
Remove all of uchar.
388
  if ((meta_buffer[0] != (unsigned char)TINA_CHECK_HEADER) ||
163 by Brian Aker
Merge Monty's code.
389
      ((bool)(*ptr)== true))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
390
    return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
391
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
392
  internal::my_sync(meta_file, MYF(MY_WME));
1 by brian
clean slate
393
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
394
  return(0);
1 by brian
clean slate
395
}
396
397
398
/*
399
  Write CSV meta-file
400
401
  SYNOPSIS
402
    write_meta_file()
403
    meta_file   The meta-file filedes
404
    ha_rows     The number of rows we have in the datafile.
405
    dirty       A flag, which marks whether we have a corrupt table
406
407
  DESCRIPTION
408
409
    Write meta-info the the file. Only rows count, crashed bit and
410
    magic number matter now.
411
412
  RETURN
413
    0 - OK
414
    non-zero - error occurred
415
*/
416
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
417
static int write_meta_file(int meta_file, ha_rows rows, bool dirty)
1 by brian
clean slate
418
{
481 by Brian Aker
Remove all of uchar.
419
  unsigned char meta_buffer[META_BUFFER_SIZE];
420
  unsigned char *ptr= meta_buffer;
1 by brian
clean slate
421
481 by Brian Aker
Remove all of uchar.
422
  *ptr= (unsigned char)TINA_CHECK_HEADER;
423
  ptr+= sizeof(unsigned char);
424
  *ptr= (unsigned char)TINA_VERSION;
425
  ptr+= sizeof(unsigned char);
1 by brian
clean slate
426
  int8store(ptr, (uint64_t)rows);
427
  ptr+= sizeof(uint64_t);
428
  memset(ptr, 0, 3*sizeof(uint64_t));
429
  /*
430
     Skip over checkpoint, autoincrement and forced_flushes fields.
431
     We'll need them later.
432
  */
433
  ptr+= 3*sizeof(uint64_t);
481 by Brian Aker
Remove all of uchar.
434
  *ptr= (unsigned char)dirty;
1 by brian
clean slate
435
656.1.39 by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek.
436
  lseek(meta_file, 0, SEEK_SET);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
437
  if (internal::my_write(meta_file, (unsigned char *)meta_buffer, META_BUFFER_SIZE, 0)
1 by brian
clean slate
438
      != META_BUFFER_SIZE)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
439
    return(-1);
1 by brian
clean slate
440
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
441
  internal::my_sync(meta_file, MYF(MY_WME));
1 by brian
clean slate
442
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
443
  return(0);
1 by brian
clean slate
444
}
445
446
int ha_tina::init_tina_writer()
447
{
448
  /*
449
    Mark the file as crashed. We will set the flag back when we close
450
    the file. In the case of the crash it will remain marked crashed,
451
    which enforce recovery.
452
  */
163 by Brian Aker
Merge Monty's code.
453
  (void)write_meta_file(share->meta_file, share->rows_recorded, true);
1 by brian
clean slate
454
455
  if ((share->tina_write_filedes=
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
456
        internal::my_open(share->data_file_name, O_RDWR|O_APPEND, MYF(0))) == -1)
1 by brian
clean slate
457
  {
163 by Brian Aker
Merge Monty's code.
458
    share->crashed= true;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
459
    return(1);
1 by brian
clean slate
460
  }
163 by Brian Aker
Merge Monty's code.
461
  share->tina_write_opened= true;
1 by brian
clean slate
462
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
463
  return(0);
1 by brian
clean slate
464
}
465
466
467
/*
468
  Free lock controls.
469
*/
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
470
int ha_tina::free_share()
1 by brian
clean slate
471
{
472
  pthread_mutex_lock(&tina_mutex);
473
  int result_code= 0;
474
  if (!--share->use_count){
475
    /* Write the meta file. Mark it as crashed if needed. */
476
    (void)write_meta_file(share->meta_file, share->rows_recorded,
163 by Brian Aker
Merge Monty's code.
477
                          share->crashed ? true :false);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
478
    if (internal::my_close(share->meta_file, MYF(0)))
1 by brian
clean slate
479
      result_code= 1;
480
    if (share->tina_write_opened)
481
    {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
482
      if (internal::my_close(share->tina_write_filedes, MYF(0)))
1 by brian
clean slate
483
        result_code= 1;
163 by Brian Aker
Merge Monty's code.
484
      share->tina_write_opened= false;
1 by brian
clean slate
485
    }
486
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
487
    Tina *a_tina= static_cast<Tina *>(engine);
1240.2.2 by Monty Taylor
Turned TINA_SHARE into TinaShare.
488
    a_tina->deleteOpenTable(share->table_name);
489
    delete share;
1 by brian
clean slate
490
  }
491
  pthread_mutex_unlock(&tina_mutex);
492
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
493
  return(result_code);
1 by brian
clean slate
494
}
495
496
497
/*
498
  This function finds the end of a line and returns the length
499
  of the line ending.
500
501
  We support three kinds of line endings:
502
  '\r'     --  Old Mac OS line ending
503
  '\n'     --  Traditional Unix and Mac OS X line ending
504
  '\r''\n' --  DOS\Windows line ending
505
*/
506
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
507
static off_t find_eoln_buff(Transparent_file *data_buff, off_t begin,
508
                            off_t end, int *eoln_len)
1 by brian
clean slate
509
{
510
  *eoln_len= 0;
511
512
  for (off_t x= begin; x < end; x++)
513
  {
514
    /* Unix (includes Mac OS X) */
515
    if (data_buff->get_value(x) == '\n')
516
      *eoln_len= 1;
517
    else
518
      if (data_buff->get_value(x) == '\r') // Mac or Dos
519
      {
520
        /* old Mac line ending */
521
        if (x + 1 == end || (data_buff->get_value(x + 1) != '\n'))
522
          *eoln_len= 1;
523
        else // DOS style ending
524
          *eoln_len= 2;
525
      }
526
527
    if (*eoln_len)  // end of line was found
528
      return x;
529
  }
530
531
  return 0;
532
}
533
534
535
1208.3.2 by brian
Update for Cursor renaming.
536
ha_tina::ha_tina(drizzled::plugin::StorageEngine &engine_arg, TableShare &table_arg)
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
537
  :Cursor(engine_arg, table_arg),
1 by brian
clean slate
538
  /*
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
539
    These definitions are found in Cursor.h
1 by brian
clean slate
540
    They are not probably completely right.
541
  */
542
  current_position(0), next_position(0), local_saved_data_file_length(0),
1608.3.1 by Zimin
refactor CSV engine's tina_set
543
  file_buff(0), local_data_file_version(0), records_is_known(0)
1 by brian
clean slate
544
{
545
  /* Set our original buffers from pre-allocated memory */
546
  buffer.set((char*)byte_buffer, IO_SIZE, &my_charset_bin);
547
  file_buff= new Transparent_file();
548
}
549
550
551
/*
552
  Encode a buffer into the quoted format.
553
*/
554
653 by Brian Aker
More solaris bits
555
int ha_tina::encode_quote(unsigned char *)
1 by brian
clean slate
556
{
557
  char attribute_buffer[1024];
558
  String attribute(attribute_buffer, sizeof(attribute_buffer),
559
                   &my_charset_bin);
560
561
  buffer.length(0);
562
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
563
  for (Field **field= table->getFields() ; *field ; field++)
1 by brian
clean slate
564
  {
565
    const char *ptr;
566
    const char *end_ptr;
567
    const bool was_null= (*field)->is_null();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
568
1 by brian
clean slate
569
    /*
570
      assistance for backwards compatibility in production builds.
571
      note: this will not work for ENUM columns.
572
    */
573
    if (was_null)
574
    {
575
      (*field)->set_default();
576
      (*field)->set_notnull();
577
    }
578
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
579
    /* 
580
      Since we are needing to "translate" the type into a string we 
581
      will need to do a val_str(). This would cause an assert() to
582
      normally occur since we are onlying "writing" values.
583
    */
584
    (*field)->setReadSet();
1 by brian
clean slate
585
    (*field)->val_str(&attribute,&attribute);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
586
1 by brian
clean slate
587
    if (was_null)
588
      (*field)->set_null();
589
590
    if ((*field)->str_needs_quotes())
591
    {
592
      ptr= attribute.ptr();
593
      end_ptr= attribute.length() + ptr;
594
595
      buffer.append('"');
596
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
597
      while (ptr < end_ptr)
1 by brian
clean slate
598
      {
599
        if (*ptr == '"')
600
        {
601
          buffer.append('\\');
602
          buffer.append('"');
603
          *ptr++;
604
        }
605
        else if (*ptr == '\r')
606
        {
607
          buffer.append('\\');
608
          buffer.append('r');
609
          *ptr++;
610
        }
611
        else if (*ptr == '\\')
612
        {
613
          buffer.append('\\');
614
          buffer.append('\\');
615
          *ptr++;
616
        }
617
        else if (*ptr == '\n')
618
        {
619
          buffer.append('\\');
620
          buffer.append('n');
621
          *ptr++;
622
        }
623
        else
624
          buffer.append(*ptr++);
625
      }
626
      buffer.append('"');
627
    }
628
    else
629
    {
630
      buffer.append(attribute);
631
    }
632
633
    buffer.append(',');
634
  }
635
  // Remove the comma, add a line feed
636
  buffer.length(buffer.length() - 1);
637
  buffer.append('\n');
638
639
  //buffer.replace(buffer.length(), 0, "\n", 1);
640
641
  return (buffer.length());
642
}
643
644
/*
645
  chain_append() adds delete positions to the chain that we use to keep
646
  track of space. Then the chain will be used to cleanup "holes", occurred
647
  due to deletes and updates.
648
*/
649
int ha_tina::chain_append()
650
{
1608.3.1 by Zimin
refactor CSV engine's tina_set
651
  if (chain.size() > 0 && chain.back().second == current_position)
652
    chain.back().second= next_position;
1 by brian
clean slate
653
  else
1608.3.1 by Zimin
refactor CSV engine's tina_set
654
    chain.push_back(make_pair(current_position, next_position));
1 by brian
clean slate
655
  return 0;
656
}
657
658
659
/*
660
  Scans for a row.
661
*/
481 by Brian Aker
Remove all of uchar.
662
int ha_tina::find_current_row(unsigned char *buf)
1 by brian
clean slate
663
{
664
  off_t end_offset, curr_offset= current_position;
665
  int eoln_len;
666
  int error;
667
1487 by Brian Aker
More updates for memory::Root
668
  blobroot.free_root(MYF(drizzled::memory::MARK_BLOCKS_FREE));
1 by brian
clean slate
669
670
  /*
671
    We do not read further then local_saved_data_file_length in order
672
    not to conflict with undergoing concurrent insert.
673
  */
674
  if ((end_offset=
675
        find_eoln_buff(file_buff, current_position,
676
                       local_saved_data_file_length, &eoln_len)) == 0)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
677
    return(HA_ERR_END_OF_FILE);
1 by brian
clean slate
678
679
  error= HA_ERR_CRASHED_ON_USAGE;
680
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
681
  memset(buf, 0, table->getShare()->null_bytes);
1 by brian
clean slate
682
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
683
  for (Field **field=table->getFields() ; *field ; field++)
1 by brian
clean slate
684
  {
685
    char curr_char;
584.5.1 by Monty Taylor
Removed field includes from field.h.
686
1 by brian
clean slate
687
    buffer.length(0);
688
    if (curr_offset >= end_offset)
689
      goto err;
690
    curr_char= file_buff->get_value(curr_offset);
691
    if (curr_char == '"')
692
    {
693
      curr_offset++; // Incrementpast the first quote
694
695
      for(; curr_offset < end_offset; curr_offset++)
696
      {
697
        curr_char= file_buff->get_value(curr_offset);
698
        // Need to convert line feeds!
699
        if (curr_char == '"' &&
700
            (curr_offset == end_offset - 1 ||
701
             file_buff->get_value(curr_offset + 1) == ','))
702
        {
703
          curr_offset+= 2; // Move past the , and the "
704
          break;
705
        }
706
        if (curr_char == '\\' && curr_offset != (end_offset - 1))
707
        {
708
          curr_offset++;
709
          curr_char= file_buff->get_value(curr_offset);
710
          if (curr_char == 'r')
711
            buffer.append('\r');
712
          else if (curr_char == 'n' )
713
            buffer.append('\n');
714
          else if (curr_char == '\\' || curr_char == '"')
715
            buffer.append(curr_char);
716
          else  /* This could only happed with an externally created file */
717
          {
718
            buffer.append('\\');
719
            buffer.append(curr_char);
720
          }
721
        }
722
        else // ordinary symbol
723
        {
724
          /*
725
            We are at final symbol and no last quote was found =>
726
            we are working with a damaged file.
727
          */
728
          if (curr_offset == end_offset - 1)
729
            goto err;
730
          buffer.append(curr_char);
731
        }
732
      }
733
    }
584.5.1 by Monty Taylor
Removed field includes from field.h.
734
    else
1 by brian
clean slate
735
    {
736
      for(; curr_offset < end_offset; curr_offset++)
737
      {
738
        curr_char= file_buff->get_value(curr_offset);
739
        if (curr_char == ',')
740
        {
741
          curr_offset++;       // Skip the ,
742
          break;
743
        }
744
        buffer.append(curr_char);
745
      }
746
    }
747
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
748
    if ((*field)->isReadSet() || (*field)->isWriteSet())
1 by brian
clean slate
749
    {
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
750
      /* This masks a bug in the logic for a SELECT * */
751
      (*field)->setWriteSet();
1 by brian
clean slate
752
      if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset(),
753
                          CHECK_FIELD_WARN))
754
        goto err;
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
755
1 by brian
clean slate
756
      if ((*field)->flags & BLOB_FLAG)
757
      {
758
        Field_blob *blob= *(Field_blob**) field;
481 by Brian Aker
Remove all of uchar.
759
        unsigned char *src, *tgt;
482 by Brian Aker
Remove uint.
760
        uint32_t length, packlength;
584.5.1 by Monty Taylor
Removed field includes from field.h.
761
1 by brian
clean slate
762
        packlength= blob->pack_length_no_ptr();
763
        length= blob->get_length(blob->ptr);
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
764
        memcpy(&src, blob->ptr + packlength, sizeof(char*));
1 by brian
clean slate
765
        if (src)
766
        {
1485 by Brian Aker
Updates to confine memroot
767
          tgt= (unsigned char*) blobroot.alloc_root(length);
629.3.4 by Kristian Nielsen
Take Mats'es changes from bmove()->memcpy(), and fix all of them to be
768
          memmove(tgt, src, length);
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
769
          memcpy(blob->ptr + packlength, &tgt, sizeof(char*));
1 by brian
clean slate
770
        }
771
      }
772
    }
773
  }
774
  next_position= end_offset + eoln_len;
775
  error= 0;
776
777
err:
778
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
779
  return(error);
1 by brian
clean slate
780
}
781
782
/*
783
  Three functions below are needed to enable concurrent insert functionality
784
  for CSV engine. For more details see mysys/thr_lock.c
785
*/
786
653 by Brian Aker
More solaris bits
787
void tina_get_status(void* param, int)
1 by brian
clean slate
788
{
789
  ha_tina *tina= (ha_tina*) param;
790
  tina->get_status();
791
}
792
793
void tina_update_status(void* param)
794
{
795
  ha_tina *tina= (ha_tina*) param;
796
  tina->update_status();
797
}
798
799
/* this should exist and return 0 for concurrent insert to work */
653 by Brian Aker
More solaris bits
800
bool tina_check_status(void *)
1 by brian
clean slate
801
{
802
  return 0;
803
}
804
805
/*
806
  Save the state of the table
807
808
  SYNOPSIS
809
    get_status()
810
811
  DESCRIPTION
812
    This function is used to retrieve the file length. During the lock
813
    phase of concurrent insert. For more details see comment to
814
    ha_tina::update_status below.
815
*/
816
817
void ha_tina::get_status()
818
{
819
  local_saved_data_file_length= share->saved_data_file_length;
820
}
821
822
823
/*
824
  Correct the state of the table. Called by unlock routines
825
  before the write lock is released.
826
827
  SYNOPSIS
828
    update_status()
829
830
  DESCRIPTION
831
    When we employ concurrent insert lock, we save current length of the file
832
    during the lock phase. We do not read further saved value, as we don't
833
    want to interfere with undergoing concurrent insert. Writers update file
834
    length info during unlock with update_status().
835
836
  NOTE
837
    For log tables concurrent insert works different. The reason is that
838
    log tables are always opened and locked. And as they do not unlock
839
    tables, the file length after writes should be updated in a different
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
840
    way.
1 by brian
clean slate
841
*/
842
843
void ha_tina::update_status()
844
{
845
  /* correct local_saved_data_file_length for writers */
846
  share->saved_data_file_length= local_saved_data_file_length;
847
}
848
849
850
/*
851
  Open a database file. Keep in mind that tables are caches, so
852
  this will not be called for every request. Any sort of positions
853
  that need to be reset should be kept in the ::extra() call.
854
*/
1633.4.1 by Brian Aker
Merge ha_open to have doOpen() which passes identifier.
855
int ha_tina::doOpen(const TableIdentifier &identifier, int , uint32_t )
1 by brian
clean slate
856
{
1633.4.1 by Brian Aker
Merge ha_open to have doOpen() which passes identifier.
857
  if (!(share= get_share(identifier.getPath().c_str())))
820.3.1 by Padraig
Changed ha_tina::open to return the correct error code
858
    return(ENOENT);
1 by brian
clean slate
859
1237.6.2 by Brian Aker
Minor cleanup for dead code.
860
  if (share->crashed)
1 by brian
clean slate
861
  {
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
862
    free_share();
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
863
    return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
864
  }
865
866
  local_data_file_version= share->data_file_version;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
867
  if ((data_file= internal::my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
868
    return(0);
1 by brian
clean slate
869
870
  /*
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
871
    Init locking. Pass Cursor object to the locking routines,
1 by brian
clean slate
872
    so that they could save/update local_saved_data_file_length value
873
    during locking. This is needed to enable concurrent inserts.
874
  */
875
  thr_lock_data_init(&share->lock, &lock, (void*) this);
876
  ref_length=sizeof(off_t);
877
878
  share->lock.get_status= tina_get_status;
879
  share->lock.update_status= tina_update_status;
880
  share->lock.check_status= tina_check_status;
881
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
882
  return(0);
1 by brian
clean slate
883
}
884
885
/*
886
  Close a database file. We remove ourselves from the shared strucutre.
887
  If it is empty we destroy it.
888
*/
889
int ha_tina::close(void)
890
{
891
  int rc= 0;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
892
  rc= internal::my_close(data_file, MYF(0));
1240.2.1 by Monty Taylor
Fixed the CSV tina_open_tables HASH to be a std::map.
893
  return(free_share() || rc);
1 by brian
clean slate
894
}
895
896
/*
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
897
  This is an INSERT. At the moment this Cursor just seeks to the end
1 by brian
clean slate
898
  of the file and appends the data. In an error case it really should
899
  just truncate to the original position (this is not done yet).
900
*/
1491.1.2 by Jay Pipes
Cursor::write_row() -> Cursor::doInsertRecord(). Cursor::ha_write_row() -> Cursor::insertRecord()
901
int ha_tina::doInsertRecord(unsigned char * buf)
1 by brian
clean slate
902
{
903
  int size;
904
905
  if (share->crashed)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
906
      return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
907
908
  size= encode_quote(buf);
909
910
  if (!share->tina_write_opened)
911
    if (init_tina_writer())
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
912
      return(-1);
1 by brian
clean slate
913
914
   /* use pwrite, as concurrent reader could have changed the position */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
915
  if (internal::my_write(share->tina_write_filedes, (unsigned char*)buffer.ptr(), size,
1 by brian
clean slate
916
               MYF(MY_WME | MY_NABP)))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
917
    return(-1);
1 by brian
clean slate
918
919
  /* update local copy of the max position to see our own changes */
920
  local_saved_data_file_length+= size;
921
922
  /* update shared info */
923
  pthread_mutex_lock(&share->mutex);
924
  share->rows_recorded++;
925
  /* update status for the log tables */
926
  pthread_mutex_unlock(&share->mutex);
927
928
  stats.records++;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
929
  return(0);
1 by brian
clean slate
930
}
931
932
933
int ha_tina::open_update_temp_file_if_needed()
934
{
935
  char updated_fname[FN_REFLEN];
936
937
  if (!share->update_file_opened)
938
  {
939
    if ((update_temp_file=
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
940
           internal::my_create(internal::fn_format(updated_fname, share->table_name.c_str(),
1 by brian
clean slate
941
                               "", CSN_EXT,
942
                               MY_REPLACE_EXT | MY_UNPACK_FILENAME),
943
                     0, O_RDWR | O_TRUNC, MYF(MY_WME))) < 0)
944
      return 1;
163 by Brian Aker
Merge Monty's code.
945
    share->update_file_opened= true;
1 by brian
clean slate
946
    temp_file_length= 0;
947
  }
948
  return 0;
949
}
950
951
/*
952
  This is called for an update.
953
  Make sure you put in code to increment the auto increment, also
954
  update any timestamp data. Currently auto increment is not being
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
955
  fixed since autoincrements have yet to be added to this table Cursor.
1 by brian
clean slate
956
  This will be called in a table scan right before the previous ::rnd_next()
957
  call.
958
*/
1491.1.3 by Jay Pipes
Cursor::update_row() changed to doUpdateRecord() and updateRecord()
959
int ha_tina::doUpdateRecord(const unsigned char *, unsigned char * new_data)
1 by brian
clean slate
960
{
961
  int size;
962
  int rc= -1;
963
964
  size= encode_quote(new_data);
965
966
  /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
967
    During update we mark each updating record as deleted
968
    (see the chain_append()) then write new one to the temporary data file.
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
969
    At the end of the sequence in the doEndTableScan() we append all non-marked
1 by brian
clean slate
970
    records from the data file to the temporary data file then rename it.
971
    The temp_file_length is used to calculate new data file length.
972
  */
973
  if (chain_append())
974
    goto err;
975
976
  if (open_update_temp_file_if_needed())
977
    goto err;
978
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
979
  if (internal::my_write(update_temp_file, (unsigned char*)buffer.ptr(), size,
1 by brian
clean slate
980
               MYF(MY_WME | MY_NABP)))
981
    goto err;
982
  temp_file_length+= size;
983
  rc= 0;
984
985
err:
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
986
  return(rc);
1 by brian
clean slate
987
}
988
989
990
/*
991
  Deletes a row. First the database will find the row, and then call this
992
  method. In the case of a table scan, the previous call to this will be
993
  the ::rnd_next() that found this row.
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
994
  The exception to this is an ORDER BY. This will cause the table Cursor
1 by brian
clean slate
995
  to walk the table noting the positions of all rows that match a query.
996
  The table will then be deleted/positioned based on the ORDER (so RANDOM,
997
  DESC, ASC).
998
*/
1491.1.4 by Jay Pipes
delete_row() is now deleteRecord() and doDeleteRecord() in Cursor
999
int ha_tina::doDeleteRecord(const unsigned char *)
1 by brian
clean slate
1000
{
1001
1002
  if (chain_append())
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1003
    return(-1);
1 by brian
clean slate
1004
1005
  stats.records--;
1006
  /* Update shared info */
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1007
  assert(share->rows_recorded);
1 by brian
clean slate
1008
  pthread_mutex_lock(&share->mutex);
1009
  share->rows_recorded--;
1010
  pthread_mutex_unlock(&share->mutex);
1011
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1012
  return(0);
1 by brian
clean slate
1013
}
1014
1015
1016
/**
1017
  @brief Initialize the data file.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1018
1 by brian
clean slate
1019
  @details Compare the local version of the data file with the shared one.
1020
  If they differ, there are some changes behind and we have to reopen
1021
  the data file to make the changes visible.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1022
  Call @c file_buff->init_buff() at the end to read the beginning of the
1 by brian
clean slate
1023
  data file into buffer.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1024
1 by brian
clean slate
1025
  @retval  0  OK.
1026
  @retval  1  There was an error.
1027
*/
1028
1029
int ha_tina::init_data_file()
1030
{
1031
  if (local_data_file_version != share->data_file_version)
1032
  {
1033
    local_data_file_version= share->data_file_version;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1034
    if (internal::my_close(data_file, MYF(0)) ||
1035
        (data_file= internal::my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1)
1 by brian
clean slate
1036
      return 1;
1037
  }
1038
  file_buff->init_buff(data_file);
1039
  return 0;
1040
}
1041
1042
1043
/*
1044
  All table scans call this first.
1045
  The order of a table scan is:
1046
1047
  ha_tina::info
1048
  ha_tina::rnd_init
1049
  ha_tina::extra
1050
  ENUM HA_EXTRA_CACHE   Cash record in HA_rrnd()
1051
  ha_tina::rnd_next
1052
  ha_tina::rnd_next
1053
  ha_tina::rnd_next
1054
  ha_tina::rnd_next
1055
  ha_tina::rnd_next
1056
  ha_tina::rnd_next
1057
  ha_tina::rnd_next
1058
  ha_tina::rnd_next
1059
  ha_tina::rnd_next
1060
  ha_tina::extra
1061
  ENUM HA_EXTRA_NO_CACHE   End cacheing of records (def)
1062
  ha_tina::extra
1063
  ENUM HA_EXTRA_RESET   Reset database to after open
1064
1065
  Each call to ::rnd_next() represents a row returned in the can. When no more
1066
  rows can be returned, rnd_next() returns a value of HA_ERR_END_OF_FILE.
1067
  The ::info() call is just for the optimizer.
1068
1069
*/
1070
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
1071
int ha_tina::doStartTableScan(bool)
1 by brian
clean slate
1072
{
1073
  /* set buffer to the beginning of the file */
1074
  if (share->crashed || init_data_file())
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1075
    return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
1076
1077
  current_position= next_position= 0;
1078
  stats.records= 0;
1079
  records_is_known= 0;
1608.3.1 by Zimin
refactor CSV engine's tina_set
1080
  chain.clear();
1 by brian
clean slate
1081
1487 by Brian Aker
More updates for memory::Root
1082
  blobroot.init_alloc_root(BLOB_MEMROOT_ALLOC_SIZE);
1 by brian
clean slate
1083
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1084
  return(0);
1 by brian
clean slate
1085
}
1086
1087
/*
1088
  ::rnd_next() does all the heavy lifting for a table scan. You will need to
1089
  populate *buf with the correct field data. You can walk the field to
1090
  determine at what position you should store the data (take a look at how
1091
  ::find_current_row() works). The structure is something like:
1092
  0Foo  Dog  Friend
1093
  The first offset is for the first attribute. All space before that is
1094
  reserved for null count.
1095
  Basically this works as a mask for which rows are nulled (compared to just
1096
  empty).
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1097
  This table Cursor doesn't do nulls and does not know the difference between
1098
  NULL and "". This is ok since this table Cursor is for spreadsheets and
1 by brian
clean slate
1099
  they don't know about them either :)
1100
*/
481 by Brian Aker
Remove all of uchar.
1101
int ha_tina::rnd_next(unsigned char *buf)
1 by brian
clean slate
1102
{
1103
  int rc;
1104
1105
  if (share->crashed)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1106
      return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
1107
1273.16.8 by Brian Aker
Remove typedef.
1108
  ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
1 by brian
clean slate
1109
1110
  current_position= next_position;
1111
1112
  /* don't scan an empty file */
1113
  if (!local_saved_data_file_length)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1114
    return(HA_ERR_END_OF_FILE);
1 by brian
clean slate
1115
1116
  if ((rc= find_current_row(buf)))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1117
    return(rc);
1 by brian
clean slate
1118
1119
  stats.records++;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1120
  return(0);
1 by brian
clean slate
1121
}
1122
1123
/*
1124
  In the case of an order by rows will need to be sorted.
1125
  ::position() is called after each call to ::rnd_next(),
1126
  the data it stores is to a byte array. You can store this
1127
  data via my_store_ptr(). ref_length is a variable defined to the
1128
  class that is the sizeof() of position being stored. In our case
1129
  its just a position. Look at the bdb code if you want to see a case
1130
  where something other then a number is stored.
1131
*/
653 by Brian Aker
More solaris bits
1132
void ha_tina::position(const unsigned char *)
1 by brian
clean slate
1133
{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1134
  internal::my_store_ptr(ref, ref_length, current_position);
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1135
  return;
1 by brian
clean slate
1136
}
1137
1138
1139
/*
1140
  Used to fetch a row from a posiion stored with ::position().
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1141
  internal::my_get_ptr() retrieves the data for you.
1 by brian
clean slate
1142
*/
1143
481 by Brian Aker
Remove all of uchar.
1144
int ha_tina::rnd_pos(unsigned char * buf, unsigned char *pos)
1 by brian
clean slate
1145
{
1273.16.8 by Brian Aker
Remove typedef.
1146
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1147
  current_position= (off_t)internal::my_get_ptr(pos,ref_length);
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1148
  return(find_current_row(buf));
1 by brian
clean slate
1149
}
1150
1151
/*
1152
  ::info() is used to return information to the optimizer.
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1153
  Currently this table Cursor doesn't implement most of the fields
1 by brian
clean slate
1154
  really needed. SHOW also makes use of this data
1155
*/
653 by Brian Aker
More solaris bits
1156
int ha_tina::info(uint32_t)
1 by brian
clean slate
1157
{
1158
  /* This is a lie, but you don't want the optimizer to see zero or 1 */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1159
  if (!records_is_known && stats.records < 2)
1 by brian
clean slate
1160
    stats.records= 2;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1161
  return(0);
1 by brian
clean slate
1162
}
1163
1164
/*
1165
  Set end_pos to the last valid byte of continuous area, closest
1166
  to the given "hole", stored in the buffer. "Valid" here means,
1167
  not listed in the chain of deleted records ("holes").
1168
*/
1608.3.1 by Zimin
refactor CSV engine's tina_set
1169
bool ha_tina::get_write_pos(off_t *end_pos, vector< pair<off_t, off_t> >::iterator &closest_hole)
1 by brian
clean slate
1170
{
1608.3.1 by Zimin
refactor CSV engine's tina_set
1171
  if (closest_hole == chain.end()) /* no more chains */
1 by brian
clean slate
1172
    *end_pos= file_buff->end();
1173
  else
398.1.5 by Monty Taylor
Removed C++ includes and std namespace from global.h.
1174
    *end_pos= std::min(file_buff->end(),
1608.3.1 by Zimin
refactor CSV engine's tina_set
1175
                       closest_hole->first);
1176
  return (closest_hole != chain.end()) && (*end_pos == closest_hole->first);
1 by brian
clean slate
1177
}
1178
1179
1180
/*
1181
  Called after each table scan. In particular after deletes,
1182
  and updates. In the last case we employ chain of deleted
1183
  slots to clean up all of the dead space we have collected while
1184
  performing deletes/updates.
1185
*/
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
1186
int ha_tina::doEndTableScan()
1 by brian
clean slate
1187
{
1188
  char updated_fname[FN_REFLEN];
1189
  off_t file_buffer_start= 0;
1190
1487 by Brian Aker
More updates for memory::Root
1191
  blobroot.free_root(MYF(0));
1 by brian
clean slate
1192
  records_is_known= 1;
1193
1608.3.1 by Zimin
refactor CSV engine's tina_set
1194
  if (chain.size() > 0)
1 by brian
clean slate
1195
  {
1608.3.1 by Zimin
refactor CSV engine's tina_set
1196
    vector< pair<off_t, off_t> >::iterator ptr= chain.begin();
1 by brian
clean slate
1197
1198
    /*
1199
      Re-read the beginning of a file (as the buffer should point to the
1200
      end of file after the scan).
1201
    */
1202
    file_buff->init_buff(data_file);
1203
1204
    /*
1205
      The sort is needed when there were updates/deletes with random orders.
1206
      It sorts so that we move the firts blocks to the beginning.
1207
    */
1608.3.1 by Zimin
refactor CSV engine's tina_set
1208
    sort(chain.begin(), chain.end());
1 by brian
clean slate
1209
1210
    off_t write_begin= 0, write_end;
1211
1212
    /* create the file to write updated table if it wasn't yet created */
1213
    if (open_update_temp_file_if_needed())
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1214
      return(-1);
1 by brian
clean slate
1215
1216
    /* write the file with updated info */
1217
    while ((file_buffer_start != -1))     // while not end of file
1218
    {
1219
      bool in_hole= get_write_pos(&write_end, ptr);
1220
      off_t write_length= write_end - write_begin;
779.3.21 by Monty Taylor
Fixed solaris fixes for linux. Oh, and I also seem to have fixed some more configure stuff.
1221
      if ((uint64_t)write_length > SIZE_MAX)
779.3.18 by Monty Taylor
Cleaned up warnings up through innodb.
1222
      {
1223
        goto error;
1224
      }
1 by brian
clean slate
1225
1226
      /* if there is something to write, write it */
1227
      if (write_length)
1228
      {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1229
        if (internal::my_write(update_temp_file,
481 by Brian Aker
Remove all of uchar.
1230
                     (unsigned char*) (file_buff->ptr() +
1 by brian
clean slate
1231
                               (write_begin - file_buff->start())),
779.3.18 by Monty Taylor
Cleaned up warnings up through innodb.
1232
                     (size_t)write_length, MYF_RW))
1 by brian
clean slate
1233
          goto error;
1234
        temp_file_length+= write_length;
1235
      }
1236
      if (in_hole)
1237
      {
1238
        /* skip hole */
1608.3.1 by Zimin
refactor CSV engine's tina_set
1239
        while (file_buff->end() <= ptr->second && file_buffer_start != -1)
1 by brian
clean slate
1240
          file_buffer_start= file_buff->read_next();
1608.3.1 by Zimin
refactor CSV engine's tina_set
1241
        write_begin= ptr->second;
1242
        ++ptr;
1 by brian
clean slate
1243
      }
1244
      else
1245
        write_begin= write_end;
1246
1247
      if (write_end == file_buff->end())
1248
        file_buffer_start= file_buff->read_next(); /* shift the buffer */
1249
1250
    }
1251
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1252
    if (internal::my_sync(update_temp_file, MYF(MY_WME)) ||
1253
        internal::my_close(update_temp_file, MYF(0)))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1254
      return(-1);
1 by brian
clean slate
1255
163 by Brian Aker
Merge Monty's code.
1256
    share->update_file_opened= false;
1 by brian
clean slate
1257
1258
    if (share->tina_write_opened)
1259
    {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1260
      if (internal::my_close(share->tina_write_filedes, MYF(0)))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1261
        return(-1);
1 by brian
clean slate
1262
      /*
1263
        Mark that the writer fd is closed, so that init_tina_writer()
1264
        will reopen it later.
1265
      */
163 by Brian Aker
Merge Monty's code.
1266
      share->tina_write_opened= false;
1 by brian
clean slate
1267
    }
1268
1269
    /*
1270
      Close opened fildes's. Then move updated file in place
1271
      of the old datafile.
1272
    */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1273
    if (internal::my_close(data_file, MYF(0)) ||
1274
        internal::my_rename(internal::fn_format(updated_fname,
1275
                                                share->table_name.c_str(),
1276
                                                "", CSN_EXT,
1277
                                                MY_REPLACE_EXT | MY_UNPACK_FILENAME),
1278
                            share->data_file_name, MYF(0)))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1279
      return(-1);
1 by brian
clean slate
1280
1281
    /* Open the file again */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1282
    if (((data_file= internal::my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1283
      return(-1);
1 by brian
clean slate
1284
    /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1285
      As we reopened the data file, increase share->data_file_version
1286
      in order to force other threads waiting on a table lock and
1 by brian
clean slate
1287
      have already opened the table to reopen the data file.
1288
      That makes the latest changes become visible to them.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1289
      Update local_data_file_version as no need to reopen it in the
1 by brian
clean slate
1290
      current thread.
1291
    */
1292
    share->data_file_version++;
1293
    local_data_file_version= share->data_file_version;
1294
    /*
1295
      The datafile is consistent at this point and the write filedes is
1296
      closed, so nothing worrying will happen to it in case of a crash.
1297
      Here we record this fact to the meta-file.
1298
    */
163 by Brian Aker
Merge Monty's code.
1299
    (void)write_meta_file(share->meta_file, share->rows_recorded, false);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1300
    /*
1301
      Update local_saved_data_file_length with the real length of the
1 by brian
clean slate
1302
      data file.
1303
    */
1304
    local_saved_data_file_length= temp_file_length;
1305
  }
1306
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1307
  return(0);
1 by brian
clean slate
1308
error:
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1309
  internal::my_close(update_temp_file, MYF(0));
163 by Brian Aker
Merge Monty's code.
1310
  share->update_file_opened= false;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1311
  return(-1);
1 by brian
clean slate
1312
}
1313
1314
1315
/*
1316
  DELETE without WHERE calls this
1317
*/
1318
1319
int ha_tina::delete_all_rows()
1320
{
1321
  int rc;
1322
1323
  if (!records_is_known)
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
1324
    return(errno=HA_ERR_WRONG_COMMAND);
1 by brian
clean slate
1325
1326
  if (!share->tina_write_opened)
1327
    if (init_tina_writer())
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1328
      return(-1);
1 by brian
clean slate
1329
1330
  /* Truncate the file to zero size */
30 by Brian Aker
Large file and ftruncate() support
1331
  rc= ftruncate(share->tina_write_filedes, 0);
1 by brian
clean slate
1332
1333
  stats.records=0;
1334
  /* Update shared info */
1335
  pthread_mutex_lock(&share->mutex);
1336
  share->rows_recorded= 0;
1337
  pthread_mutex_unlock(&share->mutex);
1338
  local_saved_data_file_length= 0;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1339
  return(rc);
1 by brian
clean slate
1340
}
1341
1342
/*
1343
  Create a table. You do not want to leave the table open after a call to
1344
  this (the database will call ::open() if it needs to).
1345
*/
1346
1413 by Brian Aker
doCreateTable() was still taking a pointer instead of a session reference.
1347
int Tina::doCreateTable(Session &session,
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
1348
                        Table& table_arg,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
1349
                        const drizzled::TableIdentifier &identifier,
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
1350
                        drizzled::message::Table &create_proto)
1 by brian
clean slate
1351
{
1352
  char name_buff[FN_REFLEN];
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
1353
  int create_file;
1 by brian
clean slate
1354
1355
  /*
1356
    check columns
1357
  */
1591 by Brian Aker
Small bits of field abstraction.
1358
  const drizzled::TableShare::Fields fields(table_arg.getShare()->getFields());
1359
  for (drizzled::TableShare::Fields::const_iterator iter= fields.begin();
1360
       iter != fields.end();
1578.2.14 by Brian Aker
Additional pass through to remove raw field access.
1361
       iter++)
1 by brian
clean slate
1362
  {
1591 by Brian Aker
Small bits of field abstraction.
1363
    if (not *iter) // Historical legacy for NULL array end.
1364
      continue;
1365
1578.2.14 by Brian Aker
Additional pass through to remove raw field access.
1366
    if ((*iter)->real_maybe_null())
1 by brian
clean slate
1367
    {
1368
      my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "nullable columns");
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1369
      return(HA_ERR_UNSUPPORTED);
1 by brian
clean slate
1370
    }
1371
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1372
1 by brian
clean slate
1373
1358.1.9 by Brian Aker
Update for std::string
1374
  if ((create_file= internal::my_create(internal::fn_format(name_buff, identifier.getPath().c_str(), "", CSM_EXT,
1375
                                                            MY_REPLACE_EXT|MY_UNPACK_FILENAME), 0,
1376
                                        O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1377
    return(-1);
1 by brian
clean slate
1378
163 by Brian Aker
Merge Monty's code.
1379
  write_meta_file(create_file, 0, false);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1380
  internal::my_close(create_file, MYF(0));
1 by brian
clean slate
1381
1358.1.9 by Brian Aker
Update for std::string
1382
  if ((create_file= internal::my_create(internal::fn_format(name_buff, identifier.getPath().c_str(), "", CSV_EXT,
1383
                                                            MY_REPLACE_EXT|MY_UNPACK_FILENAME),0,
1384
                                        O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1385
    return(-1);
1 by brian
clean slate
1386
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1387
  internal::my_close(create_file, MYF(0));
1 by brian
clean slate
1388
1413 by Brian Aker
doCreateTable() was still taking a pointer instead of a session reference.
1389
  session.storeTableMessage(identifier, create_proto);
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
1390
1391
  return 0;
1 by brian
clean slate
1392
}
1393
1394
1228.1.5 by Monty Taylor
Merged in some naming things.
1395
DRIZZLE_DECLARE_PLUGIN
1 by brian
clean slate
1396
{
1241.10.2 by Monty Taylor
Added support for embedding the drizzle version number in the plugin file.
1397
  DRIZZLE_VERSION_ID,
1 by brian
clean slate
1398
  "CSV",
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
1399
  "1.0",
1 by brian
clean slate
1400
  "Brian Aker, MySQL AB",
1401
  "CSV storage engine",
1402
  PLUGIN_LICENSE_GPL,
1403
  tina_init_func, /* Plugin Init */
1404
  NULL,                       /* system variables                */
1405
  NULL                        /* config options                  */
1406
}
1228.1.5 by Monty Taylor
Merged in some naming things.
1407
DRIZZLE_DECLARE_PLUGIN_END;
1 by brian
clean slate
1408