~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Monty Taylor
  • Date: 2009-03-12 20:16:13 UTC
  • mto: This revision was merged to the branch mainline in revision 934.
  • Revision ID: mordred@inaugust.com-20090312201613-5tqkgezp7696kcia
Removing hand-done completion hash functions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
125
125
#define vidattr(A) {}      // Can't get this to work
126
126
#endif
127
127
 
128
 
#include "completion_hash.h"
 
128
#include <iostream>
 
129
#include <functional>
 
130
#include <map>
129
131
 
130
132
using namespace std;
131
133
 
149
151
} STATUS;
150
152
 
151
153
 
152
 
static HashTable ht;
 
154
static map<string, string>::iterator completion_iter;
 
155
static map<string, string> completion_map;
153
156
static char **defaults_argv;
154
157
 
155
158
enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
197
200
static char default_pager[FN_REFLEN];
198
201
static char pager[FN_REFLEN], outfile[FN_REFLEN];
199
202
static FILE *PAGER, *OUTFILE;
200
 
static MEM_ROOT hash_mem_root;
201
203
static uint32_t prompt_counter;
202
204
static char delimiter[16]= DEFAULT_DELIMITER;
203
205
static uint32_t delimiter_length= 1;
1095
1097
    my_end(0);
1096
1098
    exit(1);
1097
1099
  }
1098
 
  completion_hash_init(&ht, 128);
1099
 
  init_alloc_root(&hash_mem_root, 16384, 0);
1100
1100
  memset(&drizzle, 0, sizeof(drizzle));
1101
1101
  if (sql_connect(current_host,current_db,current_user,opt_password,
1102
1102
                  opt_silent))
1193
1193
      my_rename(histfile_tmp, histfile, MYF(MY_WME));
1194
1194
  }
1195
1195
  batch_readline_end(status.line_buff);
1196
 
  completion_hash_free(&ht);
1197
 
  free_root(&hash_mem_root,MYF(0));
1198
1196
 
1199
1197
  if (sig >= 0)
1200
1198
    put_info(sig ? _("Aborted") : _("Bye"), INFO_RESULT,0,0);
2221
2219
    return (char**) 0;
2222
2220
}
2223
2221
 
 
2222
inline string lower_string(const string &from_string)
 
2223
{
 
2224
  string to_string= from_string;
 
2225
  transform(to_string.begin(), to_string.end(),
 
2226
            to_string.begin(), ::tolower);
 
2227
  return to_string;
 
2228
}
 
2229
 
 
2230
class CompletionMatch :
 
2231
  public unary_function<const string&, bool>
 
2232
{
 
2233
  string match_text; 
 
2234
public:
 
2235
  CompletionMatch(string text) : match_text(text)
 
2236
  {
 
2237
    transform(match_text.begin(), match_text.end(),
 
2238
              match_text.begin(), ::tolower);
 
2239
  }
 
2240
  inline bool operator() (const pair<string,string> &match_against) const
 
2241
  {
 
2242
    string sub_match=
 
2243
      lower_string(match_against.first.substr(0,match_text.size()));
 
2244
    return (sub_match == match_text);
 
2245
/*(cout << "Matching " << match_text << " against " << match_against.first <<end;
 
2246
    if (match_text.compare(0, match_text.size(),
 
2247
                           match_against.first, 0,
 
2248
                           match_text.size()) == 0)
 
2249
      return true;
 
2250
    return false; */
 
2251
  }
 
2252
};
 
2253
 
 
2254
 
 
2255
 
2224
2256
extern "C"
2225
 
char *new_command_generator(const char *text,int state)
 
