Cassandra / C# - 在地图上插入空值<frozen <whatever>&gt;

时间:2016-03-14 19:02:48

标签: c# cassandra datastax

当我尝试使用空的IEnumerable插入/更新POCO时,我在使用带有Mapper扩展名的DataStax c#驱动程序时遇到了一些麻烦(这是一个Map或一个冻结列表)。

驱动程序不应该自动生成逻辑删除吗? (我在Insert上添加了insertNulls:true)选项,但我仍然有例外:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>


// Function prototypes. Don't change these.
unsigned char * read_card(char fname[], int *size);
void save_jpeg(unsigned char data[], int starting_byte, int size, char fname[]);
void recover(unsigned char data[], int size);

int main()
{
    // Read the card.raw file into an array of bytes (unsigned char)
    int card_length;
    unsigned char *card = read_card("card.raw", &card_length);

    // Recover the images
    recover(card, card_length);
}
//read the card.raw file, returns array of unsigned char(bytes)
unsigned char * read_card(char fname[], int *size)
{

    struct stat st;
    if (stat(fname, &st) == -1)
    {
        fprintf(stderr, "Can't get info about %s\n", fname);
        exit(1);
    }
    int len = st.st_size;
    unsigned char *raw = (unsigned char *)malloc(len * sizeof(unsigned char));

    FILE *fp = fopen(fname, "rb");
    if (!fp)
    {
        fprintf(stderr, "Can't open %s for reading\n", fname);
        exit(1);
    }

    char buf[512];
    int r = 0;
    int i = 0;
    while (fread(buf, 1, 512, fp))
    {
        for (i = 0; i < 512; i++)
        {
            raw[r] = buf[i];
            r++;
        }
    }
    fclose(fp);

    *size = len;
    return raw;
}
//parameters: array of unsigned char(bytes),has data for a single pic
//length of the data and name of the file to save to
void save_jpeg(unsigned char data[], int starting_byte, int size, char fname[])
{
    unsigned char *contents = (unsigned char *)malloc((size + 1) * sizeof(unsigned char));

    strncpy(contents, &data[starting_byte], size);
    contents[size + 1] = '\0';

    FILE *fp = fopen(fname, "wb");
    if (!fp)
    {
        fprintf(stderr, "Can't write to %s\n", fname);
        exit(1);
    }

    fwrite(contents, 1, size, fp);
    fclose(fp);
    free(contents);
}

void recover(unsigned char data[], int size)
{
  int count = 0;
  int block = 512;
  int byte_offset = 0;
  int starting_byte = 0;
  bool image_wraps = false;

  for (int leading_byte = 0; leading_byte < size; leading_byte+=block)
  {
    if (image_wraps == false) {
      //check for beginning signatures
      if (data[leading_byte] == 0xff && data[leading_byte+1] == 0xd8 && data[leading_byte+2] == 0xff &&
        (data[leading_byte+3] == 0xe0 || data[leading_byte+3] == 0xe1)) 
      {
        //store start
        starting_byte = leading_byte;
        for (int current_byte = leading_byte + 4; current_byte < leading_byte + block - 1; ++current_byte)
        {
            if (data[current_byte] == 0xff && data[current_byte+1] == 0xd9)
            {
              char filename[30];
              snprintf(filename, sizeof(filename), "%03d.jpg", ++count);
              save_jpeg(data, starting_byte, current_byte - leading_byte, filename);
            }
        }
        image_wraps = true;
        byte_offset = block;
      }
    }
    // image wraps to multiple blocks
    else {
      for (int current_byte = leading_byte; current_byte < leading_byte + block - 1; ++current_byte)
      {
        if (data[current_byte] == 0xff && data[current_byte+1] == 0xd9)
        {
          char filename[30];
          snprintf(filename, sizeof(filename), "%03d.jpg", ++count);
          printf("leading %i, current %i, c-l+o %i\n", leading_byte, current_byte, byte_offset);
          save_jpeg(data, starting_byte, current_byte - leading_byte + byte_offset, filename);
          image_wraps = false;
          starting_byte = 0;
          byte_offset = 0;
        }
      }
      if (byte_offset > 0) {
          byte_offset += block;
      }
    }
  }

  printf("How many images?: %d\n", count);
}

这是代码的一部分(我已经恢复了实体属性,以便更容易理解)。一切都被映射(表和udt):

Cassandra Schema:

Exception caught: 'System.ArgumentNullException' in Cassandra.dll ("Null values are not supported inside collections")  136.11s     [1732]  

C#代码:

CREATE TYPE IF NOT EXISTS maintenancetime (
    id uuid,
    beg int,
    end int
);

CREATE TABLE IF NOT EXISTS bank (
    id uuid PRIMARY KEY,
    name text,
    maintenancetime set<frozen<maintenancetime>>
);

2 个答案:

答案 0 :(得分:0)

在Cassandra中,您可以插入地图列并将其设置为null(生成逻辑删除),但不支持将单元格值设置为包含密钥null值的地图。

例如,在以下查询中,不允许使用包含null值的地图:

INSERT INTO tbl (id, map_col) VALUES (?, ?)
UPDATE tbl SET map_col = ? WHERE id = ?

这就是司机阻止它的原因。

当列未冻结时,您可以使用以下查询(由@doanduyhai指出)

为给定键将特定地图值设置为null
UPDATE tbl SET map_col[?] = null WHERE id = ?

http://cassandra.apache.org/doc/cql3/CQL.html#collections

答案 1 :(得分:0)

  

不支持将特定地图值设置为null。

使用UPDATE

支持
cqlsh:music> create table mm(id bigint PRIMARY KEY, m map<int, text>);
cqlsh:music> INSERT INTO mm(id,m) VALUES(1, {1: 'one', 2: 'two'});
cqlsh:music> UPDATE mm SET m[1]=null WHERE id=1;
cqlsh:music> SELECT * FROM mm;

 id | m
----+------------
  1 | {2: 'two'}

我正在使用Cassandra 3.4