This guide explains the minimum and recommended steps to add a new pluggable data source implementation to the Beep Data Management (BeepDM) platform.
Core contracts:
IDataSource– CRUD, metadata, connection, scripting operations.IDataConnection– Low level connection state & properties.EntityStructure/EntityField– In-memory schema model.RelationShipKeys/ChildRelation– Relationship metadata.IErrorsInfo– Standard error container.IDMEEditor– Central orchestrator (logging, utilities, type builder, config, ETL context).
Optional helpers:
RDBMSHelper,DMTypeBuilder,ObservableBindingList<T>,ETLScriptDet,PagedResult.
Create a plugin project (Class Library) under BeepDataSources/DataSourcesPlugins/<YourDataSource>.
Reference core projects:
DataManagementModelsStandardDataManagementEngineStandardAssembly_helpersStandard(if using assembly/type utilities)
public class MySource : IDataSource {
public string GuidID { get; set; } = Guid.NewGuid().ToString();
public string DatasourceName { get; set; }
public DataSourceType DatasourceType { get; set; }
public DatasourceCategory Category { get; set; } = DatasourceCategory.Other; // or specialized
public IDataConnection Dataconnection { get; set; }
public IErrorsInfo ErrorObject { get; set; }
public IDMLogger Logger { get; set; }
public List<string> EntitiesNames { get; set; } = new();
public List<EntityStructure> Entities { get; set; } = new();
public IDMEEditor DMEEditor { get; set; }
public ConnectionState ConnectionStatus { get; set; }
public string ColumnDelimiter { get; set; } = "\""; // adjust per provider
public string ParameterDelimiter { get; set; } = "@"; // adjust per provider
public event EventHandler<PassedArgs> PassEvent;
public MySource(string name, IDMLogger logger, IDMEEditor editor, DataSourceType type, IErrorsInfo errors) {
DatasourceName = name;
Logger = logger;
DMEEditor = editor;
DatasourceType = type;
ErrorObject = errors;
Dataconnection = new MyDataConnection(editor) { Logger = logger, ErrorObject = errors };
}
// Implement required members ...
}| Method | Purpose |
|---|---|
Openconnection / Closeconnection |
Manage physical connectivity. |
GetEntitesList |
Populate EntitiesNames (tables/collections). |
GetEntityStructure |
Load schema metadata (fields, PKs, relations). |
GetEntityType |
Build runtime type (via DMTypeBuilder). |
GetEntity / GetEntityAsync |
Retrieve data (return IBindingList). |
InsertEntity / UpdateEntity / DeleteEntity |
CRUD operations. |
ExecuteSql / RunQuery / GetScalar |
Generic execution helpers. |
CreateEntityAs / GetCreateEntityScript |
DDL support (optional for read-only providers). |
- Obtain a lightweight schema snapshot (provider metadata API or DESCRIBE equivalent).
- Map columns to
EntityField(type, length, nullability, PK flag, uniqueness, identity/auto number, precision/scale). - Build
PrimaryKeys&Relationslists if available. - Cache in
Entitiesfor reuse.
- Accept either a pure entity name or a raw SELECT.
- Support an optional
List<AppFilter>(field, operator, value) to parameterize queries. - Return an
ObservableBindingList<T>whereTis a runtime type built for the entity.
- Always use provider parameter prefix (e.g.
@,:,?). - Maintain a set of used parameter names to avoid collisions.
- Skip auto increment / computed fields on INSERT.
- Place PK fields only in WHERE clause for UPDATE & DELETE.
Use DMEEditor.AddLogMessage(level, message, date, code, context, flag) and set ErrorObject.Flag / ErrorObject.Message consistently.
Expose a GetEntity(..., pageNumber, pageSize) using provider-specific paging (LIMIT/OFFSET, ROW_NUMBER, TOP + OFFSET/FETCH, etc.).
If write-enabled:
- Provide
CreateEntity(EntityStructure)logic mapping field definitions to provider types. - Handle auto number / identity syntax per provider.
- Generate FK constraints separately if required.
Implement introspection queries to populate RelationShipKeys and ChildRelation for navigation / modeling features.
- Open / close connection lifecycle.
- Entity list non-empty.
- Schema load matches actual column definitions.
- Insert / Update / Delete round trip.
- Filtering returns expected row subsets.
- Pagination boundaries (page 1, last page, empty).
- DDL script executes cleanly (if supported).
If your backend is read-only (e.g. REST, flat file catalog):
- Implement only: connection open/close (may be no-op),
GetEntitesList,GetEntityStructure,GetEntity,RunQuery(optional), and set CRUD methods to return failure (Errors.NotImplemented).
- Add project to solution & reference shared assemblies.
- Implement any driver metadata (adapter/command types) in config if needed.
- Update any plugin discovery manifest (if used) so
IDMEEditor.GetDataSource(name)can instantiate it. - Build NuGet package if distributed separately.
Override in advanced scenarios:
- Custom parameter naming (
GetInsertStringetc.) - Vendor specific identity fetch
- Advanced query rewriting (sharding / multi-tenancy)
- Optimistic concurrency tokens
- Reuse commands where safe (prepare once for bulk loops).
- Avoid loading full schema repeatedly; cache until explicit refresh.
- Batch inserts where provider supports table-valued / bulk APIs.
| Issue | Resolution |
|---|---|
| Mismatched runtime type vs. schema | Refresh EntityStructure then rebuild type. |
| Parameter collisions | Track & uniquify names (suffix counter). |
| Identity not returned | Ensure provider-specific identity retrieval is correct. |
| Null vs empty string confusion | Normalize before parameter assignment. |
Follow this guide to ensure consistency and interoperability across all BeepDM data source plugins.