| 68 | } |
| 69 | |
| 70 | PropertyMap *PropertyMap_New |
| 71 | ( |
| 72 | const cypher_astnode_t *props |
| 73 | ) { |
| 74 | if(props == NULL) return NULL; |
| 75 | ASSERT(cypher_astnode_type(props) == CYPHER_AST_MAP); // TODO add parameter support |
| 76 | |
| 77 | uint prop_count = cypher_ast_map_nentries(props); |
| 78 | |
| 79 | PropertyMap *map = rm_malloc(sizeof(PropertyMap)); |
| 80 | map->keys = array_new(const char *, prop_count); |
| 81 | map->values = array_new(AR_ExpNode *, prop_count); |
| 82 | |
| 83 | for(uint prop_idx = 0; prop_idx < prop_count; prop_idx++) { |
| 84 | uint insert_idx = prop_idx; |
| 85 | const cypher_astnode_t *ast_key = cypher_ast_map_get_key(props, prop_idx); |
| 86 | const char *attribute = cypher_ast_prop_name_get_value(ast_key); |
| 87 | const cypher_astnode_t *ast_value = cypher_ast_map_get_value(props, prop_idx); |
| 88 | AR_ExpNode *value = AR_EXP_FromASTNode(ast_value); |
| 89 | |
| 90 | // search for duplicate attributes |
| 91 | uint count = array_len(map->keys); |
| 92 | for (uint i = 0; i < count; i++) { |
| 93 | if(strcmp(attribute, map->keys[i]) == 0) { |
| 94 | insert_idx = i; |
| 95 | break; |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | if(insert_idx == prop_idx) { |
| 100 | array_append(map->keys, attribute); |
| 101 | array_append(map->values, value); |
| 102 | } else { |
| 103 | AR_EXP_Free(map->values[insert_idx]); |
| 104 | map->values[insert_idx] = value; |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | return map; |
| 109 | } |
| 110 | |
| 111 | static PropertyMap *_PropertyMap_Clone |
| 112 | ( |
no test coverage detected