~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/csv/ha_tina.cc

  • Committer: Brian Aker
  • Date: 2010-09-13 21:43:18 UTC
  • mto: (1768.2.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 1770.
  • Revision ID: brian@tangent.org-20100913214318-b5tdvn64qvtvybnj
Use full path for opening up directory files when checking for types.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
  You should have received a copy of the GNU General Public License
13
13
  along with this program; if not, write to the Free Software
14
 
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/*
17
17
  Make sure to look at ha_tina.h for more details.
112
112
    pthread_mutex_destroy(&tina_mutex);
113
113
  }
114
114
 
115
 
  virtual Cursor *create(Table &table)
 
115
  virtual Cursor *create(TableShare &table)
116
116
  {
117
117
    return new ha_tina(*this, table);
118
118
  }
130
130
                           const drizzled::TableIdentifier &identifier,
131
131
                           drizzled::message::Table &table_message);
132
132
 
 
133
  /* Temp only engine, so do not return values. */
 
134
  void doGetTableNames(drizzled::CachedDirectory &, const SchemaIdentifier&, set<string>&) { };
 
135
 
133
136
  int doDropTable(Session&, const drizzled::TableIdentifier &identifier);
134
137
  TinaShare *findOpenTable(const string table_name);
135
138
  void addOpenTable(const string &table_name, TinaShare *);
144
147
 
145
148
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
146
149
                             const drizzled::SchemaIdentifier &schema_identifier,
147
 
                             drizzled::TableIdentifier::vector &set_of_identifiers);
 
150
                             drizzled::TableIdentifiers &set_of_identifiers);
148
151
};
149
152
 
150
153
void Tina::doGetTableIdentifiers(drizzled::CachedDirectory&,
151
154
                                 const drizzled::SchemaIdentifier&,
152
 
                                 drizzled::TableIdentifier::vector&)
 
155
                                 drizzled::TableIdentifiers&)
153
156
{
154
157
}
155
158
 
167
170
    }
168
171
  }
169
172
 
170
 
  session.getMessageCache().renameTableMessage(from, to);
 
173
  session.renameTableMessage(from, to);
171
174
 
172
175
  return error;
173
176
}
174
177
 
175
178
bool Tina::doDoesTableExist(Session &session, const drizzled::TableIdentifier &identifier)
176
179
{
177
 
  return session.getMessageCache().doesTableMessageExist(identifier);
 
180
  return session.doesTableMessageExist(identifier);
178
181
}
179
182
 
180
183
 
183
186
{
184
187
  int error= 0;
185
188
  int enoent_or_zero= ENOENT;                   // Error if no file was deleted
 
189
  char buff[FN_REFLEN];
186
190
 
187
191
  for (const char **ext= bas_ext(); *ext ; ext++)
188
192
  {
189
 
    std::string full_name= identifier.getPath();
190
 
    full_name.append(*ext);
191
 
 
192
 
    if (internal::my_delete_with_symlink(full_name.c_str(), MYF(0)))
 
193
    internal::fn_format(buff, identifier.getPath().c_str(), "", *ext,
 
194
                        MY_UNPACK_FILENAME|MY_APPEND_EXT);
 
195
    if (internal::my_delete_with_symlink(buff, MYF(0)))
193
196
    {
194
197
      if ((error= errno) != ENOENT)
195
198
        break;
196
199
    }
197
200
    else
198
 
    {
199
201
      enoent_or_zero= 0;                        // No error for ENOENT
200
 
    }
201
202
    error= enoent_or_zero;
202
203
  }
203
204
 
204
 
  session.getMessageCache().removeTableMessage(identifier);
 
205
  session.removeTableMessage(identifier);
205
206
 
206
207
  return error;
207
208
}
232
233
                               const drizzled::TableIdentifier &identifier,
233
234
                               drizzled::message::Table &table_message)
