Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ common_libswsscommon_la_SOURCES = \
common/c-api/util.cpp \
common/c-api/dbconnector.cpp \
common/c-api/configdbconnector.cpp \
common/c-api/sonicv2connector.cpp \
common/c-api/consumerstatetable.cpp \
common/c-api/producerstatetable.cpp \
common/c-api/subscriberstatetable.cpp \
Expand Down
162 changes: 162 additions & 0 deletions common/c-api/sonicv2connector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#include <cstring>
#include <string>
#include <utility>
#include <map>
#include <vector>

#include "../sonicv2connector.h"
#include "sonicv2connector.h"
#include "util.h"

using namespace swss;
using namespace std;

SWSSResult SWSSSonicV2Connector_new(uint8_t use_unix_socket_path, const char *netns, SWSSSonicV2Connector *outConnector) {
SWSSTry({
string netns_str = netns ? string(netns) : "";
*outConnector = (SWSSSonicV2Connector) new SonicV2Connector_Native(use_unix_socket_path != 0, netns_str.c_str());
});
}

SWSSResult SWSSSonicV2Connector_free(SWSSSonicV2Connector connector) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
SWSSTry(delete (SonicV2Connector_Native *)connector);
#pragma GCC diagnostic pop
}

SWSSResult SWSSSonicV2Connector_getNamespace(SWSSSonicV2Connector connector, SWSSString *outNamespace) {
SWSSTry({
string ns = ((SonicV2Connector_Native *)connector)->getNamespace();
*outNamespace = makeString(std::move(ns));
});
}

SWSSResult SWSSSonicV2Connector_connect(SWSSSonicV2Connector connector, const char *db_name, uint8_t retry_on) {
SWSSTry(((SonicV2Connector_Native *)connector)->connect(string(db_name), retry_on != 0));
}

SWSSResult SWSSSonicV2Connector_close_db(SWSSSonicV2Connector connector, const char *db_name) {
SWSSTry(((SonicV2Connector_Native *)connector)->close(string(db_name)));
}

SWSSResult SWSSSonicV2Connector_close_all(SWSSSonicV2Connector connector) {
SWSSTry(((SonicV2Connector_Native *)connector)->close());
}

SWSSResult SWSSSonicV2Connector_get_db_list(SWSSSonicV2Connector connector, SWSSStringArray *outDbList) {
SWSSTry({
auto db_list = ((SonicV2Connector_Native *)connector)->get_db_list();
*outDbList = makeStringArray(std::move(db_list));
});
}

SWSSResult SWSSSonicV2Connector_get_dbid(SWSSSonicV2Connector connector, const char *db_name, int *outDbId) {
SWSSTry({
*outDbId = ((SonicV2Connector_Native *)connector)->get_dbid(string(db_name));
});
}

SWSSResult SWSSSonicV2Connector_get_db_separator(SWSSSonicV2Connector connector, const char *db_name, SWSSString *outSeparator) {
SWSSTry({
string separator = ((SonicV2Connector_Native *)connector)->get_db_separator(string(db_name));
*outSeparator = makeString(std::move(separator));
});
}

SWSSResult SWSSSonicV2Connector_get_redis_client(SWSSSonicV2Connector connector, const char *db_name, SWSSDBConnector *outDbConnector) {
SWSSTry({
DBConnector& redis_client = ((SonicV2Connector_Native *)connector)->get_redis_client(string(db_name));
*outDbConnector = (SWSSDBConnector)&redis_client;
});
}

SWSSResult SWSSSonicV2Connector_publish(SWSSSonicV2Connector connector, const char *db_name, const char *channel, const char *message, int64_t *outResult) {
SWSSTry({
*outResult = ((SonicV2Connector_Native *)connector)->publish(string(db_name), string(channel), string(message));
});
}

SWSSResult SWSSSonicV2Connector_exists(SWSSSonicV2Connector connector, const char *db_name, const char *key, uint8_t *outExists) {
SWSSTry({
*outExists = ((SonicV2Connector_Native *)connector)->exists(string(db_name), string(key)) ? 1 : 0;
});
}

SWSSResult SWSSSonicV2Connector_keys(SWSSSonicV2Connector connector, const char *db_name, const char *pattern, uint8_t blocking, SWSSStringArray *outKeys) {
SWSSTry({
const char* pattern_str = pattern ? pattern : "*";
auto keys = ((SonicV2Connector_Native *)connector)->keys(string(db_name), pattern_str, blocking != 0);
*outKeys = makeStringArray(std::move(keys));
});
}

SWSSResult SWSSSonicV2Connector_scan(SWSSSonicV2Connector connector, const char *db_name, int cursor, const char *match, uint32_t count, int *outCursor, SWSSStringArray *outKeys) {
SWSSTry({
const char* match_str = match ? match : "";
auto result = ((SonicV2Connector_Native *)connector)->scan(string(db_name), cursor, match_str, count);
*outCursor = result.first;
*outKeys = makeStringArray(std::move(result.second));
});
}

