@@ -58,6 +58,13 @@ typedef struct geoOptions {
5858 zend_string * key ;
5959} geoOptions ;
6060
61+ typedef struct redisLcsOptions {
62+ zend_bool len ;
63+ zend_bool idx ;
64+ zend_long minmatchlen ;
65+ zend_bool withmatchlen ;
66+ } redisLcsOptions ;
67+
6168/* Local passthrough macro for command construction. Given that these methods
6269 * are generic (so they work whether the caller is Redis or RedisCluster) we
6370 * will always have redis_sock, slot*, and */
@@ -2222,6 +2229,102 @@ redis_hstrlen_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
22222229 return SUCCESS ;
22232230}
22242231
2232+ void redis_get_lcs_options (redisLcsOptions * dst , HashTable * ht ) {
2233+ zend_string * key ;
2234+ zval * zv ;
2235+
2236+ ZEND_ASSERT (dst != NULL );
2237+
2238+ memset (dst , 0 , sizeof (* dst ));
2239+
2240+ if (ht == NULL )
2241+ return ;
2242+
2243+ ZEND_HASH_FOREACH_STR_KEY_VAL (ht , key , zv ) {
2244+ if (key ) {
2245+ if (zend_string_equals_literal_ci (key , "LEN" )) {
2246+ dst -> idx = 0 ;
2247+ dst -> len = zval_is_true (zv );
2248+ } else if (zend_string_equals_literal_ci (key , "IDX" )) {
2249+ dst -> len = 0 ;
2250+ dst -> idx = zval_is_true (zv );
2251+ } else if (zend_string_equals_literal_ci (key , "MINMATCHLEN" )) {
2252+ dst -> minmatchlen = zval_get_long (zv );
2253+ } else if (zend_string_equals_literal_ci (key , "WITHMATCHLEN" )) {
2254+ dst -> withmatchlen = zval_is_true (zv );
2255+ } else {
2256+ php_error_docref (NULL , E_WARNING , "Unknown LCS option '%s'" , ZSTR_VAL (key ));
2257+ }
2258+ } else if (Z_TYPE_P (zv ) == IS_STRING ) {
2259+ if (zend_string_equals_literal_ci (Z_STR_P (zv ), "LEN" )) {
2260+ dst -> idx = 0 ;
2261+ dst -> len = 1 ;
2262+ } else if (zend_string_equals_literal_ci (Z_STR_P (zv ), "IDX" )) {
2263+ dst -> idx = 1 ;
2264+ dst -> len = 0 ;
2265+ } else if (zend_string_equals_literal_ci (Z_STR_P (zv ), "WITHMATCHLEN" )) {
2266+ dst -> withmatchlen = 1 ;
2267+ }
2268+ }
2269+ } ZEND_HASH_FOREACH_END ();
2270+ }
2271+
2272+ /* LCS */
2273+ int redis_lcs_cmd (INTERNAL_FUNCTION_PARAMETERS , RedisSock * redis_sock ,
2274+ char * * cmd , int * cmd_len , short * slot , void * * ctx )
2275+ {
2276+ zend_string * key1 = NULL , * key2 = NULL ;
2277+ smart_string cmdstr = {0 };
2278+ HashTable * ht = NULL ;
2279+ redisLcsOptions opt ;
2280+ int argc ;
2281+
2282+ ZEND_PARSE_PARAMETERS_START (2 , 3 )
2283+ Z_PARAM_STR (key1 )
2284+ Z_PARAM_STR (key2 )
2285+ Z_PARAM_OPTIONAL
2286+ Z_PARAM_ARRAY_HT_OR_NULL (ht )
2287+ ZEND_PARSE_PARAMETERS_END_EX (return FAILURE );
2288+
2289+ key1 = redis_key_prefix_zstr (redis_sock , key1 );
2290+ key2 = redis_key_prefix_zstr (redis_sock , key2 );
2291+
2292+ if (slot ) {
2293+ * slot = cluster_hash_key_zstr (key1 );
2294+ if (* slot != cluster_hash_key_zstr (key2 )) {
2295+ php_error_docref (NULL , E_WARNING , "Warning, not all keys hash to the same slot!" );
2296+ zend_string_release (key1 );
2297+ zend_string_release (key2 );
2298+ return FAILURE ;
2299+ }
2300+ }
2301+
2302+ redis_get_lcs_options (& opt , ht );
2303+
2304+ argc = 2 + !!opt .idx + !!opt .len + !!opt .withmatchlen + (opt .minmatchlen ? 2 : 0 );
2305+ REDIS_CMD_INIT_SSTR_STATIC (& cmdstr , argc , "LCS" );
2306+
2307+ redis_cmd_append_sstr_zstr (& cmdstr , key1 );
2308+ redis_cmd_append_sstr_zstr (& cmdstr , key2 );
2309+
2310+ REDIS_CMD_APPEND_SSTR_OPT_STATIC (& cmdstr , opt .idx , "IDX" );
2311+ REDIS_CMD_APPEND_SSTR_OPT_STATIC (& cmdstr , opt .len , "LEN" );
2312+ REDIS_CMD_APPEND_SSTR_OPT_STATIC (& cmdstr , opt .withmatchlen , "WITHMATCHLEN" );
2313+
2314+ if (opt .minmatchlen ) {
2315+ REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr , "MINMATCHLEN" );
2316+ redis_cmd_append_sstr_long (& cmdstr , opt .minmatchlen );
2317+ }
2318+
2319+ zend_string_release (key1 );
2320+ zend_string_release (key2 );
2321+
2322+ * cmd = cmdstr .c ;
2323+ * cmd_len = cmdstr .len ;
2324+ return SUCCESS ;
2325+ }
2326+
2327+
22252328/* BITPOS */
22262329int redis_bitpos_cmd (INTERNAL_FUNCTION_PARAMETERS , RedisSock * redis_sock ,
22272330 char * * cmd , int * cmd_len , short * slot , void * * ctx )
0 commit comments