修改MVCActiveRecord支持匿名函数(用于动态决定数据库连接)

news2024/12/26 18:57:51

要修改 TMVCActiveRecordMiddleware 以直接接受一个匿名函数(用于动态决定数据库连接)以及一个配置文件名,你需要对构造函数进行一些调整。这可以通过重载构造函数以接收另一个参数——匿名函数来实现。

构造函数修改步骤

假设你的目标是允许传入一个匿名函数,用于在运行时选择数据库连接名称。对于 FireDAC 的 ActiveRecord 支持,你可能需要一个逻辑,在中间件初始化时通过连接配置文件动态加载连接定义。

以下是如何修改和添加新的构造函数:

  1. 定义合适的匿名函数类型:假设你希望使用 TFunc<TWebContext, string> 类型的函数来动态提供数据库连接定义名称。
  2. 修改构造函数以接受匿名函数:添加新的构造函数。

修改后的代码

type
  // 新增的匿名函数类型,用于获取连接定义名称
  TConnectionDefNameResolver = reference to function(AContext: TWebContext): string;

  TMVCActiveRecordMiddleware = class(TInterfacedObject, IMVCMiddleware)
  private
    fDefaultConnectionDefName: string;
    fConnectionDefFileName: string;
    fConnectionLoaded: Boolean;
    fResolver: TConnectionDefNameResolver; // 新增成员
  protected
    procedure EnsureConnection(AContext: TWebContext);
    // ...
  public
    // 新的构造函数,接收匿名函数
    constructor Create(
      const Resolver: TConnectionDefNameResolver;
      const ConnectionDefFileName: string = 'FDConnectionDefs.ini'); overload;

    // ...
  end;

constructor TMVCActiveRecordMiddleware.Create(
  const Resolver: TConnectionDefNameResolver;
  const ConnectionDefFileName: string);
begin
  inherited Create;
  fConnectionLoaded := False;
  fResolver := Resolver; // 赋值匿名函数
  fConnectionDefFileName := ConnectionDefFileName;
end;

procedure TMVCActiveRecordMiddleware.EnsureConnection(AContext: TWebContext);
var
  ConnectionDefName: string;
begin
  if fConnectionLoaded then
  begin
    Exit;
  end;

  TMonitor.Enter(Self);
  try
    if fConnectionLoaded then
    begin
      Exit;
    end;
    if TInterlocked.CompareExchange(gCONNECTION_DEF_FILE_LOADED, 1, 0) = 0 then
    begin
      FDManager.ConnectionDefFileAutoLoad := False;
      FDManager.ConnectionDefFileName := fConnectionDefFileName;
      if not FDManager.ConnectionDefFileLoaded then
      begin
        FDManager.LoadConnectionDefFile;
      end;
    end;

    // 使用匿名函数动态获取连接定义名称
    if Assigned(fResolver) then
    begin
      ConnectionDefName := fResolver(AContext);
      if FDManager.IsConnectionDef(ConnectionDefName) then
      begin
        ActiveRecordConnectionsRegistry.AddDefaultConnection(ConnectionDefName);
      end
      else
      begin
        raise EMVCConfigException.CreateFmt('ConnectionDefName "%s" not found in config file "%s"',
          [ConnectionDefName, FDManager.ActualConnectionDefFileName]);
      end;
    end;

    fConnectionLoaded := True;
  finally
    TMonitor.Exit(Self);
  end;
end;

procedure TMVCActiveRecordMiddleware.OnBeforeRouting(AContext: TWebContext; var AHandled: Boolean);
begin
  // 用于确保每次请求都动态评价连接名
  EnsureConnection(AContext);
  AHandled := False;
end;

在 Web Module 中的配置

使用这个新的构造函数,可以在 WebModuleCreate 中注册中间件:

procedure TMyWebModule.WebModuleCreate(Sender: TObject);
begin
  FMVC := TMVCEngine.Create(Self,
    procedure(Config: TMVCConfig)
    begin
      // 通用配置
    end);

  // 注册中间件并传递匿名函数
  FMVC.AddMiddleware(TMVCActiveRecordMiddleware.Create(
    function(AContext: TWebContext): string
    var
      DBIdentifier: string;
    begin
      // 身份认证的检查
      if not AContext.LoggedUser.IsValid then
        raise EMVCException.Create(HTTP_STATUS.Unauthorized, 'Unauthorized access');

      // 从请求中确定数据库名称
      DBIdentifier := AContext.Request.BodyParam('database_name');
      if DBIdentifier = '' then
        raise EMVCException.Create(HTTP_STATUS.BadRequest, 'Database name must be provided');

      if not IsDatabaseAllowed(DBIdentifier) then
        raise EMVCException.Create(HTTP_STATUS.Forbidden, 'Access to this database is not allowed');

      Result := DBIdentifier;  // 返回有效的连接定义名称
    end,
    'FDConnectionDefs.ini'  // 连接定义文件
  ));

  // 其他中间件注册和配置
end;

注意事项

  • 错误处理:确保在匿名函数中和配置检查中有适当的错误处理机制。
  • 线程安全:考虑多线程环境下对连接的访问和修改是否安全。
  • 性能:确保在高并发环境下性能最佳,尽量减少锁定时间和资源占用。

通过这些修改,你可以让 TMVCActiveRecordMiddleware 更加灵活地根据请求上下文动态选择数据库连接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2253108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nginx Web服务器管理、均衡负载、访问控制与跨域问题

Nginx Web 服务器的均衡负载、访问控制与跨域问题 Nginx 的配置 1. 安装Nginx 首先安装Nginx apt install nginx -ycaccpurgatory-v:~$ sudo apt install nginx [sudo] password for cacc: Reading package lists... Done Building dependency tree... Done Reading state i…

Bert+CRF的NER实战

CRF&#xff08;条件随机场-Conditional Random Field&#xff09; 原始本文&#xff1a;我在北京吃炸酱面 标注示例&#xff08;采用BIO标注方式&#xff09;&#xff1a; 我O在O北B-PLA京I-PLA吃O炸B-FOOD酱I-FOOD面I-FOOD CRF&#xff1a; 目的&#xff1a;提出一些不可能…

C++语法·识

人生建议&#xff1a;请手机反省一下&#xff0c;为什么总拉着我熬夜。 目录 STL简介 string类容器一 auto&#xff08;自动声明类型&#xff09; 简介&#xff1a; 特点 范围for&#xff08;语法糖&#xff09; 简介 特点 string string类的常见接口 1.构造 2.容…

蓝桥杯准备训练(lesson1,c++方向)

前言 报名参加了蓝桥杯&#xff08;c&#xff09;方向的宝子们&#xff0c;今天我将与大家一起努力参赛&#xff0c;后序会与大家分享我的学习情况&#xff0c;我将从最基础的内容开始学习&#xff0c;带大家打好基础&#xff0c;在每节课后都会有练习题&#xff0c;刚开始的练…

【开源】A059-基于SpringBoot的社区养老服务系统的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看项目链接获取⬇️&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600个选题ex…

winform跨线程更新界面

前言&#xff1a; 大家好&#xff0c;我是上位机马工&#xff0c;硕士毕业4年年入40万&#xff0c;目前在一家自动化公司担任软件经理&#xff0c;从事C#上位机软件开发8年以上&#xff01;我们在开发C#程序的时候&#xff0c;有时候需要在非Ui主线程更新界面&#xff0c;为了…

无界(wujie)微前端项目搭建,nginx线上部署,pnpm一键安装依赖、启动应用,git代码仓库存放方式

这里写自定义目录标题 1. 创建项目项目目录布局选择主应用子应用 2. pnpm包管理&#xff0c;一键安装、启动、打包pnpm一键安装依赖npm-run-all 一键启动、打包 3. nginx线上部署主应用中子应用中nginx文件目录及配置 git代码存放方式 1. 创建项目 主应用&#xff1a; vue3vit…

10.容器-list列表

定义一个list使用[] 定义一个空列表 [] 或者 list() 列表中每个元素之间用逗号隔开 a_list [aa, bb, cc] print(a_list) # <class list> print(type(a_list)) list列表可以存储不同类型的元素 a_list [aa, bb, cc] print(a_list) # <class list> print(type…

BiGRU:双向门控循环单元在序列处理中的深度探索

一、引言 在当今的人工智能领域&#xff0c;序列数据的处理是一个极为重要的任务&#xff0c;涵盖了自然语言处理、语音识别、时间序列分析等多个关键领域。循环神经网络&#xff08;RNN&#xff09;及其衍生结构在处理序列数据方面发挥了重要作用。然而&#xff0c;传统的 RN…