SWSSResult SWSSSonicV2Connector_get(SWSSSonicV2Connector connector, const char *db_name, const char *hash, const char *key, uint8_t blocking, SWSSString *outValue) {
SWSSTry({
auto value = ((SonicV2Connector_Native *)connector)->get(string(db_name), string(hash), string(key), blocking != 0);
if (value) {
*outValue = makeString(std::move(*value));
} else {
*outValue = nullptr;
}
});
}

SWSSResult SWSSSonicV2Connector_hexists(SWSSSonicV2Connector connector, const char *db_name, const char *hash, const char *key, uint8_t *outExists) {
SWSSTry({
*outExists = ((SonicV2Connector_Native *)connector)->hexists(string(db_name), string(hash), string(key)) ? 1 : 0;
});
}

SWSSResult SWSSSonicV2Connector_get_all(SWSSSonicV2Connector connector, const char *db_name, const char *hash, uint8_t blocking, SWSSFieldValueArray *outFieldValues) {
SWSSTry({
auto field_values_map = ((SonicV2Connector_Native *)connector)->get_all(string(db_name), string(hash), blocking != 0);

// Convert map<string, string> to vector<pair<string, string>> for makeFieldValueArray
vector<pair<string, string>> pairs;
pairs.reserve(field_values_map.size());
for (auto &pair : field_values_map) {
pairs.push_back(make_pair(pair.first, move(pair.second)));
}

*outFieldValues = makeFieldValueArray(std::move(pairs));
});
}

SWSSResult SWSSSonicV2Connector_hmset(SWSSSonicV2Connector connector, const char *db_name, const char *key, const SWSSFieldValueArray *values) {
SWSSTry({
// Convert SWSSFieldValueArray to map<string, string>
map<string, string> values_map;
auto field_values = takeFieldValueArray(*values);
for (auto &fv : field_values) {
values_map[fv.first] = fv.second;
}

((SonicV2Connector_Native *)connector)->hmset(string(db_name), string(key), values_map);
});
}

SWSSResult SWSSSonicV2Connector_set(SWSSSonicV2Connector connector, const char *db_name, const char *hash, const char *key, const char *val, uint8_t blocking, int64_t *outResult) {
SWSSTry({
*outResult = ((SonicV2Connector_Native *)connector)->set(string(db_name), string(hash), string(key), string(val), blocking != 0);
});
}

SWSSResult SWSSSonicV2Connector_del(SWSSSonicV2Connector connector, const char *db_name, const char *key, uint8_t blocking, int64_t *outResult) {
SWSSTry({
*outResult = ((SonicV2Connector_Native *)connector)->del(string(db_name), string(key), blocking != 0);
});
}

SWSSResult SWSSSonicV2Connector_delete_all_by_pattern(SWSSSonicV2Connector connector, const char *db_name, const char *pattern) {
SWSSTry(((SonicV2Connector_Native *)connector)->delete_all_by_pattern(string(db_name), string(pattern)));
}
91 changes: 91 additions & 0 deletions common/c-api/sonicv2connector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#ifndef SWSS_COMMON_C_API_SONICV2CONNECTOR_H
#define SWSS_COMMON_C_API_SONICV2CONNECTOR_H

#include "result.h"
#include "util.h"
#include "dbconnector.h"

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

typedef struct SWSSSonicV2ConnectorOpaque *SWSSSonicV2Connector;

// Create a new SonicV2Connector
// Pass 0 to use TCP connection, 1 to use Unix socket
SWSSResult SWSSSonicV2Connector_new(uint8_t use_unix_socket_path, const char *netns, SWSSSonicV2Connector *outConnector);

// Free the SonicV2Connector
SWSSResult SWSSSonicV2Connector_free(SWSSSonicV2Connector connector);

// Get namespace
SWSSResult SWSSSonicV2Connector_getNamespace(SWSSSonicV2Connector connector, SWSSString *outNamespace);

// Connect to a specific database
SWSSResult SWSSSonicV2Connector_connect(SWSSSonicV2Connector connector, const char *db_name, uint8_t retry_on);

// Close connection to a specific database
SWSSResult SWSSSonicV2Connector_close_db(SWSSSonicV2Connector connector, const char *db_name);

// Close all connections
SWSSResult SWSSSonicV2Connector_close_all(SWSSSonicV2Connector connector);

// Get list of available databases
// Result array must be freed using SWSSStringArray_free()
SWSSResult SWSSSonicV2Connector_get_db_list(SWSSSonicV2Connector connector, SWSSStringArray *outDbList);

// Get database ID for a given database name
SWSSResult SWSSSonicV2Connector_get_dbid(SWSSSonicV2Connector connector, const char *db_name, int *outDbId);

// Get database separator for a given database name
SWSSResult SWSSSonicV2Connector_get_db_separator(SWSSSonicV2Connector connector, const char *db_name, SWSSString *outSeparator);

// Get Redis client for a specific database
SWSSResult SWSSSonicV2Connector_get_redis_client(SWSSSonicV2Connector connector, const char *db_name, SWSSDBConnector *outDbConnector);