2257
char *new_command_generator(const char *text, int state)
2226
2258
{
2227
 
  static int textlen;
2228
 
  char *ptr;
2229
 
  static Bucket *b;
2230
 
  static entry *e;
2231
 
  static uint32_t i;
2232
2259
 
2233
2260
  if (!state)
2234
 
    textlen=(uint32_t) strlen(text);
2235
 
 
2236
 
  if (textlen>0)
2237
 
  {            /* lookup in the hash */
2238
 
    if (!state)
2239
 
    {
2240
 
      uint32_t len;
2241
 
 
2242
 
      b = find_all_matches(&ht,text,(uint32_t) strlen(text),&len);
2243
 
      if (!b)
2244
 
        return NULL;
2245
 
      e = b->pData;
2246
 
    }
2247
 
 
2248
 
    if (e)
2249
 
    {
2250
 
      ptr= strdup(e->str);
2251
 
      e = e->pNext;
2252
 
      return ptr;
2253
 
    }
2254
 
  }
2255
 
  else
2256
 
  { /* traverse the entire hash, ugly but works */
2257
 
 
2258
 
    if (!state)
2259
 
    {
2260
 
      /* find the first used bucket */
2261
 
      for (i=0 ; i < ht.nTableSize ; i++)
2262
 
      {
2263
 
        if (ht.arBuckets[i])
2264
 
        {
2265
 
          b = ht.arBuckets[i];
2266
 
          e = b->pData;
2267
 
          break;
2268
 
        }
2269
 
      }
2270
 
    }
2271
 
    ptr= NULL;
2272
 
    while (e && !ptr)
2273
 
    {          /* find valid entry in bucket */
2274
 
      if ((uint32_t) strlen(e->str) == b->nKeyLength)
2275
 
        ptr = strdup(e->str);
2276
 
      /* find the next used entry */
2277
 
      e = e->pNext;
2278
 
      if (!e)
2279
 
      { /* find the next used bucket */
2280
 
        b = b->pNext;
2281
 
        if (!b)
2282
 
        {
2283
 
          for (i++ ; i<ht.nTableSize; i++)
2284
 
          {
2285
 
            if (ht.arBuckets[i])
2286
 
            {
2287
 
              b = ht.arBuckets[i];
2288
 
              e = b->pData;
2289
 
              break;
2290
 
            }
2291
 
          }
2292
 
        }
2293
 
        else
2294
 
          e = b->pData;
2295
 
      }
2296
 
    }
2297
 
    if (ptr)
2298
 
      return ptr;
2299
 
  }
2300
 
  return NULL;
 
2261
  {
 
2262
cout << "trying to find: " << text << endl;
 
2263
    string match_text(text);
 
2264
    if (match_text.size() == 0)
 
2265
    {
 
2266
/*cout << "doing the big one " << endl;
 
2267
      for(completion_iter= completion_map.begin();
 
2268
          completion_iter!= completion_map.end();
 
2269
          completion_iter++)
 
2270
cout << "SET CONTAINS: " << (*completion_iter).second << endl; */
 
2271
      completion_iter= completion_map.begin();
 
2272
    }
 
2273
    else
 
2274
      completion_iter= find_if(completion_map.begin(), completion_map.end(),
 
2275
                               CompletionMatch(match_text));
 
2276
  }
 
2277
  if (completion_iter == completion_map.end())
 
2278
    return NULL;
 
2279
  char *result= (char *)malloc((*completion_iter).second.size()+1);
 
2280
  strcpy(result, (*completion_iter).second.c_str());
 
2281
  completion_iter++;
 
2282
  return result;
2301
2283
}
2302
2284
 
2303
 
 
2304
2285
/* Build up the completion hash */
2305
2286
 
2306
2287
static void build_completion_hash(bool rehash, bool write_info)
2308
2289
  COMMANDS *cmd=commands;
2309
2290
  DRIZZLE_RES *databases=0,*tables=0;
2310
2291
  DRIZZLE_RES *fields;
2311
 
  static char ***field_names= 0;
2312
2292
  DRIZZLE_ROW database_row,table_row;
2313
2293
  DRIZZLE_FIELD *sql_field;
2314
 
  char buf[NAME_LEN*2+2];     // table name plus field name plus 2
2315
 
  int i,j,num_fields;
 
2294
  string tmp_str, tmp_str_lower;
2316
2295
 
2317
2296
 
2318
2297
  if (status.batch || quick || !current_db)
2320
2299
  if (!rehash)
2321
2300
    return;
2322
2301
 
2323
 
  /* Free old used memory */
2324
 
  if (field_names)
2325
 
    field_names=0;
2326
 
  completion_hash_clean(&ht);
2327
 
  free_root(&hash_mem_root,MYF(0));
 
2302
  completion_map.clear();
2328
2303
 
2329
2304
  /* hash this file's known subset of SQL commands */
2330
2305
  while (cmd->name) {
2331
 
    add_word(&ht,(char*) cmd->name);
 
2306
    tmp_str= cmd->name;
 
2307
    tmp_str_lower= lower_string(tmp_str);
 
2308
    completion_map[tmp_str_lower]= tmp_str;
2332
2309
    cmd++;
2333
2310
  }
