Пример #1
0
void rmsgpack_dom_value_print(struct rmsgpack_dom_value *obj)
{
   unsigned i;

   switch (obj->type)
   {
      case RDT_NULL:
         printf("nil");
         break;
      case RDT_BOOL:
         if (obj->val.bool_)
            printf("true");
         else
            printf("false");
         break;
      case RDT_INT:
         puts_i64(obj->val.int_);
         break;
      case RDT_UINT:
         puts_u64(obj->val.uint_);
         break;
      case RDT_STRING:
         printf("\"%s\"", obj->val.string.buff);
         break;
      case RDT_BINARY:
         printf("\"");
         for (i = 0; i < obj->val.binary.len; i++)
            printf("%02X", (unsigned char) obj->val.binary.buff[i]);
         printf("\"");
         break;
      case RDT_MAP:
         printf("{");
         for (i = 0; i < obj->val.map.len; i++)
         {
            rmsgpack_dom_value_print(&obj->val.map.items[i].key);
            printf(": ");
            rmsgpack_dom_value_print(&obj->val.map.items[i].value);
            if (i < (obj->val.map.len - 1))
               printf(", ");
         }
         printf("}");
         break;
      case RDT_ARRAY:
         printf("[");
         for (i = 0; i < obj->val.array.len; i++)
         {
            rmsgpack_dom_value_print(&obj->val.array.items[i]);
            if (i < (obj->val.array.len - 1))
               printf(", ");
         }
         printf("]");
   }
}
Пример #2
0
int main(int argc, char ** argv)
{
   int rv;
   libretrodb_t db;
   libretrodb_cursor_t cur;
   libretrodb_query_t *q;
   struct rmsgpack_dom_value item;
   const char *command, *path, *query_exp, *error;

   if (argc < 3)
   {
      printf("Usage: %s <db file> <command> [extra args...]\n", argv[0]);
      printf("Available Commands:\n");
      printf("\tlist\n");
      printf("\tcreate-index <index name> <field name>\n");
      printf("\tfind <query expression>\n");
      return 1;
   }

   command = argv[2];
   path    = argv[1];

   if ((rv = libretrodb_open(path, &db)) != 0)
   {
      printf("Could not open db file '%s': %s\n", path, strerror(-rv));
      return 1;
   }
   else if (strcmp(command, "list") == 0)
   {
      if ((rv = libretrodb_cursor_open(&db, &cur, NULL)) != 0)
      {
         printf("Could not open cursor: %s\n", strerror(-rv));
         return 1;
      }

      if (argc != 3)
      {
         printf("Usage: %s <db file> list\n", argv[0]);
         return 1;
      }

      while (libretrodb_cursor_read_item(&cur, &item) == 0)
      {
         rmsgpack_dom_value_print(&item);
         printf("\n");
         rmsgpack_dom_value_free(&item);
      }
   }
   else if (strcmp(command, "find") == 0)
   {
      if (argc != 4)
      {
         printf("Usage: %s <db file> find <query expression>\n", argv[0]);
         return 1;
      }

      query_exp = argv[3];
      error = NULL;
      q = libretrodb_query_compile(&db, query_exp, strlen(query_exp), &error);

      if (error)
      {
         printf("%s\n", error);
         return 1;
      }

      if ((rv = libretrodb_cursor_open(&db, &cur, q)) != 0)
      {
         printf("Could not open cursor: %s\n", strerror(-rv));
         return 1;
      }

      while (libretrodb_cursor_read_item(&cur, &item) == 0)
      {
         rmsgpack_dom_value_print(&item);
         printf("\n");
         rmsgpack_dom_value_free(&item);
      }
   }
   else if (strcmp(command, "create-index") == 0)
   {
      const char * index_name, * field_name;

      if (argc != 5)
      {
         printf("Usage: %s <db file> create-index <index name> <field name>\n", argv[0]);
         return 1;
      }

      index_name = argv[3];
      field_name = argv[4];

      libretrodb_create_index(&db, index_name, field_name);
   }
   else
   {
      printf("Unknown command %s\n", argv[2]);
      return 1;
   }

   libretrodb_close(&db);
   return 1;
}
Пример #3
0
int libretrodb_create_index(libretrodb_t *db,
      const char *name, const char *field_name)
{
	int rv;
	struct node_iter_ctx nictx;
	struct rmsgpack_dom_value key;
	libretrodb_index_t idx;
	struct rmsgpack_dom_value item;
	struct rmsgpack_dom_value * field;
	struct bintree tree;
	libretrodb_cursor_t cur;
	uint64_t idx_header_offset;
	void * buff = NULL;
	uint64_t * buff_u64 = NULL;
	uint8_t field_size = 0;
	uint64_t item_loc = libretrodb_tell(db);

	bintree_new(&tree, node_compare, &field_size);

	if (libretrodb_cursor_open(db, &cur, NULL) != 0)
   {
		rv = -1;
		goto clean;
	}

	key.type = RDT_STRING;
	key.string.len = strlen(field_name);

	/* We know we aren't going to change it */
	key.string.buff = (char *) field_name;

	while (libretrodb_cursor_read_item(&cur, &item) == 0)
   {
		if (item.type != RDT_MAP)
      {
			rv = -EINVAL;
			printf("Only map keys are supported\n");
			goto clean;
		}

		field = rmsgpack_dom_value_map_value(&item, &key);

		if (!field)
      {
			rv = -EINVAL;
			printf("field not found in item\n");
			goto clean;
		}

		if (field->type != RDT_BINARY)
      {
			rv = -EINVAL;
			printf("field is not binary\n");
			goto clean;
		}

		if (field->binary.len == 0)
      {
			rv = -EINVAL;
			printf("field is empty\n");
			goto clean;
		}

		if (field_size == 0)
			field_size = field->binary.len;
		else if (field->binary.len != field_size)
      {
			rv = -EINVAL;
			printf("field is not of correct size\n");
			goto clean;
		}

		buff = malloc(field_size + sizeof(uint64_t));
		if (!buff)
      {
			rv = -ENOMEM;
			goto clean;
		}

		memcpy(buff, field->binary.buff, field_size);

		buff_u64 = (uint64_t *)buff + field_size;

		memcpy(buff_u64, &item_loc, sizeof(uint64_t));

		if (bintree_insert(&tree, buff) != 0)
      {
			printf("Value is not unique: ");
			rmsgpack_dom_value_print(field);
			printf("\n");
			rv = -EINVAL;
			goto clean;
		}
		buff = NULL;
		rmsgpack_dom_value_free(&item);
		item_loc = libretrodb_tell(db);
	}

	(void)rv;
	(void)idx_header_offset;

	idx_header_offset = lseek(db->fd, 0, SEEK_END);
	strncpy(idx.name, name, 50);

	idx.name[49] = '\0';
	idx.key_size = field_size;
	idx.next = db->count * (field_size + sizeof(uint64_t));
	libretrodb_write_index_header(db->fd, &idx);

	nictx.db = db;
	nictx.idx = &idx;
	bintree_iterate(&tree, node_iter, &nictx);
	bintree_free(&tree);
clean:
	rmsgpack_dom_value_free(&item);
	if (buff)
		free(buff);
	if (cur.is_valid)
		libretrodb_cursor_close(&cur);
	return 0;
}