// Publish a message to a channel
SWSSResult SWSSSonicV2Connector_publish(SWSSSonicV2Connector connector, const char *db_name, const char *channel, const char *message, int64_t *outResult);

// Check if a key exists
SWSSResult SWSSSonicV2Connector_exists(SWSSSonicV2Connector connector, const char *db_name, const char *key, uint8_t *outExists);

// Get all keys matching a pattern
// Result array must be freed using SWSSStringArray_free()
SWSSResult SWSSSonicV2Connector_keys(SWSSSonicV2Connector connector, const char *db_name, const char *pattern, uint8_t blocking, SWSSStringArray *outKeys);

// Scan keys with cursor-based iteration
// Returns cursor and matching keys
// Result array must be freed using SWSSStringArray_free()
SWSSResult SWSSSonicV2Connector_scan(SWSSSonicV2Connector connector, const char *db_name, int cursor, const char *match, uint32_t count, int *outCursor, SWSSStringArray *outKeys);

// Get a single field value from a hash
// Result string must be freed using SWSSString_free()
// Returns null if key/field doesn't exist
SWSSResult SWSSSonicV2Connector_get(SWSSSonicV2Connector connector, const char *db_name, const char *hash, const char *key, uint8_t blocking, SWSSString *outValue);

// Check if a field exists in a hash
SWSSResult SWSSSonicV2Connector_hexists(SWSSSonicV2Connector connector, const char *db_name, const char *hash, const char *key, uint8_t *outExists);

// Get all field-value pairs from a hash
// Result array must be freed using SWSSFieldValueArray_free()
SWSSResult SWSSSonicV2Connector_get_all(SWSSSonicV2Connector connector, const char *db_name, const char *hash, uint8_t blocking, SWSSFieldValueArray *outFieldValues);

// Set multiple field-value pairs in a hash
SWSSResult SWSSSonicV2Connector_hmset(SWSSSonicV2Connector connector, const char *db_name, const char *key, const SWSSFieldValueArray *values);

// Set a single field value in a hash
SWSSResult SWSSSonicV2Connector_set(SWSSSonicV2Connector connector, const char *db_name, const char *hash, const char *key, const char *val, uint8_t blocking, int64_t *outResult);

// Delete a key
SWSSResult SWSSSonicV2Connector_del(SWSSSonicV2Connector connector, const char *db_name, const char *key, uint8_t blocking, int64_t *outResult);

// Delete all keys matching a pattern
SWSSResult SWSSSonicV2Connector_delete_all_by_pattern(SWSSSonicV2Connector connector, const char *db_name, const char *pattern);

#ifdef __cplusplus
}
#endif

#endif
6 changes: 5 additions & 1 deletion crates/swss-common-testing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ const CONFIG_DB_REDIS_CONFIG_JSON: &str = r#"
"id": 4,
"separator": ":",
"instance": "redis"
},
"TEST_DB": {
"id": 15,
"separator": "|",
"instance": "redis"
}
}
}
Expand All @@ -160,7 +165,6 @@ const DB_GLOBAL_CONFIG_JSON: &str = r#"
{
"container_name" : "dpu0",
"include" : "db_config_test.json"

}
]
}
Expand Down
1 change: 1 addition & 0 deletions crates/swss-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ swss-common-testing = { path = "../swss-common-testing" }
paste = "1.0.15"
tokio = { version = "1", features = ["rt-multi-thread", "macros", "time"] }
serial_test.workspace = true
serde_json = "1.0"
2 changes: 1 addition & 1 deletion crates/swss-common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod bindings {
pub(crate) mod bindings {
#![allow(unused, non_snake_case, non_upper_case_globals, non_camel_case_types)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}
Expand Down
2 changes: 2 additions & 0 deletions crates/swss-common/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod events;
mod exception;
mod logger;
mod producerstatetable;
mod sonicv2connector;
mod subscriberstatetable;
mod table;
mod zmqclient;
Expand All @@ -24,6 +25,7 @@ pub use events::EventPublisher;
pub use exception::{Exception, Result};
pub use logger::{link_to_swsscommon_logger, log_level, log_output, LoggerConfigChangeHandler};
pub use producerstatetable::ProducerStateTable;
pub use sonicv2connector::SonicV2Connector;
pub use subscriberstatetable::SubscriberStateTable;
pub use table::Table;
pub use zmqclient::ZmqClient;
Expand Down
6 changes: 6 additions & 0 deletions crates/swss-common/src/types/configdbconnector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,12 @@ pub struct BorrowedDbConnector {
}

impl BorrowedDbConnector {
/// Create a new BorrowedDbConnector from a raw pointer.
/// This is intended for internal use by other modules.
pub(crate) fn new(ptr: SWSSDBConnector) -> Self {
Self { ptr }
}

/// Flush the current database, removing all keys.
/// Equivalent to Redis FLUSHDB command.
pub fn flush_db(&self) -> Result<bool> {
Expand Down
Loading
Loading