2334
2311
 
2343
2320
    {
2344
2321
      while ((database_row=drizzleclient_fetch_row(databases)))
2345
2322
      {
2346
 
        char *str=strdup_root(&hash_mem_root, (char*) database_row[0]);
2347
 
        if (str)
2348
 
          add_word(&ht,(char*) str);
 
2323
        tmp_str= database_row[0];
 
2324
        tmp_str_lower= lower_string(tmp_str);
 
2325
        completion_map[tmp_str_lower]= tmp_str;
2349
2326
      }
2350
2327
      drizzleclient_free_result(databases);
2351
2328
    }
2365
2342
      }
2366
2343
      while ((table_row=drizzleclient_fetch_row(tables)))
2367
2344
      {
2368
 
        char *str=strdup_root(&hash_mem_root, (char*) table_row[0]);
2369
 
        if (str &&
2370
 
            !completion_hash_exists(&ht,(char*) str, (uint32_t) strlen(str)))
2371
 
          add_word(&ht,str);
 
2345
        tmp_str= table_row[0];
 
2346
        tmp_str_lower= lower_string(tmp_str);
 
2347
        completion_map[tmp_str_lower]= tmp_str;
2372
2348
      }
2373
2349
    }
2374
2350
  }
2379
2355
    return;
2380
2356
  }
2381
2357
  drizzleclient_data_seek(tables,0);
2382
 
  if (!(field_names= (char ***) alloc_root(&hash_mem_root,sizeof(char **) *
2383
 
                                           (uint32_t) (drizzleclient_num_rows(tables)+1))))
2384
 
  {
2385
 
    drizzleclient_free_result(tables);
2386
 
    return;
2387
 
  }
2388
 
  i=0;
 
2358
 
2389
2359
  while ((table_row=drizzleclient_fetch_row(tables)))
2390
2360
  {
2391
2361
    string query;
2399
2369
      fields= drizzleclient_store_result(&drizzle);
2400
2370
      if (fields) 
2401
2371
      {
2402
 
        num_fields=drizzleclient_num_fields(fields);
2403
 
        if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
2404
 
                                                    sizeof(char *) *
2405
 
                                                    (num_fields*2+1))))
2406
 
        {
2407
 
          drizzleclient_free_result(fields);
2408
 
          break;
2409
 
        }
2410
 
        field_names[i][num_fields*2]= '\0';
2411
 
        j= 0;
2412
2372
        while ((sql_field=drizzleclient_fetch_field(fields)))
2413
2373
        {
2414
 
          sprintf(buf,"%.64s.%.64s",table_row[0],sql_field->name);
2415
 
          field_names[i][j] = strdup_root(&hash_mem_root,buf);
2416
 
          add_word(&ht,field_names[i][j]);
2417
 
          field_names[i][num_fields+j] = strdup_root(&hash_mem_root,
2418
 
                                                     sql_field->name);
2419
 
          if (!completion_hash_exists(&ht,field_names[i][num_fields+j],
2420
 
                                      (uint32_t) strlen(field_names[i][num_fields+j])))
2421
 
            add_word(&ht,field_names[i][num_fields+j]);
2422
 
          j++;
 
2374
          tmp_str=table_row[0];
 
2375
          tmp_str.append(".");
 
2376
          tmp_str.append(sql_field->name);
 
2377
          tmp_str_lower= lower_string(tmp_str);
 
2378
          completion_map[tmp_str_lower]= tmp_str;
 
2379
 
 
2380
          tmp_str=sql_field->name;
 
2381
          tmp_str_lower= lower_string(tmp_str);
 
2382
          completion_map[tmp_str_lower]= tmp_str;
 
2383
 
2423
2384
        }
2424
2385
        drizzleclient_free_result(fields);
2425
2386
      }
2426
2387
    }
2427
 
    else
2428
 
      field_names[i]= 0;
2429
 
 
2430
 
    i++;
2431
2388
  }
2432
2389
  drizzleclient_free_result(tables);
2433
 
  field_names[i]=0;        // End pointer
2434
 
  return;
 
2390
  completion_iter= completion_map.begin();
2435
2391
}
2436
2392
 
2437
2393
/* for gnu readline */