2013-10-15 4 views
0

Я создал некоторые данные с помощью Кассандры DB 2.0.1 (CQL 3) штрафРаспаковка Cassandra Map Тип

CREATE TABLE fans (id text PRIMARY KEY, fans map<text, text>); 
INSERT INTO fans (id, fans) VALUES ('John', {'fruit' : 'apple', 'band' : 'Beatles'}); 
UPDATE fans SET fans = fans + {'movie' : 'Cassablanca'} WHERE id = 'John'; 

это работает в.

cqlsh:testdb> SELECT * FROM fans; 

id | fans 
------+--------------------------------------------------------------- 
John | {'band': 'Beatles', 'fruit': 'apple', 'movie': 'Cassablanca'} 

(1 rows) 

Теперь я пытаюсь получить данные с PHP (thobbs/phpcassa v1.1.0).

include_once ("/include/autoload.php"); 
$pool = new phpcassa\Connection\ConnectionPool('testdb'); 
$connection = $pool->get(); 
$rows = $connection->client->execute_cql3_query("SELECT id, fans FROM fans", cassandra\Compression::NONE, cassandra\ConsistencyLevel::ONE); 
var_dump($rows->rows); 
$pool->return_connection($connection); 
unset($connection); 
$pool->close(); 

Это также хорошо работает.

array (size=1) 
    0 => 
    object(cassandra\CqlRow)[10] 
     public 'key' => string '' (length=0) 
     public 'columns' => 
     array (size=2) 
      0 => 
      object(cassandra\Column)[11] 
       public 'name' => string 'id' (length=2) 
       public 'value' => string 'John' (length=4) 
       public 'timestamp' => null 
       public 'ttl' => null 
      1 => 
      object(cassandra\Column)[12] 
       public 'name' => string 'fans' (length=4) 
       public 'value' => string '��band�Beatles�fruit�apple�movie�Cassablanca' (length=51) 
       public 'timestamp' => null 
       public 'ttl' => null 

Проблема заключается в том, как распаковать значение, представленное в виде карты? я могу видеть

��band�Beatles�fruit�apple�movie�Cassablanca 

, и я знаю, что это showld быть

{'band': 'Beatles', 'fruit': 'apple', 'movie': 'Cassablanca'} 

Есть ли какая-то внутренняя функция десериализовать или распаковать эту закодированную строку в карте или массив?

Я wroute функции, которая считывает непечатаемые символы:

function unistr_to_ords($str, $encoding = 'UTF-8') { 
    $str = mb_convert_encoding($str, 'UCS-4BE', $encoding); 
    $ords = array(); 
    for ($i = 0; $i < mb_strlen($str, 'UCS-4BE'); $i++) { 
     $s2 = mb_substr($str, $i, 1, 'UCS-4BE'); 
     $val = unpack('N', $s2); 
     $ords[] = $val[1]; 
    } 
    return($ords); 
} 

И когда я пытаюсь его с этим значением я вижу следующий результат:

array (size=51) 
    0 => int 0 
    1 => int 3 
    2 => int 0 
    3 => int 4 
    4 => int 98 
    5 => int 97 
    6 => int 110 
    7 => int 100 
    8 => int 0 
    9 => int 7 
    10 => int 66 
    11 => int 101 
    12 => int 97 
    13 => int 116 
    14 => int 108 
    15 => int 101 
    16 => int 115 
    17 => int 0 
    18 => int 5 
    19 => int 102 
    20 => int 114 
    21 => int 117 
    22 => int 105 
    23 => int 116 
    24 => int 0 
    25 => int 5 
    26 => int 97 
    27 => int 112 
    28 => int 112 
    29 => int 108 
    30 => int 101 
    31 => int 0 
    32 => int 5 
    33 => int 109 
    34 => int 111 
    35 => int 118 
    36 => int 105 
    37 => int 101 
    38 => int 0 
    39 => int 11 
    40 => int 67 
    41 => int 97 
    42 => int 115 
    43 => int 115 
    44 => int 97 
    45 => int 98 
    46 => int 108 
    47 => int 97 
    48 => int 110 
    49 => int 99 
    50 => int 97 

Как я понял, 0 (ноль) является разделителем, после 0 - длина, например первый 03 означает 3 элемента на карте. Тогда 04 означает, что 4 - это длина слова «полоса», тогда 07 означает новое слово длиной 7 для слова «Битлз» и так далее.

Но какой-либо внутренний встроенный метод или функция для извлечения карты, списка или набора?

ответ

1

Возможно, кто-то взломал что-то вместе, но официальный ответ заключается в том, что phpcassa не поддерживает CQL3 и, следовательно, не поддерживает функции CQL3, такие как коллекции колонок (карты, наборы и списки).

0

Я надеялся найти что-то, чтобы сделать это, но не мог, поэтому я взломал это. Работает для карты < текст, текст >. Это то, что я использую. Думал, что я поместил его сюда для всех, кто смотрит.

function cql3_map_to_array($map) { 
    $byte_array = unpack('C*', $map); 
    $map_array = array(); 

    if(sizeof($byte_array) > 2) { 
     $pos = 1; 
     $size = (intval($byte_array[$pos]) * 256) + intval($byte_array[$pos + 1]); 
     $pos += 2; 

     while($size > 0) { 
      $length = (intval($byte_array[$pos]) * 256) + intval($byte_array[$pos + 1]); 
      $pos += 2; 
      $key = substr($map, $pos - 1, $length); 
      $pos += $length; 

      $length = (intval($byte_array[$pos]) * 256) + intval($byte_array[$pos + 1]); 
      $pos += 2; 
      $value = substr($map, $pos - 1, $length); 
      $pos += $length; 

      $map_array[$key] = $value; 

      $size--; 
     } 
    } 

    return $map_array; 
} 
Смежные вопросы