234
235
{
235
 
  if (session.getMessageCache().getTableMessage(identifier, table_message))
 
236
  if (session.getTableMessage(identifier, table_message))
236
237
    return EEXIST;
237
238
 
238
239
  return ENOENT;
253
254
 
254
255
 
255
256
 
256
 
TinaShare::TinaShare(const std::string &table_name_arg) : 
257
 
  table_name(table_name_arg),
258
 
  data_file_name(table_name_arg),
259
 
  use_count(0),
260
 
  saved_data_file_length(0),
261
 
  update_file_opened(false),
262
 
  tina_write_opened(false),
263
 
  crashed(false),
264
 
  rows_recorded(0),
265
 
  data_file_version(0)
 
257
TinaShare::TinaShare(const char *table_name_arg)
 
258
  : table_name(table_name_arg), use_count(0), saved_data_file_length(0),
 
259
    update_file_opened(false), tina_write_opened(false),
 
260
    crashed(false), rows_recorded(0), data_file_version(0)
266
261
{
267
 
  data_file_name.append(CSV_EXT);
 
262
  thr_lock_init(&lock);
 
263
  internal::fn_format(data_file_name, table_name_arg, "", CSV_EXT,
 
264
            MY_REPLACE_EXT|MY_UNPACK_FILENAME);
268
265
}
269
266
 
270
267
TinaShare::~TinaShare()
271
268
{
 
269
  lock.deinit();
272
270
  pthread_mutex_destroy(&mutex);
273
271
}
274
272
 
275
273
/*
276
274
  Simple lock controls.
277
275
*/
278
 
TinaShare *ha_tina::get_share(const std::string &table_name)
 
276
TinaShare *ha_tina::get_share(const char *table_name)
279
277
{
280
278
  pthread_mutex_lock(&tina_mutex);
281
279
 
282
 
  Tina *a_tina= static_cast<Tina *>(getEngine());
 
280
  Tina *a_tina= static_cast<Tina *>(engine);
283
281
  share= a_tina->findOpenTable(table_name);
284
282
 
285
 
  std::string meta_file_name;
 
283
  char meta_file_name[FN_REFLEN];
286
284
  struct stat file_stat;
287
285
 
288
286
  /*
299
297
      return NULL;
300
298
    }
301
299
 
302
 
    meta_file_name.assign(table_name);
303
 
    meta_file_name.append(CSM_EXT);
 
300
    internal::fn_format(meta_file_name, table_name, "", CSM_EXT,
 
301
              MY_REPLACE_EXT|MY_UNPACK_FILENAME);
304
302
 
305
 
    if (stat(share->data_file_name.c_str(), &file_stat))
 
303
    if (stat(share->data_file_name, &file_stat))
306
304
    {
307
305
      pthread_mutex_unlock(&tina_mutex);
308
306
      delete share;
321
319
      Usually this will result in auto-repair, and we will get a good
322
320
      meta-file in the end.
323
321
    */
324
 
    if ((share->meta_file= internal::my_open(meta_file_name.c_str(),
 
322
    if ((share->meta_file= internal::my_open(meta_file_name,
325
323
                                             O_RDWR|O_CREAT, MYF(0))) == -1)
326
324
      share->crashed= true;
327
325
 
450
448
  (void)write_meta_file(share->meta_file, share->rows_recorded, true);
451
449
 
452
450
  if ((share->tina_write_filedes=
453
 
        internal::my_open(share->data_file_name.c_str(), O_RDWR|O_APPEND, MYF(0))) == -1)
 
451
        internal::my_open(share->data_file_name, O_RDWR|O_APPEND, MYF(0))) == -1)
454
452
  {
455
453
    share->crashed= true;
456
454
    return(1);
481
479
      share->tina_write_opened= false;
482
480
    }
483
481
 
484
 
    Tina *a_tina= static_cast<Tina *>(getEngine());
 
482
    Tina *a_tina= static_cast<Tina *>(engine);
485
483
    a_tina->deleteOpenTable(share->table_name);
486
484
    delete share;
487
485
  }
530
528
 
531
529
 
532
530
 
533
 
ha_tina::ha_tina(drizzled::plugin::StorageEngine &engine_arg, Table &table_arg)
 
531
ha_tina::ha_tina(drizzled::plugin::StorageEngine &engine_arg, TableShare &table_arg)
534
532
  :Cursor(engine_arg, table_arg),
535
533
  /*
536
534
    These definitions are found in Cursor.h
557
555
 
558
556
  buffer.length(0);
559
557
 
560
 
  for (Field **field= getTable()->getFields() ; *field ; field++)
 
558
  for (Field **field= table->getFields() ; *field ; field++)
561
559
  {
562
560
    const char *ptr;
563
561
    const char *end_ptr;
597
595
        {
598
596
          buffer.append('\\');
599
597
          buffer.append('"');
600
 
          (void) *ptr++;
 
598
          *ptr++;
601
599
        }
602
600
        else if (*ptr == '\r')
603
601
        {
604
602
          buffer.append('\\');
605
603
          buffer.append('r');
606
 
          (void) *ptr++;
 
604
          *ptr++;
607
605
        }
608
606
        else if (*ptr == '\\')
609
607
        {
610
608
          buffer.append('\\');
611
609
          buffer.append('\\');
612
 
          (void) *ptr++;
 
610
          *ptr++;
613
611
        }
614
612
        else if (*ptr == '\n')
615
613
        {
616
614
          buffer.append('\\');
617
615
          buffer.append('n');
618
 
          (void) *ptr++;
 
616
          *ptr++;
619
617
        }
620
618
        else
621
619
          buffer.append(*ptr++);
675
673
 
676
674
  error= HA_ERR_CRASHED_ON_USAGE;
677
675
 
678
 
  memset(buf, 0, getTable()->getShare()->null_bytes);
 
676
  memset(buf, 0, table->getShare()->null_bytes);
679
677
 
680
 
  for (Field **field= getTable()->getFields() ; *field ; field++)
 
678
  for (Field **field=table->getFields() ; *field ; field++)
681
679
  {
682
680
    char curr_char;
683
681
 
746
744
    {
747
745
      /* This masks a bug in the logic for a SELECT * */
748
746
      (*field)->setWriteSet();
749
 
      if ((*field)->store_and_check(CHECK_FIELD_WARN, buffer.c_ptr(), buffer.length(), buffer.charset()))
750
 
      {
 
747
      if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset(),
 
748
                          CHECK_FIELD_WARN))
751
749
        goto err;
752
 
      }
