如何拦截子类DBI中的查询?

时间:2018-02-06 13:59:36

标签: perl dbi

我需要拦截所有查询(比如说,做一些结构化的日志记录)。 该应用程序已经使用了一个子类DBI,所以我希望我可以将我需要的代码注入execute类中的MyDB::st重载。

显然,这还不够。

在下面的示例中,MyDB::st::execute仅在示例2中执行。它不会在我呼叫do的情况下执行,也不会在我呼叫selectrow_array的情况下执行(即使文档说selectrow_array结合了prepareexecute ,和fetchrow_hashref)。

我是否还需要重载MyDB::db类中的语句?有很多(doselectrow_arrayselectrow_arrayrefselectrow_hashrefselectall_arrayrefselectall_arrayselectall_hashref,{{ 1}}等等。我希望我能避免这种情况。

该示例使用SQLite来简化,但我检查的其他驱动程序也是如此。

selectcol_arrayref

2 个答案:

答案 0 :(得分:3)

虽然文档根据其他方法描述了某些方法,但文档并未声明这些方法会调用其他方法。

每个驱动程序通过使用DBI提供的模板提供许多DBI方法(例如selectrow_array)的自己的实现。用C语言编写,模板中方法的实现经常直接调用驱动程序的函数,而不是通过DBI方法调用间接调用它们。

这使得调用更快,但正如您所发现的那样,这使得扩展DBI变得更加困难。

您可以找到DBI.pm中列出的所有方法的Perl实现。复制这些。这些实现都是根据以下方法定义的,限制了您必须更改的内容:

  • prepare
  • execute
  • fetch
  • fetchrow_hashref
  • fetchrow_arrayref
  • bind_col

答案 1 :(得分:2)

如果您只想做日志查询,则无需拦截任何内容。尝试设置DBI_TRACE环境变量。

DBI_TRACE=1=dbitrace.log

其中1是日志级别,第二个参数是日志文件的路径。请参阅https://metacpan.org/pod/DBI#DBI_TRACEhttps://metacpan.org/pod/DBI#TRACING