我需要拦截所有查询(比如说,做一些结构化的日志记录)。
该应用程序已经使用了一个子类DBI,所以我希望我可以将我需要的代码注入execute
类中的MyDB::st
重载。
显然,这还不够。
在下面的示例中,MyDB::st::execute
仅在示例2中执行。它不会在我呼叫do
的情况下执行,也不会在我呼叫selectrow_array
的情况下执行(即使文档说selectrow_array
结合了prepare
,execute
,和fetchrow_hashref
)。
我是否还需要重载MyDB::db
类中的语句?有很多(do
,selectrow_array
,selectrow_arrayref
,selectrow_hashref
,selectall_arrayref
,selectall_array
,selectall_hashref
,{{ 1}}等等。我希望我能避免这种情况。
该示例使用SQLite来简化,但我检查的其他驱动程序也是如此。
selectcol_arrayref
答案 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_TRACE和https://metacpan.org/pod/DBI#TRACING