PDF与PDF/A的区别及如何使用Python实现它们之间的相互转换

目录 概述 PDF/A 是什么&#xff1f;与 PDF 有何不同&#xff1f; 用于实现 PDF 与 PDF/A 相互转换的 Python 库 Python 实现 PDF 转 PDF/A 将 PDF 转换为 PDF/A-1a 将 PDF 转换为 PDF/A-1b 将 PDF 转换为 PDF/A-2a 将 PDF 转换为 PDF/A-2b 将 PDF 转换为 PDF/A-3a 将…

计费结算系统的架构设计思路

背景 近期负责关于集团的计费结算相关的系统&#xff0c;相对于2C系统的大流量&#xff0c;高并发的场景&#xff0c;计费和结算的信息对稳定性要求更高。对时效性要求并没有过于严苛的要求。那么接下来就和大家分享一下计费结算系统的架构设计。 模块划分 我们暂且将平台细分…

人工智障(5)

今天kimi把我气疯了&#xff0c;你们看原对话&#xff1a; 月之暗面最近在搞什么&#xff0c;不仅算力慢&#xff0c;而且回答离谱的要死&#xff0c;难道换老板了&#xff1f;

Python爬虫——城市数据分析与市场潜能计算(Pandas库)

使用Python进行城市市场潜能分析 简介 本教程将指导您如何使用Python和Pandas库来处理城市数据&#xff0c;包括GDP、面积和城市间距离。我们将计算每个城市的市场潜能&#xff0c;这有助于了解各城市的经济影响力。 步骤 1: 准备环境 确保您的环境中安装了Python和以下库&…

Python毕业设计选题:基于Flask的医疗预约与诊断系统

开发语言&#xff1a;Python框架&#xff1a;flaskPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 系统首页 疾病信息 就诊信息 个人中心 管理员登录界面 管理员功能界面 用户界面 医生…

Android 图形系统之二:ViewRootImpl

ViewRootImpl简介 ViewRootImpl 是 Android UI 系统的核心类之一&#xff0c;负责将 View 层级树与窗口管理器 WindowManager 联系起来。它是Android 应用视图的根节点&#xff0c;与 WindowManager 结合&#xff0c;实现视图的绘制、事件分发、窗口更新等功能。虽然 ViewRoot…

python通过ODBC连接神通数据库

1、安装神通数据库 2、安装python 3、安装pyodbc pip3 install pyodbc-5.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 注&#xff1a;pyodbc要和python版本相对应 4、安装unixodbc 5、配置神通数据库ODBC数据源 6、示例代码如下 #!/usr/bin/python…

基于单片机的智能药箱设计

本设计主要由红外检测传感器、显示、独立按键、舵机、语音以及短信等模块组成。红外传感器模块主要对药仓中的药物数据进行采集&#xff0c;采集完毕由主控制器进行数据加工&#xff0c;之后可传送至显示模块上进行显示&#xff0c;在显示模块也可对显示时间、吃药倒计时、吃药…

【掩体计划——DFS+缩点】

题目 代码 #include <bits/stdc.h> using namespace std; const int N 1e5 10; vector<vector<int>> g; bool st[N]; int ans 1e9; bool dfs(int f, int u, int dis) {bool is 1;for (auto j : g[u]){if (j f)continue;is & dfs(u, j, dis (g[u].…

无人机点云处理算法技术解析!

一、核心技术 数据预处理&#xff1a; 数据预处理是点云处理的第一步&#xff0c;主要包括滤波、去噪、数据压缩等。滤波技术可以去除点云数据中的噪声和孤立点&#xff0c;提高数据质量。常用的滤波方法包括双边滤波、高斯滤波等。 数据压缩则用于减少数据量&#xff0c;提…

Android13 允许桌面自动旋转

一&#xff09;需求-场景 Android13 实现允许桌面自动旋转 Android13 版本开始后&#xff0c;支持屏幕自动旋转&#xff0c;优化体验和兼容性&#xff0c;适配不同屏幕 主界面可自动旋转 二&#xff09;参考资料 android framework13-launcher3【06手机旋转问题】 Launcher默…