753
750
 
754
751
      if ((*field)->flags & BLOB_FLAG)
755
752
      {
784
781
*/
785
782
int ha_tina::doOpen(const TableIdentifier &identifier, int , uint32_t )
786
783
{
787
 
  if (not (share= get_share(identifier.getPath().c_str())))
 
784
  if (!(share= get_share(identifier.getPath().c_str())))
788
785
    return(ENOENT);
789
786
 
790
787
  if (share->crashed)
794
791
  }
795
792
 
796
793
  local_data_file_version= share->data_file_version;
797
 
  if ((data_file= internal::my_open(share->data_file_name.c_str(), O_RDONLY, MYF(0))) == -1)
 
794
  if ((data_file= internal::my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1)
798
795
    return(0);
799
796
 
800
797
  /*
802
799
    so that they could save/update local_saved_data_file_length value
803
800
    during locking. This is needed to enable concurrent inserts.
804
801
  */
 
802
  lock.init(&share->lock);
805
803
  ref_length=sizeof(off_t);
806
804
 
807
805
  return(0);
957
955
  {
958
956
    local_data_file_version= share->data_file_version;
959
957
    if (internal::my_close(data_file, MYF(0)) ||
960
 
        (data_file= internal::my_open(share->data_file_name.c_str(), O_RDONLY, MYF(0))) == -1)
 
958
        (data_file= internal::my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1)
961
959
      return 1;
962
960
  }
963
961
  file_buff->init_buff(data_file);
1110
1108
*/
1111
1109
int ha_tina::doEndTableScan()
1112
1110
{
 
1111
  char updated_fname[FN_REFLEN];
1113
1112
  off_t file_buffer_start= 0;
1114
1113
 
1115
1114
  blobroot.free_root(MYF(0));
1194
1193
      Close opened fildes's. Then move updated file in place
1195
1194
      of the old datafile.
1196
1195
    */
1197
 
    std::string rename_file= share->table_name;
1198
 
    rename_file.append(CSN_EXT);
1199
1196
    if (internal::my_close(data_file, MYF(0)) ||
1200
 
        internal::my_rename(rename_file.c_str(),
1201
 
                            share->data_file_name.c_str(), MYF(0)))
 
1197
        internal::my_rename(internal::fn_format(updated_fname,
 
1198
                                                share->table_name.c_str(),
 
1199
                                                "", CSN_EXT,
 
1200
                                                MY_REPLACE_EXT | MY_UNPACK_FILENAME),
 
1201
                            share->data_file_name, MYF(0)))
1202
1202
      return(-1);
1203
1203
 
1204
1204
    /* Open the file again */
1205
 
    if (((data_file= internal::my_open(share->data_file_name.c_str(), O_RDONLY, MYF(0))) == -1))
 
1205
    if (((data_file= internal::my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1))
1206
1206
      return(-1);
1207
1207
    /*
1208
1208
      As we reopened the data file, increase share->data_file_version
1309
1309
 
1310
1310
  internal::my_close(create_file, MYF(0));
1311
1311
 
1312
 
  session.getMessageCache().storeTableMessage(identifier, create_proto);
 
1312
  session.storeTableMessage(identifier, create_proto);
1313
1313
 
1314
1314
  return 0;
1315
1315
}