186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project/*
286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * Copyright 2001-2004 Brandon Long
386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * All Rights Reserved.
486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *
586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * ClearSilver Templating System
686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *
786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * This code is made available under the terms of the ClearSilver License.
886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * http://www.clearsilver.net/license.hdf
986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *
1086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project */
1186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project/*
1286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * The wdb is a wrapper around the sleepycat db library which adds
1386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * a relatively simple data/column definition.  In many respects, this
1486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * code is way more complicated than it ever needed to be, but it works,
1586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * so I'm loathe to "fix" it.
1686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *
1786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * One of they key features of this is the ability to update the
1886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * "schema" of the wdb without changing all of the existing rows of
1986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * data.
2086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project */
2186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
2286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include "cs_config.h"
2386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
2486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include <unistd.h>
2586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include <stdlib.h>
2686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include <stdarg.h>
2786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include <errno.h>
2886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include <string.h>
2986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include <limits.h>
3086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include <db.h>
3186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include <ctype.h>
3286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
3386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include "neo_misc.h"
3486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include "neo_err.h"
3586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include "dict.h"
3686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include "ulist.h"
3786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include "skiplist.h"
3886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#include "wdb.h"
3986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
4086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
4186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define DEFN_VERSION_1 "WDB-VERSION-200006301"
4286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define PACK_VERSION_1 1
4386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
4486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic void string_rstrip (char *s)
4586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
4686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  size_t len;
4786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
4886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  len = strlen(s);
4986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  len--;
5086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  while (len > 0 && isspace(s[len]))
5186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
5286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    s[len] = '\0';
5386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    len--;
5486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
5586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return;
5686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
5786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
5886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic int to_hex (unsigned char ch, unsigned char *s)
5986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
6086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  unsigned int uvalue = ch;
6186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
6286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  s[1] = "0123456789ABCDEF"[uvalue % 16];
6386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  uvalue = (uvalue / 16);  s[0] = "0123456789ABCDEF"[uvalue % 16];
6486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return 0;
6586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
6686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
6786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectint Index_hex[128] = {
6886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
6986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
7086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
7186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,
7286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
7386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,  -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
7486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
7586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project};
7686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
7786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define hexval(c) Index_hex[(unsigned int)(c)]
7886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
7986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project/* Encoding means any non-printable characters and : and % */
8086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic NEOERR *wdb_encode_str_alloc (const char *s, char **o)
8186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
8286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int x = 0;
8386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int c = 0;
8486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *out;
8586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  unsigned char ch;
8686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
8786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  while (s[x])
8886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
8986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    ch = (unsigned char) s[x];
9086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if ((ch < 32) || (ch > 127) || (ch == ':') || (ch == '%') || isspace(ch))
9186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      c++;
9286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    x++;
9386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
9486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
9586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  out = (char *) malloc (sizeof (char) * (x + c * 3) + 1);
9686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (out == NULL)
9786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM,
9886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Unable to allocate memory for encoding %s", s);
9986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
10086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  x = 0;
10186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  c = 0;
10286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
10386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *o = out;
10486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
10586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  while (s[x])
10686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
10786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    ch = (unsigned char) s[x];
10886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if ((ch < 32) || (ch > 127) || (ch == ':') || (ch == '%') || isspace(ch))
10986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
11086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      out[c++] = '%';
11186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      to_hex (s[x], &out[c]);
11286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      c+=2;
11386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
11486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    else
11586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
11686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      out[c++] = s[x];
11786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
11886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    x++;
11986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
12086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  out[c] = '\0';
12186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
12286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
12386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
12486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
12586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic NEOERR *wdb_decode_str_alloc (const char *s, char **o)
12686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
12786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int x = 0;
12886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int c = 0;
12986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *out;
13086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  unsigned char ch;
13186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
13286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
13386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  x = strlen(s);
13486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* Overkill, the decoded string will be smaller */
13586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  out = (char *) malloc (sizeof (char) * (x + 1));
13686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (out == NULL)
13786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM,
13886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Unable to allocate memory for decoding %s", s);
13986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
14086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  x = 0;
14186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  c = 0;
14286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
14386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  while (s[x])
14486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
14586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (s[x] == '%')
14686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
14786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      x++;
14886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      ch = hexval(s[x]) << 4;
14986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      x++;
15086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      ch |= hexval(s[x]);
15186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      out[c++] = ch;
15286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
15386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    else
15486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
15586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      out[c++] = s[x];
15686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
15786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    x++;
15886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
15986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  out[c] = '\0';
16086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *o = out;
16186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
16286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
16386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
16486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
16586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic void free_cb (void *value, void *rock)
16686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
16786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (value);
16886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
16986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
17086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic void free_col_cb (void *value, void *rock)
17186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
17286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *col;
17386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
17486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  col = (WDBColumn *)value;
17586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
17686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (col->name);
17786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (col);
17886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
17986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
18086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic NEOERR *wdb_alloc (WDB **wdb, int flags)
18186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
18286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDB *my_wdb;
18386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
18486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
18586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_wdb = (WDB *) calloc (1, sizeof (WDB));
18686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
18786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb == NULL)
18886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM, "Unable to allocate memory for WDB");
18986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
19086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  do
19186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
19286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = dictCreate (&(my_wdb->attrs), 0, 2, 5, 0, 0, free_cb, NULL);
19386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err != STATUS_OK) break;
19486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = dictCreate (&(my_wdb->cols), 0, 2, 5, 0, 0, free_col_cb, NULL);
19586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err != STATUS_OK) break;
19686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = uListInit (&(my_wdb->cols_l), 0, 0);
19786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err != STATUS_OK) break;
19886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = skipNewList(&(my_wdb->ondisk), 0, 4, 2, 0, NULL, NULL);
19986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err != STATUS_OK) break;
20086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
20186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    *wdb = my_wdb;
20286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
20386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return STATUS_OK;
20486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  } while (0);
20586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
20686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb_destroy(&my_wdb);
20786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return nerr_pass (err);
20886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
20986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
21086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
21186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define STATE_REQUIRED 1
21286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define STATE_ATTRIBUTES 2
21386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define STATE_COLUMN_DEF 3
21486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
21586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic NEOERR *wdb_load_defn_v1 (WDB *wdb, FILE *fp)
21686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
21786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char line[1024];
21886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int state = 1;
21986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *k, *v;
22086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
22186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int colindex = 1;
22286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *col;
22386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
22486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  while (fgets(line, sizeof(line), fp) != NULL)
22586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
22686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    string_rstrip(line);
22786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    switch (state)
22886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
22986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      case STATE_REQUIRED:
23086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	if (!strcmp(line, "attributes"))
23186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  state = STATE_ATTRIBUTES;
23286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	else if (!strcmp(line, "columns"))
23386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  state = STATE_COLUMN_DEF;
23486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	else
23586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	{
23686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  k = line;
23786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  v = strchr(line, ':');
23886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  /* HACK */
23986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  if (!strcmp(k, "name") && ((v == NULL) || (v[1] == '\0')))
24086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  {
24186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    v = "dNone";
24286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  }
24386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  else
24486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  {
24586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    if (v == NULL)
24686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	      return nerr_raise (NERR_PARSE, "Error parsing %s", line);
24786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    if (v[1] == '\0')
24886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	      return nerr_raise (NERR_PARSE, "Error parsing %s", line);
24986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  }
25086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  v[0] = '\0';
25186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  v++;
25286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  if (!strcmp(k, "key"))
25386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  {
25486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    err = wdb_decode_str_alloc (v, &(wdb->key));
25586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    if (err) return nerr_pass(err);
25686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  }
25786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  else if (!strcmp(k, "name"))
25886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  {
25986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    err = wdb_decode_str_alloc (v, &(wdb->name));
26086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    if (err) return nerr_pass(err);
26186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  }
26286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  else if (!strcmp(k, "ondisk"))
26386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  {
26486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    wdb->last_ondisk = atoi (v);
26586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  }
26686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	}
26786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	break;
26886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      case STATE_ATTRIBUTES:
26986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	if (!strcmp(line, "columns"))
27086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  state = STATE_COLUMN_DEF;
27186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	else
27286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	{
27386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  k = line;
27486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  v = strchr(line, ':');
27586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  if (v == NULL)
27686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    return nerr_raise (NERR_PARSE, "Error parsing %s", line);
27786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  v[0] = '\0';
27886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  v++;
27986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  err = wdb_decode_str_alloc (k, &k);
28086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  if (err) return nerr_pass(err);
28186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  err = wdb_decode_str_alloc (v, &v);
28286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  if (err) return nerr_pass(err);
28386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  err = dictSetValue(wdb->attrs, k, v);
28486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  free(k);
28586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  if (err)
28686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    return nerr_pass_ctx(err, "Error parsing %s", line);
28786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	}
28886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	break;
28986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      case STATE_COLUMN_DEF:
29086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	k = line;
29186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	v = strchr(line, ':');
29286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	if (v == NULL)
29386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  return nerr_raise (NERR_PARSE, "Error parsing %s", line);
29486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	if (v[1] == '\0')
29586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  return nerr_raise (NERR_PARSE, "Error parsing %s", line);
29686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	v[0] = '\0';
29786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	v++;
29886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	err = wdb_decode_str_alloc (k, &k);
29986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	if (err) return nerr_pass(err);
30086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	col = (WDBColumn *) calloc (1, sizeof (WDBColumn));
30186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	col->name = k;
30286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	col->inmem_index = colindex++;
30386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	col->type = *v;
30486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	v+=2;
30586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	col->ondisk_index = atoi(v);
30686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	err = dictSetValue(wdb->cols, k, col);
30786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	if (err)
30886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  return nerr_raise (NERR_PARSE, "Error parsing %s", line);
30986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	err = uListAppend(wdb->cols_l, col);
31086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	if (err) return nerr_pass(err);
31186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	/* stupid skiplist will assert */
31286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	if (col->ondisk_index == 0)
31386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	{
31486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  return nerr_raise (NERR_ASSERT, "Invalid ondisk mapping for %s", k);
31586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	}
31686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	err = skipInsert (wdb->ondisk, col->ondisk_index,
31786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    (void *)(col->inmem_index), 0);
31886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	if (err)
31986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  return nerr_pass_ctx(err, "Unable to update ondisk mapping for %s", k);
32086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	break;
32186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      default:
32286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	return nerr_raise (NERR_ASSERT, "Invalid state %d", state);
32386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
32486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
32586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
32686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
32786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
32886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic NEOERR *wdb_save_defn_v1 (WDB *wdb, FILE *fp)
32986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
33086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
33186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *col;
33286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *s = NULL;
33386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *key = NULL;
33486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int r, x, len;
33586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *k = NULL;
33686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *v = NULL;
33786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
33886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* Write version string */
33986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = fprintf (fp, "%s\n", DEFN_VERSION_1);
34086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (!r) goto save_err;
34186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
34286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = wdb_encode_str_alloc (wdb->name, &s);
34386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err) goto save_err;
34486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = fprintf (fp, "name:%s\n", s);
34586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (!r) goto save_err;
34686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (s);
34786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
34886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = wdb_encode_str_alloc (wdb->key, &s);
34986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err != STATUS_OK) goto save_err;
35086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = fprintf (fp, "key:%s\n", s);
35186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (!r) goto save_err;
35286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (s);
35386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  s = NULL;
35486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
35586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = fprintf (fp, "ondisk:%d\n", wdb->last_ondisk);
35686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (!r) goto save_err;
35786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
35886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = fprintf (fp, "attributes\n");
35986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (!r) goto save_err;
36086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  key = NULL;
36186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  s = (char *) dictNext (wdb->attrs, &key, NULL);
36286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  while (s)
36386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
36486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = wdb_encode_str_alloc (key, &k);
36586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err != STATUS_OK) goto save_err;
36686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = wdb_encode_str_alloc (s, &v);
36786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err != STATUS_OK) goto save_err;
36886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    r = fprintf (fp, "%s:%s\n", k, v);
36986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (!r) goto save_err;
37086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (k);
37186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (v);
37286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    k = NULL;
37386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    v = NULL;
37486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    s = (char *) dictNext (wdb->attrs, &key, NULL);
37586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
37686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  s = NULL;
37786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
37886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = fprintf (fp, "columns\n");
37986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (!r) goto save_err;
38086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
38186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  len = uListLength(wdb->cols_l);
38286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
38386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  for (x = 0; x < len; x++)
38486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
38586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = uListGet (wdb->cols_l, x, (void *)&col);
38686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err) goto save_err;
38786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = wdb_encode_str_alloc (col->name, &s);
38886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err != STATUS_OK) goto save_err;
38986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    r = fprintf (fp, "%s:%c:%d\n", s, col->type, col->ondisk_index);
39086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (!r) goto save_err;
39186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free(s);
39286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    s = NULL;
39386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
39486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
39586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
39686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
39786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectsave_err:
39886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (s != NULL) free (s);
39986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (k != NULL) free (k);
40086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (v != NULL) free (v);
40186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err == STATUS_OK) return nerr_pass(err);
40286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return nerr_raise (r, "Unable to save defn");
40386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
40486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
40586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic NEOERR *wdb_load_defn (WDB *wdb, const char *name)
40686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
40786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char path[_POSIX_PATH_MAX];
40886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char line[1024];
40986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  FILE *fp;
41086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
41186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
41286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  snprintf (path, sizeof(path), "%s.wdf", name);
41386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  fp = fopen (path, "r");
41486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (fp == NULL)
41586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
41686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (errno == ENOENT)
41786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_raise (NERR_NOT_FOUND, "Unable to open defn %s", name);
41886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise_errno (NERR_IO, "Unable to open defn %s", name);
41986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
42086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
42186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* Read Version string */
42286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (fgets (line, sizeof(line), fp) == NULL)
42386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
42486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    fclose(fp);
42586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise_errno (NERR_IO, "Unable to read defn %s", name);
42686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
42786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  string_rstrip(line);
42886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
42986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (!strcmp(line, DEFN_VERSION_1))
43086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
43186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = wdb_load_defn_v1(wdb, fp);
43286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    fclose(fp);
43386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err) return nerr_pass(err);
43486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
43586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  else
43686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
43786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    fclose(fp);
43886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_ASSERT, "Unknown defn version %s: %s", line, name);
43986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
44086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
44186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb->table_version = rand();
44286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
44386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
44486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
44586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
44686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic NEOERR *wdb_save_defn (WDB *wdb, const char *name)
44786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
44886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char path[_POSIX_PATH_MAX];
44986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char path2[_POSIX_PATH_MAX];
45086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  FILE *fp;
45186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
45286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int r;
45386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
45486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  snprintf (path, sizeof(path), "%s.wdf.new", name);
45586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  snprintf (path2, sizeof(path2), "%s.wdf", name);
45686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  fp = fopen (path, "w");
45786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (fp == NULL)
45886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise_errno (NERR_IO, "Unable to open defn %s", name);
45986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
46086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = wdb_save_defn_v1 (wdb, fp);
46186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  fclose (fp);
46286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err != STATUS_OK)
46386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
46486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    unlink (path);
46586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass (err);
46686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
46786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
46886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = unlink (path2);
46986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (r == -1 && errno != ENOENT)
47086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise_errno (NERR_IO, "Unable to unlink %s", path2);
47186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = link (path, path2);
47286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (r == -1)
47386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise_errno (NERR_IO, "Unable to link %s to %s", path, path2);
47486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = unlink (path);
47586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
47686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb->defn_dirty = 0;
47786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb->table_version = rand();
47886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
47986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
48086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
48186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
48286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_open (WDB **wdb, const char *name, int flags)
48386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
48486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDB *my_wdb;
48586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char path[_POSIX_PATH_MAX];
48686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
48786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int r;
48886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
48986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *wdb = NULL;
49086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
49186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = wdb_alloc (&my_wdb, flags);
49286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err) return nerr_pass(err);
49386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
49486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_wdb->path = strdup (name);
49586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err)
49686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
49786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb_destroy (&my_wdb);
49886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass(err);
49986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
50086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
50186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = wdb_load_defn (my_wdb, name);
50286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err)
50386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
50486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb_destroy (&my_wdb);
50586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass(err);
50686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
50786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
50886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  snprintf (path, sizeof(path), "%s.wdb", name);
50986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = db_open(path, DB_BTREE, 0, 0, NULL, NULL, &(my_wdb->db));
51086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (r)
51186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
51286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb_destroy (&my_wdb);
51386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_DB, "Unable to open database %s: %d", name, r);
51486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
51586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
51686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *wdb = my_wdb;
51786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
51886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
51986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
52086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
52186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_save (WDB *wdb)
52286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
52386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (wdb->defn_dirty)
52486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
52586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb_save_defn (wdb, wdb->path);
52686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
52786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
52886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
52986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
53086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectvoid wdb_destroy (WDB **wdb)
53186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
53286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDB *my_wdb;
53386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
53486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_wdb = *wdb;
53586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
53686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb == NULL) return;
53786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
53886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb->defn_dirty)
53986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
54086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb_save_defn (my_wdb, my_wdb->path);
54186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
54286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
54386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb->attrs != NULL)
54486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
54586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    dictDestroy (my_wdb->attrs);
54686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
54786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
54886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb->cols != NULL)
54986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
55086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    dictDestroy (my_wdb->cols);
55186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
55286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
55386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb->cols_l != NULL)
55486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
55586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    uListDestroy(&(my_wdb->cols_l), 0);
55686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
55786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
55886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb->ondisk != NULL)
55986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
56086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    skipFreeList(my_wdb->ondisk);
56186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
56286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
56386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb->db != NULL)
56486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
56586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    my_wdb->db->close (my_wdb->db, 0);
56686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    my_wdb->db = NULL;
56786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
56886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
56986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb->path != NULL)
57086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
57186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free(my_wdb->path);
57286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    my_wdb->path = NULL;
57386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
57486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb->name != NULL)
57586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
57686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free(my_wdb->name);
57786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    my_wdb->name = NULL;
57886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
57986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb->key != NULL)
58086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
58186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free(my_wdb->key);
58286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    my_wdb->key = NULL;
58386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
58486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
58586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (my_wdb);
58686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *wdb = NULL;
58786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
58886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return;
58986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
59086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
59186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define PACK_UB4(pdata, plen, pmax, pn) \
59286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{ \
59386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (plen + 4 > pmax) \
59486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  { \
59586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    pmax *= 2; \
59686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    pdata = realloc ((void *)pdata, pmax); \
59786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (pdata == NULL) goto pack_err; \
59886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  } \
59986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pdata[plen++] = (0x0ff & (pn >> 0)); \
60086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pdata[plen++] = (0x0ff & (pn >> 8)); \
60186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pdata[plen++] = (0x0ff & (pn >> 16)); \
60286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pdata[plen++] = (0x0ff & (pn >> 24)); \
60386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
60486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
60586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define UNPACK_UB4(pdata, plen, pn, pd) \
60686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{ \
60786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (pn + 4 > plen) \
60886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    goto pack_err; \
60986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pd = ((0x0ff & pdata[pn+0])<<0) | ((0x0ff & pdata[pn+1])<<8) | \
61086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project       ((0x0ff & pdata[pn+2])<<16) | ((0x0ff & pdata[pn+3])<<24); \
61186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pn+=4; \
61286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
61386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
61486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define PACK_BYTE(pdata, plen, pmax, pn) \
61586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{ \
61686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (plen + 1 > pmax) \
61786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  { \
61886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    pmax *= 2; \
61986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    pdata = realloc ((void *)pdata, pmax); \
62086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (pdata == NULL) goto pack_err; \
62186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  } \
62286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pdata[plen++] = (0x0ff & (pn >> 0)); \
62386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
62486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
62586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define UNPACK_BYTE(pdata, plen, pn, pd) \
62686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{ \
62786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (pn + 1 > plen) \
62886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    goto pack_err; \
62986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pd = pdata[pn++]; \
63086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
63186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
63286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define PACK_STRING(pdata, plen, pmax, dl, ds) \
63386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{ \
63486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (plen + 4 + dl > pmax) \
63586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  { \
63686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    while (plen + 4 + dl > pmax) \
63786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      pmax *= 2; \
63886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    pdata = realloc ((void *)pdata, pmax); \
63986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (pdata == NULL) goto pack_err; \
64086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  } \
64186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pdata[plen++] = (0x0ff & (dl >> 0)); \
64286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pdata[plen++] = (0x0ff & (dl >> 8)); \
64386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pdata[plen++] = (0x0ff & (dl >> 16)); \
64486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pdata[plen++] = (0x0ff & (dl >> 24)); \
64586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memcpy (&pdata[plen], ds, dl); \
64686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  plen+=dl;\
64786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
64886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
64986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#define UNPACK_STRING(pdata, plen, pn, ps) \
65086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{ \
65186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int pl; \
65286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (pn + 4 > plen) \
65386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    goto pack_err; \
65486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pl = ((0x0ff & pdata[pn+0])<<0) | ((0x0ff & pdata[pn+1])<<8) | \
65586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project       ((0x0ff & pdata[pn+2])<<16) | ((0x0ff & pdata[pn+3])<<24); \
65686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  pn+=4; \
65786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (pl) \
65886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  { \
65986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    ps = (char *)malloc(sizeof(char)*(pl+1)); \
66086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (ps == NULL) \
66186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      goto pack_err; \
66286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    memcpy (ps, &pdata[pn], pl); \
66386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    ps[pl] = '\0'; \
66486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    pn += pl; \
66586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  } else { \
66686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    ps = NULL; \
66786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  } \
66886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
66986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
67086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project/* A VERSION_1 Row consists of the following data:
67186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * UB4 VERSION
67286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * UB4 DATA COUNT
67386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * DATA where
67486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *   UB4 ONDISK INDEX
67586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *   UB1 TYPE
67686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *   if INT, then UB4
67786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *   if STR, then UB4 length and length UB1s
67886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project */
67986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
68086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic NEOERR *pack_row (WDB *wdb, WDBRow *row, void **rdata, int *rdlen)
68186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
68286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *data;
68386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int x, len, dlen, dmax;
68486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *s;
68586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int n;
68686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *col;
68786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err;
68886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
68986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *rdata = NULL;
69086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *rdlen = 0;
69186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* allocate */
69286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  data = (char *)malloc(sizeof (char) * 1024);
69386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (data == NULL)
69486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM, "Unable to allocate memory to pack row");
69586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
69686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dmax = 1024;
69786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dlen = 0;
69886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
69986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  PACK_UB4 (data, dlen, dmax, PACK_VERSION_1);
70086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project/*  PACK_UB4 (data, dlen, dmax, time(NULL)); */
70186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
70286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  len = uListLength(wdb->cols_l);
70386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (len > row->data_count)
70486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    len = row->data_count;
70586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  PACK_UB4 (data, dlen, dmax, len);
70686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
70786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  for (x = 0; x < len; x++)
70886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
70986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = uListGet (wdb->cols_l, x, (void *)&col);
71086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err) goto pack_err;
71186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    PACK_UB4 (data, dlen, dmax, col->ondisk_index);
71286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    PACK_BYTE (data, dlen, dmax, col->type);
71386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    switch (col->type)
71486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
71586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      case WDB_TYPE_INT:
71686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	n = (int)(row->data[x]);
71786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	PACK_UB4 (data, dlen, dmax, n);
71886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	break;
71986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      case WDB_TYPE_STR:
72086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	s = (char *)(row->data[x]);
72186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	if (s == NULL)
72286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	{
72386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  s = "";
72486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	}
72586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	n = strlen(s);
72686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	PACK_STRING (data, dlen, dmax, n, s);
72786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	break;
72886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      default:
72986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	free (data);
73086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	return nerr_raise (NERR_ASSERT, "Unknown type %d", col->type);
73186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
73286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
73386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
73486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *rdata = data;
73586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *rdlen = dlen;
73686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
73786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
73886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectpack_err:
73986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (data != NULL)
74086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (data);
74186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err == STATUS_OK)
74286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise(NERR_NOMEM, "Unable to allocate memory for pack_row");
74386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return nerr_pass(err);
74486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
74586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
74686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic NEOERR *unpack_row (WDB *wdb, void *rdata, int dlen, WDBRow *row)
74786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
74886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  unsigned char *data = rdata;
74986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int version, n;
75086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int count, x, ondisk_index, type, d_int, inmem_index;
75186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *s;
75286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
75386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  n = 0;
75486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
75586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  UNPACK_UB4(data, dlen, n, version);
75686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
75786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  switch (version)
75886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
75986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    case PACK_VERSION_1:
76086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      UNPACK_UB4(data, dlen, n, count);
76186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      for (x = 0; x<count; x++)
76286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      {
76386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	UNPACK_UB4 (data, dlen, n, ondisk_index);
76486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	UNPACK_BYTE (data, dlen, n, type);
76586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	inmem_index = (int) skipSearch (wdb->ondisk, ondisk_index, NULL);
76686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
76786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	switch (type)
76886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	{
76986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  case WDB_TYPE_INT:
77086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    UNPACK_UB4 (data, dlen, n, d_int);
77186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    if (inmem_index != 0)
77286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	      row->data[inmem_index-1] = (void *) d_int;
77386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    break;
77486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  case WDB_TYPE_STR:
77586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    UNPACK_STRING (data, dlen, n, s);
77686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    if (inmem_index != 0)
77786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	      row->data[inmem_index-1] = s;
77886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    break;
77986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  default:
78086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	    return nerr_raise (NERR_ASSERT, "Unknown type %d for col %d", type, ondisk_index);
78186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	}
78286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      }
78386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      break;
78486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    default:
78586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_raise (NERR_ASSERT, "Unknown version %d", version);
78686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
78786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
78886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
78986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectpack_err:
79086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return nerr_raise(NERR_PARSE, "Unable to unpack row %s", row->key_value);
79186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
79286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
79386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_column_insert (WDB *wdb, int loc, const char *key, char type)
79486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
79586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err;
79686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *col, *ocol;
79786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int x, len;
79886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
79986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  col = (WDBColumn *) dictSearch (wdb->cols, key, NULL);
80086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
80186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (col != NULL)
80286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_DUPLICATE,
80386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Duplicate key %s:%d", key, col->inmem_index);
80486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
80586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  col = (WDBColumn *) calloc (1, sizeof (WDBColumn));
80686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (col == NULL)
80786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
80886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM,
80986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Unable to allocate memory for creation of col %s:%d", key, loc);
81086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
81186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
81286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  col->name = strdup(key);
81386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (col->name == NULL)
81486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
81586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free(col);
81686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM,
81786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Unable to allocate memory for creation of col %s:%d", key, loc);
81886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
81986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  col->type = type;
82086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  col->ondisk_index = wdb->last_ondisk++;
82186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* -1 == append */
82286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (loc == -1)
82386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
82486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = dictSetValue(wdb->cols, key, col);
82586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err)
82686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
82786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      free (col->name);
82886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      free (col);
82986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_pass_ctx (err,
83086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  "Unable to insert for creation of col %s:%d", key, loc);
83186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
83286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = uListAppend (wdb->cols_l, (void *)col);
83386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err) return nerr_pass(err);
83486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    x = uListLength (wdb->cols_l);
83586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    col->inmem_index = x;
83686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = skipInsert (wdb->ondisk, col->ondisk_index,
83786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	            (void *)(col->inmem_index), 0);
83886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err)
83986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_pass_ctx (err, "Unable to update ondisk mapping for %s", key);
84086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
84186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  else
84286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
84386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    /* We are inserting this in middle, so the skipList ondisk is now
84486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project     * invalid, as is the inmem_index for all cols */
84586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = dictSetValue(wdb->cols, key, col);
84686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err)
84786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
84886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      free (col->name);
84986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      free (col);
85086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_pass_ctx (err,
85186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  "Unable to insert for creation of col %s:%d", key, loc);
85286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
85386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = uListInsert (wdb->cols_l, loc, (void *)col);
85486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err) return nerr_pass(err);
85586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    len = uListLength (wdb->cols_l);
85686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    /* Fix up inmem_index and ondisk skipList */
85786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    for (x = 0; x < len; x++)
85886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
85986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      err = uListGet (wdb->cols_l, x, (void *)&ocol);
86086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      if (err) return nerr_pass(err);
86186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      ocol->inmem_index = x + 1;
86286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      err = skipInsert (wdb->ondisk, ocol->ondisk_index,
86386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	              (void *)(ocol->inmem_index), TRUE);
86486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      if (err)
86586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	return nerr_pass_ctx (err, "Unable to update ondisk mapping for %s", key);
86686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
86786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
86886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
86986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb->defn_dirty = 1;
87086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb->table_version = rand();
87186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
87286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
87386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
87486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
87586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_column_update (WDB *wdb, const char *oldkey, const char *newkey)
87686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
87786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *ocol, *col;
87886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *vcol;
87986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
88086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int x, len, r;
88186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
88286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  ocol = (WDBColumn *) dictSearch (wdb->cols, oldkey, NULL);
88386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
88486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (ocol == NULL)
88586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOT_FOUND,
88686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Unable to find column for key %s", oldkey);
88786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
88886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  col = (WDBColumn *) calloc (1, sizeof (WDBColumn));
88986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (col == NULL)
89086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
89186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM,
89286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Unable to allocate memory for column update %s", newkey);
89386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
89486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
89586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *col = *ocol;
89686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  col->name = strdup(newkey);
89786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (col->name == NULL)
89886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
89986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free(col);
90086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM,
90186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Unable to allocate memory for column update %s", oldkey);
90286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
90386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  len = uListLength(wdb->cols_l);
90486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  for (x = 0; x < len; x++)
90586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
90686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = uListGet (wdb->cols_l, x, (void *)&vcol);
90786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err) return nerr_pass(err);
90886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (!strcmp(vcol->name, oldkey))
90986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
91086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      err = uListSet (wdb->cols_l, x, (void *)col);
91186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      if (err) return nerr_pass(err);
91286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      break;
91386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
91486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
91586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (x>len)
91686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
91786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_ASSERT, "Unable to find cols_l for key %s", oldkey);
91886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
91986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
92086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = dictRemove (wdb->cols, oldkey); /* Only failure is key not found */
92186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = dictSetValue(wdb->cols, newkey, col);
92286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err)
92386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
92486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (col->name);
92586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (col);
92686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass_ctx (err,
92786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Unable to insert for update of col %s->%s", oldkey, newkey);
92886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
92986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
93086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb->defn_dirty = 1;
93186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb->table_version = rand();
93286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
93386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
93486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
93586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
93686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_column_delete (WDB *wdb, const char *name)
93786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
93886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *col;
93986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
94086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int len, x, r;
94186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
94286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  len = uListLength(wdb->cols_l);
94386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  for (x = 0; x < len; x++)
94486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
94586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = uListGet (wdb->cols_l, x, (void *)&col);
94686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err) return nerr_pass(err);
94786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (!strcmp(col->name, name))
94886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
94986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      err = uListDelete (wdb->cols_l, x, NULL);
95086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      if (err) return nerr_pass(err);
95186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      break;
95286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
95386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
95486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
95586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = dictRemove (wdb->cols, name); /* Only failure is key not found */
95686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (!r)
95786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
95886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOT_FOUND,
95986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Unable to find column for key %s", name);
96086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
96186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb->defn_dirty = 1;
96286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb->table_version = rand();
96386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
96486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
96586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
96686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
96786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_column_exchange (WDB *wdb, const char *key1, const char *key2)
96886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
96986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return nerr_raise (NERR_ASSERT,
97086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      "wdb_column_exchange: Not Implemented");
97186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
97286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
97386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project/* Not that there's that much point in changing the key name ... */
97486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_update (WDB *wdb, const char *name, const char *key)
97586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
97686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (name != NULL && strcmp(wdb->name, name))
97786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
97886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (wdb->name != NULL)
97986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      free(wdb->name);
98086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb->name = strdup(name);
98186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (wdb->name == NULL)
98286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_raise (NERR_NOMEM,
98386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  "Unable to allocate memory to update name to %s", name);
98486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb->defn_dirty = 1;
98586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb->table_version = rand();
98686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
98786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (key != NULL && strcmp(wdb->key, key))
98886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
98986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (wdb->key != NULL)
99086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      free(wdb->key);
99186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb->key = strdup(key);
99286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (wdb->key == NULL)
99386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
99486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      wdb->defn_dirty = 0;
99586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_raise (NERR_NOMEM,
99686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  "Unable to allocate memory to update key to %s", key);
99786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
99886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb->defn_dirty = 1;
99986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb->table_version = rand();
100086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
100186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
100286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
100386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
100486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_create (WDB **wdb, const char *path, const char *name,
100586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project                    const char *key, ULIST *col_def, int flags)
100686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
100786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDB *my_wdb;
100886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char d_path[_POSIX_PATH_MAX];
100986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
101086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int x, len, r;
101186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *s;
101286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
101386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *wdb = NULL;
101486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
101586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = wdb_alloc (&my_wdb, flags);
101686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err) return nerr_pass(err);
101786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
101886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_wdb->name = strdup (name);
101986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_wdb->key = strdup (key);
102086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_wdb->path = strdup(path);
102186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_wdb->name == NULL || my_wdb->key == NULL || my_wdb->path == NULL)
102286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
102386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb_destroy (&my_wdb);
102486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM,
102586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	"Unable to allocate memory for creation of %s", name);
102686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
102786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
102886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* ondisk must start at one because of skipList */
102986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_wdb->last_ondisk = 1;
103086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  len = uListLength(col_def);
103186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  for (x = 0; x < len; x++)
103286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
103386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = uListGet (col_def, x, (void *)&s);
103486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err)
103586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
103686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      wdb_destroy (&my_wdb);
103786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_pass(err);
103886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
103986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = wdb_column_insert (my_wdb, -1, s, WDB_TYPE_STR);
104086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    my_wdb->defn_dirty = 0; /* So we don't save on error destroy */
104186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err)
104286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
104386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      wdb_destroy (&my_wdb);
104486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_pass(err);
104586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
104686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
104786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
104886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = wdb_save_defn (my_wdb, path);
104986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err)
105086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
105186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb_destroy (&my_wdb);
105286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass(err);
105386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
105486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
105586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  snprintf (d_path, sizeof(d_path), "%s.wdb", path);
105686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = db_open(d_path, DB_BTREE, DB_CREATE | DB_TRUNCATE, 0, NULL, NULL, &(my_wdb->db));
105786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (r)
105886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
105986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdb_destroy (&my_wdb);
106086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_DB, "Unable to create db file %s: %d", d_path, r);
106186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
106286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
106386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *wdb = my_wdb;
106486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
106586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
106686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
106786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
106886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_attr_next (WDB *wdb, char **key, char **value)
106986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
107086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *value = (char *) dictNext (wdb->attrs, key, NULL);
107186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
107286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
107386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
107486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
107586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_attr_get (WDB *wdb, const char *key, char **value)
107686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
107786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  void *v;
107886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
107986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  v = dictSearch (wdb->attrs, key, NULL);
108086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
108186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (v == NULL)
108286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOT_FOUND, "Unable to find attr %s", key);
108386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
108486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *value = (char *)v;
108586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
108686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
108786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
108886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
108986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_attr_set (WDB *wdb, const char *key, const char *value)
109086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
109186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
109286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *v;
109386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
109486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  v = strdup(value);
109586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (v == NULL)
109686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM, "No memory for new attr");
109786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
109886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = dictSetValue(wdb->attrs, key, v);
109986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err)
110086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass_ctx (err, "Unable to set attr %s", key);
110186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
110286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  wdb->defn_dirty = 1;
110386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
110486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
110586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
110686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
110786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbr_get (WDB *wdb, WDBRow *row, const char *key, void **value)
110886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
110986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *col;
111086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  void *v;
111186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
111286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  col = (WDBColumn *) dictSearch (wdb->cols, key, NULL);
111386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
111486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (col == NULL)
111586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOT_FOUND, "Unable to find key %s", key);
111686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
111786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (col->inmem_index-1 > row->data_count)
111886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_ASSERT, "Index for key %s is greater than row data, was table altered?", key);
111986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
112086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  v = row->data[col->inmem_index-1];
112186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
112286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *value = v;
112386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
112486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
112586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
112686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
112786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbr_set (WDB *wdb, WDBRow *row, const char *key, void *value)
112886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
112986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *col;
113086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
113186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  col = (WDBColumn *) dictSearch (wdb->cols, key, NULL);
113286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
113386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (col == NULL)
113486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOT_FOUND, "Unable to find key %s", key);
113586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
113686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (col->inmem_index-1 > row->data_count)
113786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_ASSERT, "Index for key %s is greater than row data, was table altered?", key);
113886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
113986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (col->type == WDB_TYPE_STR && row->data[col->inmem_index-1] != NULL)
114086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
114186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (row->data[col->inmem_index-1]);
114286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
114386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  row->data[col->inmem_index-1] = value;
114486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
114586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
114686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
114786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
114886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectstatic NEOERR *alloc_row (WDB *wdb, WDBRow **row)
114986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
115086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBRow *my_row;
115186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int len;
115286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
115386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = NULL;
115486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
115586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  len = uListLength (wdb->cols_l);
115686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
115786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_row = (WDBRow *) calloc (1, sizeof (WDBRow) + len * (sizeof (void *)));
115886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_row == NULL)
115986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM, "No memory for new row");
116086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
116186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_row->data_count = len;
116286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_row->table_version = wdb->table_version;
116386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
116486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = my_row;
116586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
116686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
116786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
116886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
116986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbr_destroy (WDB *wdb, WDBRow **row)
117086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
117186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *col;
117286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBRow *my_row;
117386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int len, x;
117486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err;
117586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
117686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = STATUS_OK;
117786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (*row == NULL)
117886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return err;
117986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
118086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_row = *row;
118186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
118286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* Verify this row maps to this table, or else we could do something
118386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project   * bad */
118486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
118586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (wdb->table_version != my_row->table_version)
118686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_ASSERT, "Row %s doesn't match current table", my_row->key_value);
118786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
118886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_row->key_value != NULL)
118986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (my_row->key_value);
119086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
119186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  len = uListLength(wdb->cols_l);
119286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
119386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  for (x = 0; x < len; x++)
119486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
119586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (my_row->data[x] != NULL)
119686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
119786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      err = uListGet (wdb->cols_l, x, (void *)&col);
119886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      if (err) break;
119986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      switch (col->type)
120086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      {
120186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	case WDB_TYPE_INT:
120286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  break;
120386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	case WDB_TYPE_STR:
120486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  free (my_row->data[x]);
120586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  break;
120686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	default:
120786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  return nerr_raise (NERR_ASSERT, "Unknown type %d", col->type);
120886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      }
120986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
121086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
121186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
121286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (my_row);
121386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = NULL;
121486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
121586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return nerr_pass(err);
121686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
121786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
121886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbr_lookup (WDB *wdb, const char *key, WDBRow **row)
121986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
122086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  DBT dkey, data;
122186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
122286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBRow *my_row;
122386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int r;
122486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
122586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = NULL;
122686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
122786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memset(&dkey, 0, sizeof(dkey));
122886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memset(&data, 0, sizeof(data));
122986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
123086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.flags = DB_DBT_USERMEM;
123186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  data.flags = DB_DBT_MALLOC;
123286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
123386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.data = (void *)key;
123486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.size = strlen(key);
123586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
123686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = wdb->db->get (wdb->db, NULL, &dkey, &data, 0);
123786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (r == DB_NOTFOUND)
123886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOT_FOUND, "Unable to find key %s", key);
123986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  else if (r)
124086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_DB, "Error retrieving key %s: %d", key, r);
124186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
124286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* allocate row */
124386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = alloc_row (wdb, &my_row);
124486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err != STATUS_OK)
124586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
124686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (data.data);
124786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass(err);
124886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
124986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
125086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_row->key_value = strdup(key);
125186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_row->key_value == NULL)
125286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
125386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (data.data);
125486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (my_row);
125586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM, "No memory for new row");
125686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
125786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
125886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* unpack row */
125986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = unpack_row (wdb, data.data, data.size, my_row);
126086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (data.data);
126186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err)
126286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
126386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (my_row);
126486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass(err);
126586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
126686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
126786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = my_row;
126886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
126986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
127086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
127186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
127286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbr_create (WDB *wdb, const char *key, WDBRow **row)
127386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
127486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBRow *my_row;
127586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
127686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
127786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = NULL;
127886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
127986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* allocate row */
128086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = alloc_row (wdb, &my_row);
128186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err) return nerr_pass(err);
128286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
128386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_row->key_value = strdup(key);
128486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_row->key_value == NULL)
128586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
128686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    wdbr_destroy (wdb, &my_row);
128786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM, "No memory for new row");
128886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
128986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
129086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = my_row;
129186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
129286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
129386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
129486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
129586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbr_save (WDB *wdb, WDBRow *row, int flags)
129686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
129786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  DBT dkey, data;
129886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int dflags = 0;
129986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
130086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int r;
130186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
130286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memset(&dkey, 0, sizeof(dkey));
130386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memset(&data, 0, sizeof(data));
130486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
130586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.data = row->key_value;
130686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.size = strlen(row->key_value);
130786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
130886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = pack_row (wdb, row, &(data.data), &data.size);
130986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err != STATUS_OK) return nerr_pass(err);
131086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
131186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (flags & WDBR_INSERT)
131286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
131386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    dflags = DB_NOOVERWRITE;
131486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
131586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
131686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = wdb->db->put (wdb->db, NULL, &dkey, &data, dflags);
131786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (data.data);
131886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (r == DB_KEYEXIST)
131986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_DUPLICATE, "Key %s already exists", row->key_value);
132086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (r)
132186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_DB, "Error saving key %s: %d",
132286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	row->key_value, r);
132386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
132486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
132586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
132686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
132786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbr_delete (WDB *wdb, const char *key)
132886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
132986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  DBT dkey;
133086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int r;
133186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
133286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memset(&dkey, 0, sizeof(dkey));
133386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
133486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.flags = DB_DBT_USERMEM;
133586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
133686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.data = (void *)key;
133786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.size = strlen(key);
133886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
133986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = wdb->db->del (wdb->db, NULL, &dkey, 0);
134086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (r == DB_NOTFOUND)
134186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOT_FOUND, "Key %s not found", key);
134286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  else if (r)
134386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_DB, "Error deleting key %s: %d", key, r);
134486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
134586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
134686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
134786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
134886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
134986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbr_dump (WDB *wdb, WDBRow *row)
135086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
135186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int x;
135286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
135386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  ne_warn ("version: %d", row->table_version);
135486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  ne_warn ("key: %s", row->key_value);
135586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  ne_warn ("count: %d", row->data_count);
135686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  for (x=0; x < row->data_count; x++)
135786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    ne_warn ("data[%d]: %s", x, row->data[x]);
135886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
135986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
136086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
136186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
136286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbc_create (WDB *wdb, WDBCursor **cursor)
136386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
136486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  DBC *db_cursor;
136586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBCursor *new_cursor;
136686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int r;
136786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
136886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *cursor = NULL;
136986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
137086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#if (DB_VERSION_MINOR==4)
137186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = (wdb->db)->cursor (wdb->db, NULL, &db_cursor);
137286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#else
137386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = (wdb->db)->cursor (wdb->db, NULL, &db_cursor, 0);
137486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project#endif
137586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (r)
137686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_DB, "Unable to create cursor: %d", r);
137786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
137886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  new_cursor = (WDBCursor *) calloc (1, sizeof (WDBCursor));
137986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (new_cursor == NULL)
138086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
138186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    db_cursor->c_close (db_cursor);
138286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM, "Unable to create cursor");
138386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
138486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
138586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  new_cursor->table_version = wdb->table_version;
138686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  new_cursor->db_cursor = db_cursor;
138786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
138886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *cursor = new_cursor;
138986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
139086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
139186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
139286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
139386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbc_destroy (WDB *wdb, WDBCursor **cursor)
139486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
139586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (*cursor != NULL)
139686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
139786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    (*cursor)->db_cursor->c_close ((*cursor)->db_cursor);
139886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (*cursor);
139986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    *cursor = NULL;
140086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
140186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
140286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
140386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
140486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbr_next (WDB *wdb, WDBCursor *cursor, WDBRow **row, int flags)
140586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
140686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  DBT dkey, data;
140786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBRow *my_row;
140886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
140986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int r;
141086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
141186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = NULL;
141286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
141386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (wdb->table_version != cursor->table_version)
141486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
141586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_ASSERT, "Cursor doesn't match database");
141686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
141786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
141886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memset(&dkey, 0, sizeof(dkey));
141986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memset(&data, 0, sizeof(data));
142086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.flags = DB_DBT_MALLOC;
142186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  data.flags = DB_DBT_MALLOC;
142286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
142386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* First call */
142486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (flags & WDBC_FIRST)
142586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
142686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    r = cursor->db_cursor->c_get (cursor->db_cursor, &dkey, &data, DB_FIRST);
142786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (r == DB_NOTFOUND)
142886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_raise (NERR_NOT_FOUND, "Cursor empty");
142986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    else if (r)
143086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_raise (NERR_DB, "Unable to get first item from cursor: %d",
143186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project	  r);
143286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
143386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  else
143486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
143586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    r = cursor->db_cursor->c_get (cursor->db_cursor, &dkey, &data, DB_NEXT);
143686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (r == DB_NOTFOUND)
143786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return STATUS_OK;
143886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    else if (r)
143986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      return nerr_raise (NERR_DB, "Unable to get next item from cursor: %d", r);
144086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
144186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
144286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* allocate row */
144386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = alloc_row (wdb, &my_row);
144486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err)
144586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
144686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (data.data);
144786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass(err);
144886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
144986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
145086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_row->key_value = (char *) malloc (dkey.size + 1);
145186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_row->key_value == NULL)
145286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
145386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (data.data);
145486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (my_row);
145586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM, "No memory for new row");
145686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
145786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
145886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memcpy (my_row->key_value, dkey.data, dkey.size);
145986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_row->key_value[dkey.size] = '\0';
146086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
146186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* unpack row */
146286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = unpack_row (wdb, data.data, data.size, my_row);
146386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (data.data);
146486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (dkey.data);
146586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err)
146686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
146786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (my_row);
146886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass(err);
146986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
147086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
147186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = my_row;
147286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
147386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
147486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
147586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
147686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdbr_find (WDB *wdb, WDBCursor *cursor, const char *key, WDBRow **row)
147786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
147886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  DBT dkey, data;
147986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBRow *my_row;
148086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err = STATUS_OK;
148186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int r;
148286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
148386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = NULL;
148486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
148586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (wdb->table_version != cursor->table_version)
148686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
148786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_ASSERT, "Cursor doesn't match database");
148886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
148986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
149086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memset(&dkey, 0, sizeof(dkey));
149186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memset(&data, 0, sizeof(data));
149286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.flags = DB_DBT_USERMEM;
149386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  data.flags = DB_DBT_MALLOC;
149486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
149586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.data = (void *)key;
149686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  dkey.size = strlen(key);
149786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
149886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  r = cursor->db_cursor->c_get (cursor->db_cursor, &dkey, &data, DB_SET_RANGE);
149986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (r == DB_NOTFOUND)
150086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return STATUS_OK;
150186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  else if (r)
150286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (r, "Unable to get find item for key %s", key);
150386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
150486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* allocate row */
150586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = alloc_row (wdb, &my_row);
150686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err)
150786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
150886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (data.data);
150986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass(err);
151086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
151186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
151286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_row->key_value = (char *) malloc (dkey.size + 1);
151386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_row->key_value == NULL)
151486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
151586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (data.data);
151686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (my_row);
151786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM, "No memory for new row");
151886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
151986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
152086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  memcpy (my_row->key_value, dkey.data, dkey.size);
152186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_row->key_value[dkey.size] = '\0';
152286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
152386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  /* unpack row */
152486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = unpack_row (wdb, data.data, data.size, my_row);
152586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  free (data.data);
152686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err)
152786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
152886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free (my_row);
152986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass(err);
153086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
153186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
153286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *row = my_row;
153386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
153486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
153586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
153686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
153786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source ProjectNEOERR *wdb_keys (WDB *wdb, char **primary_key, ULIST **data)
153886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project{
153986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  NEOERR *err;
154086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  int x, len;
154186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  WDBColumn *col;
154286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  ULIST *my_data;
154386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *my_key = NULL;
154486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  char *my_col = NULL;
154586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
154686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *data = NULL;
154786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *primary_key = NULL;
154886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  my_key = strdup(wdb->key);
154986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_key == NULL)
155086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_raise (NERR_NOMEM, "Unable to allocate memory for keys");
155186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
155286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  len = uListLength(wdb->cols_l);
155386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  err = uListInit (&my_data, len, 0);
155486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (err != STATUS_OK)
155586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
155686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    free(my_key);
155786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    return nerr_pass(err);
155886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
155986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
156086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  for (x = 0; x < len; x++)
156186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  {
156286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = uListGet (wdb->cols_l, x, (void *)&col);
156386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err) goto key_err;
156486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    my_col = strdup(col->name);
156586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (my_col == NULL)
156686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    {
156786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      err = nerr_raise (NERR_NOMEM, "Unable to allocate memory for keys");
156886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project      goto key_err;
156986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    }
157086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    err = uListAppend (my_data, my_col);
157186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    my_col = NULL;
157286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project    if (err) goto key_err;
157386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  }
157486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
157586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *data = my_data;
157686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *primary_key = my_key;
157786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return STATUS_OK;
157886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
157986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Projectkey_err:
158086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_key != NULL) free (my_key);
158186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  if (my_col != NULL) free (my_col);
158286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  *primary_key = NULL;
158386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  uListDestroy (&my_data, 0);
158486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project  return nerr_pass(err);
158586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project}
158686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project
158786abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project/*
158886abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * Known Issues:
158986abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *  - Probably need to store the actual key value in the packed row..
159086abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *    Maybe not, because any cursor you use on a sleepycat db will
159186abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *    return the key...
159286abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * - um, memory.  Especially when dealing with rows, need to keep track
159386abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *   of when we allocate, when we dealloc, and who owns that memory to
159486abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project *   free it
159586abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project * - function to delete entry from wdb
159686abe4b9898668901b812fa6c1eaa38cb34989e2The Android Open Source Project */
1597