{"id":17820,"date":"2022-07-15T20:26:06","date_gmt":"2022-07-15T18:26:06","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=17820"},"modified":"2025-10-24T09:38:36","modified_gmt":"2025-10-24T07:38:36","slug":"db-crawler-a-database-search-utility-for-documentum","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/","title":{"rendered":"db-crawler, a database search utility for Documentum"},"content":{"rendered":"<p>Working with Documentum is often a frustrating experience, and one of the main causes is the lack of meaningful error messages. Be it an encouragment to the administrator or developer to refer to the official knowledge base or a gap in the user-friendliness department, this results in the dreaded venture of investigating the origin of the error, which can take hours if not days of laborious and boring work with little chance for a reward, all the while end users are complaining that nothing works any more.<br \/>\nThe last time I was confronted to this situation, the error looked quite benine at first:<\/p>\n<div>\n<div id=\"highlighter_326140\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">1 May 2022 11:33:23,580 ERROR [pool-3-thread-93] (DCTMNewRendition.java:98) - Unable to save document with <\/code><code class=\"bash functions\">id<\/code><code class=\"bash plain\">: 090f4517812cbdc7. Got a Dctm Exception<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">com.documentum.fc.client.DfIdNotFoundException: [DM_API_E_EXIST]error:\u00a0 <\/code><code class=\"bash string\">\"Document\/object specified by 080f451780000491 does not exist.\"<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">at com.documentum.fc.client.impl.docbase.DocbaseExceptionMapper.newException(DocbaseExceptionMapper.java:49) ~[dfc.jar:?]<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">at com.documentum.fc.client.impl.connection.docbase.MessageEntry.getException(MessageEntry.java:39) ~[dfc.jar:?]<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">at com.documentum.fc.client.impl.connection.docbase.DocbaseMessageManager.getException(DocbaseMessageManager.java:137) ~[dfc.jar:?]<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Just dump the above document with id 090f4517812cbdc7 and look at its permission, the parent folder&#8217;s ones, see if the current user is allowed to save the document, nothing particularly transcendent, right ? Wrong. Firstly, the given id is not the same as the current document&#8217;s that is being saved. So, where did the server pull it from ? Secondly, an attempt at dumping that id confirms that it does not exist. Now, the nightmare begins. It&#8217;s kind of like you just entered the twilight zone actually. Inconsistencies such as this one are difficult to troubleshoot and the crude error message was for sure of no help. I first hypothesized that the given id was somehow linked to the current document either through a relationship or a tbo somewhere but the developers confirmed that they had configured none. So the next obvious step is to doubt them and prove them wrong, and to do this the whole repository had to be searched for that id because somewhere in a type, deeply buried in some attribute, that id had to be contained, referencing the document to be saved, either as a standalone value or embedded in some string. This was challenging enough for me to write this little one-liner &#8211; the db-crawler &#8211; to search for that string in the whole docbase, actually the whole schema, i.e. at the database level since working from the RDBMS gives access to a considerably much richer set of functions, and this is what I&#8217;m going to show you in the next paragraph. To close this anecdotic introduction, I&#8217;ll just say that I did found a few occurrences of the given id but they lead nowhere. The actual root cause was a bad DFC cache that somehow desynchronized from the repository and went its own way. The morale of the story is that whenever one encounters weird error messages, the first thing to try is to empty the DFC cache because it probably became stale at some point (maybe the repository was upgraded, new applications deployed, doctypes modified, etc.). The good thing, as it seems there is always some benefit to even the peskiest situations, is that I had the opportunity to dust an ancient technique and share it with you here.<\/p>\n<h3>The crawler<\/h3>\n<p>As the RDBMS used by that repository was Oracle, we&#8217;ll work mainly from within the powerful command-line tool sql*plus. The trick to crawl the database schema is first to get the name of the tables of interest from the dictionary. With Oracle, the view USER_TAB_COLS is the one to consult. Here are the most useful columns:<\/p>\n<div>\n<div id=\"highlighter_120702\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1 highlighted\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">sqlplus scott<\/code><code class=\"bash plain\">\/tiger<\/code><code class=\"bash plain\">@orcl<\/code><\/div>\n<div class=\"line number2 index1 alt1 highlighted\"><code class=\"bash plain\">SQL&gt; desc USER_TAB_COLS<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash spaces\">\u00a0<\/code><code class=\"bash plain\">Name\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Null?\u00a0\u00a0\u00a0 Type<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash spaces\">\u00a0<\/code><code class=\"bash plain\">----------------------------------------- -------- ----------------------------<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash spaces\">\u00a0<\/code><code class=\"bash plain\">TABLE_NAME\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 NOT NULL VARCHAR2(128)<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash spaces\">\u00a0<\/code><code class=\"bash plain\">COLUMN_NAME\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 NOT NULL VARCHAR2(128)<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash plain\">...<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>That view contains one row for each column of each table in the user&#8217;s schema. So the crawler just has to get the names of all the columns of all the relevant tables returned by USER_TAB_COLS and generate a SELECT statement against those columns with the string to look for as the condition, e.g. the object id 080f451780000491 from the docbase. Here is how:<\/p>\n<div>\n<div id=\"highlighter_979432\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash functions\">select<\/code> <code class=\"bash string\">'select '<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">' from '<\/code> <code class=\"bash plain\">|| table_name || <\/code><code class=\"bash string\">' where '<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">' like '<\/code><code class=\"bash string\">'%080f451780000491%'<\/code><code class=\"bash string\">';'<\/code> <code class=\"bash plain\">from USER_TAB_COLS where (table_name like <\/code><code class=\"bash string\">'%\\_S'<\/code> <code class=\"bash plain\">escape <\/code><code class=\"bash string\">'\\' or table_name like '<\/code><code class=\"bash plain\">\\_%\\_R<\/code><code class=\"bash string\">' escape '<\/code><code class=\"bash plain\">\\') order by 1;<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>The relevant tables are the ones that Documentum uses to store the object&#8217;s metadata and other technical data, typically the tables ending by _S for single-valued attributes and _R for repeating attributes. All the other objects in the schema, such as the ones named like %_SP or %_SV, are views built upon the previous tables are can therefore be ignored.<br \/>\nFor more sophisticated searches, regular expressions are better suited, as shown below:<\/p>\n<div>\n<div id=\"highlighter_402773\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash functions\">select<\/code> <code class=\"bash string\">'select '<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">' from '<\/code> <code class=\"bash plain\">|| table_name || <\/code><code class=\"bash string\">' where regexp_like('<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">', '<\/code><code class=\"bash string\">'080f451780000491'<\/code><code class=\"bash string\">');'<\/code> <code class=\"bash plain\">from USER_TAB_COLS where (table_name like <\/code><code class=\"bash string\">'%\\_S'<\/code> <code class=\"bash plain\">escape <\/code><code class=\"bash string\">'\\' or table_name like '<\/code><code class=\"bash plain\">\\_%\\_R<\/code><code class=\"bash string\">' escape '<\/code><code class=\"bash plain\">\\') order by 2, 1;<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Oracle&#8217;s regular expressions are quite complete because in addition to being POSIX-compliant, they also support the perl&#8217;s non-greedy syntax; see the SQL Reference Manual for details. In the present case, we don&#8217;t have many details about the context of the given id so we use the widest possible criteria in our search, and the traditional LIKE pattern-matching condition would be plenty sufficient but let&#8217;s switch to regular expressions for generalization (too much is better that not enough, right ?).<br \/>\nThe above statement will output a list of SELECT statements, one per column to search, as illustrated below:<\/p>\n<div>\n<div id=\"highlighter_69867\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">ACCESSOR_NAME from DM_AUDIT_POLICY_S where regexp_like(ACCESSOR_NAME, <\/code><code class=\"bash string\">'080f451780000491'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">ACL_CLASS from DM_ACL_S where regexp_like(ACL_CLASS, <\/code><code class=\"bash string\">'080f451780000491'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">ACL_CLASS from DM_AUDITTRAIL_ACL_S where regexp_like(ACL_CLASS, <\/code><code class=\"bash string\">'080f451780000491'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">ACL_DOMAIN from DMI_TYPE_INFO_S where regexp_like(ACL_DOMAIN, <\/code><code class=\"bash string\">'080f451780000491'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">ACL_DOMAIN from DM_AUDITTRAIL_S where regexp_like(ACL_DOMAIN, <\/code><code class=\"bash string\">'080f451780000491'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash plain\">...<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>In order to execute them at once, they must be enclosed in an SQL script so let&#8217;s add some sugar. Still from within sql*plus:<\/p>\n<div>\n<div id=\"highlighter_577113\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">spool db-crawler.sql<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash functions\">select<\/code> <code class=\"bash string\">'select '<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">' from '<\/code> <code class=\"bash plain\">|| table_name || <\/code><code class=\"bash string\">' where '<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">' like '<\/code><code class=\"bash string\">'%080f451780000491%'<\/code><code class=\"bash string\">';'<\/code> <code class=\"bash plain\">from USER_TAB_COLS where (table_name like <\/code><code class=\"bash string\">'%\\_S'<\/code> <code class=\"bash plain\">escape <\/code><code class=\"bash string\">'\\' or table_name like '<\/code><code class=\"bash plain\">\\_%\\_R<\/code><code class=\"bash string\">' escape '<\/code><code class=\"bash plain\">\\') order by 1;<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">spool off<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Finally, let&#8217;s execute the generated sql script and capture its output into a file:<\/p>\n<div>\n<div id=\"highlighter_873670\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1 highlighted\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">spool db-crawler.out<\/code><\/div>\n<div class=\"line number2 index1 alt1 highlighted\"><code class=\"bash plain\">@db-crawler.sql<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">spool off<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>The output is redirected to the file db-crawler.out and can be searched using the familiar commands e?grep with the same search string as in the SQL statement.<\/p>\n<p>Other RDBMS supported by Documentum, such as SQL Server and PostgreSQL, obviously have their own dictionary (sys.tables respectively information_schema) and official administration tools (sqlcmd respectively psql),\u00a0 and thus the same technique can be applied to them.<\/p>\n<h3>Some enhancements<\/h3>\n<p>As we work inside sql*plus for Oracle RDBMS, let&#8217;s make the most of this tool. sql*plus allows us to factor out the searched string using a substitution variables, as follows:<\/p>\n<div>\n<div id=\"highlighter_622860\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">define search_string = <\/code><code class=\"bash string\">\"080f451780000491\"<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>It will be referenced in the script through <em>&amp;search_string<\/em>. This way, the search string can be edited easily without directly modifying the query&#8217;s code, always a good practice in scripting and programming.<br \/>\nAlso, some formatting of the sql*plus output is needed to remove spurious headers, line-wrapping and trailing blanks; we&#8217;ll do this using set statements and the sed command-line utility.<br \/>\nBefore executing it, the generated sql script can be cleaned a bit by removing non executable lines such as sql*plus command output, still inside sql*plus:<\/p>\n<div>\n<div id=\"highlighter_367401\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">!<\/code><code class=\"bash functions\">vi<\/code> <code class=\"bash plain\">db-crawler.sql<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Putting everything together plus some additional formatting instructions, we get:<\/p>\n<div>\n<div id=\"highlighter_189017\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2\">9<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">define search_string = <\/code><code class=\"bash string\">\"080f451780000491\"<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">spool db-crawler.sql<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">pagesize 0<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">linesize 1000<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">trims on<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">term out<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash functions\">select<\/code> <code class=\"bash string\">'select '<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">' from '<\/code> <code class=\"bash plain\">|| table_name || <\/code><code class=\"bash string\">' where '<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">' like '<\/code><code class=\"bash string\">'%&amp;search_string%'<\/code><code class=\"bash string\">';'<\/code> <code class=\"bash plain\">from USER_TAB_COLS where (table_name like <\/code><code class=\"bash string\">'%\\_S'<\/code> <code class=\"bash plain\">escape <\/code><code class=\"bash string\">'\\' or table_name like '<\/code><code class=\"bash plain\">\\_%\\_R<\/code><code class=\"bash string\">' escape '<\/code><code class=\"bash plain\">\\') order by 1;<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash plain\">spool off<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"bash plain\">!<\/code><code class=\"bash functions\">vi<\/code> <code class=\"bash plain\">db-crawler.sql<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"bash plain\">spool db-crawler.out<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"bash plain\">@db-crawler.sql<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"bash plain\">spool off<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"bash functions\">less<\/code> <code class=\"bash plain\">-S db-crawler.out<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>That&#8217;s a lot of typing so look down below for an easy to use wrapper script.<\/p>\n<h3>One use case: looking for IP addresses<\/h3>\n<p>Let&#8217;s seach the whole repository&#8217;s schema for any ip v4 address expressed as a dot-separated list of 4 quadruplets of 1-byte numbers each. This is useful for example when they should be replaced by their host name counterparts for portability.<br \/>\nThe regular expression for an IP adress is:<\/p>\n<div>\n<div id=\"highlighter_684803\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash comments\"># or shorter:<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">(([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\.){3}([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>IP v6 addresses are similarly constructed, except the list is an octuplet of colon-separated 16-bit words expressed in hexadecimal:<\/p>\n<div>\n<div id=\"highlighter_93249\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">[A-F0-9]{1,4}:[A-F0-9]{1,4}:[A-F0-9]{1,4}:[A-F0-9]{1,4}:[A-F0-9]{1,4}:[A-F0-9]{1,4}:[A-F0-9]{1,4}:[A-F0-9]{1,4}<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash comments\"># or shorter:<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">([A-F0-9]{1,4}:){7}[A-F0-9]{1,4}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>So, to look for any hard-coded IP v4 address in a complete repository&#8217;s schema, we would only set the variable search_string to the above regexp and use the regexp_like condition, as follows:<\/p>\n<div>\n<div id=\"highlighter_657393\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2\">9<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">define search_string = <\/code><code class=\"bash string\">\"([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\"<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">spool db-crawler.sql<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">pagesize 0<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">linesize 1000<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">trims on<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash functions\">select<\/code> <code class=\"bash string\">'select '<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">' from '<\/code> <code class=\"bash plain\">|| table_name || <\/code><code class=\"bash string\">' where regexp_like('<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">', '<\/code><code class=\"bash string\">'&amp;search_string'<\/code><code class=\"bash string\">');'<\/code> <code class=\"bash plain\">from USER_TAB_COLS where (table_name like <\/code><code class=\"bash string\">'%\\_S'<\/code> <code class=\"bash plain\">escape <\/code><code class=\"bash string\">'\\' or table_name like '<\/code><code class=\"bash plain\">\\_%\\_R<\/code><code class=\"bash string\">' escape '<\/code><code class=\"bash plain\">\\') order by 1;<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash plain\">spool off<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash plain\">!<\/code><code class=\"bash functions\">vi<\/code> <code class=\"bash plain\">db-crawler.sql<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"bash plain\">spool db-crawler.out<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"bash plain\">@db-crawler.sql<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"bash plain\">spool off<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"bash functions\">less<\/code> <code class=\"bash plain\">-S db-crawler.out<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Still in sql*plus, let&#8217;s grep the output file db-crawler.out using the same regexp and from the sql*plus environment:<\/p>\n<div>\n<div id=\"highlighter_963855\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2\">9<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">SQL&gt; !<\/code><code class=\"bash functions\">egrep<\/code> <code class=\"bash string\">'&amp;search_string'<\/code> <code class=\"bash plain\">db-crawler.out<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">6.5.0.033<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">6.5.0.031<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">6.5.0.031<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">6.5.0.031<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash plain\">6.5.0.031<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash plain\">6.5.0.031<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash plain\">6.5.0.031<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"bash plain\">6.5.0.278SP2P2400<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"bash plain\">6.5.0.037<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"bash plain\">6.5.0.037<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"bash plain\">6.5.0.150<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"bash plain\">5.3.0.0<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"bash plain\">aspose-email-4.4.0.0-jdk16.jar<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"bash plain\">castor-0.9.5.3.jar<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"bash plain\">\/app\/dctm\/product\/16<\/code><code class=\"bash plain\">.4<\/code><code class=\"bash plain\">\/lib\/castor-0<\/code><code class=\"bash plain\">.9.5.4-xml.jar<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"bash plain\">\/app\/dctm\/product\/16<\/code><code class=\"bash plain\">.4<\/code><code class=\"bash plain\">\/install\/composer\/workspace\/MailApp\/bin\/content\/19\/-740608919\/aspose-email-4<\/code><code class=\"bash plain\">.4.0.0-jdk16[1].jar<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Some manual editing is necessary here as the above regexp also matches strings such as these, which are obviously version numbers of the content server&#8217;s components. Fortunately, in the present case, those are rare.<br \/>\ngrepping can also be done from the shell&#8217;s command-line as follows:<\/p>\n<div>\n<div id=\"highlighter_557646\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">$ <\/code><code class=\"bash functions\">egrep<\/code> <code class=\"bash string\">\"([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\"<\/code> <code class=\"bash plain\">db-crawler.out<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Factoring the search string regexp, especially such complex ones, would increase the readability and lesser the likelihood of typing or copy\/pasting mistakes. See down below for a wrapper that takes into account the above point, all the sql*plus statements and the final grepping.<\/p>\n<h3>Looking for dates<\/h3>\n<p>Let&#8217;s now look for all the attributes containing a date. While the format of a displayed date depends on the current locale, dates are stored using the database&#8217;s internal format, which is likely some binary one, e.g. a counter of elapsed seconds since some reference date in the past. However, our search expression directly accesses the attribute, which is silently converted to a string by the database server using some criteria (e.g. the time zone and locale). We need therefore to force the date column to a representation that can be compared to the given search string. The easiest way to do this is to tell the sql*plus session to format dates using a conventional, common format which we will also use in the search string, as shown below:<\/p>\n<div>\n<div id=\"highlighter_975184\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">-- force the <\/code><code class=\"bash functions\">time<\/code> <code class=\"bash plain\">zone to UTC;<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">ALTER SESSION SET TIME_ZONE = <\/code><code class=\"bash string\">'0:0'<\/code><code class=\"bash plain\">;<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">-- force the <\/code><code class=\"bash functions\">date<\/code> <code class=\"bash plain\">representation to a conventional <\/code><code class=\"bash functions\">format<\/code><code class=\"bash plain\">:<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">alter session <\/code><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">NLS_DATE_FORMAT = <\/code><code class=\"bash string\">'DD\/MM\/YYYY HH24:MI:SS'<\/code><code class=\"bash plain\">;<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>A regular expression for this date format could be:<\/p>\n<div>\n<div id=\"highlighter_468947\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">[0-9]{2}\/[0-9]{2}\/[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash comments\"># or more precisely but without checking its validity during leap years:<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">([1-9]|1[0-9]|2[0-9]|3[01])([1-9]|1[0-2])([1-9][1-9]+)<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>A popular date format in IT is the basic ISO one:<\/p>\n<div>\n<div id=\"highlighter_452977\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">alter session <\/code><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">NLS_DATE_FORMAT = <\/code><code class=\"bash string\">'YYYYMMDDHH24MISS'<\/code><code class=\"bash plain\">;<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>but it is less user-friendly so we won&#8217;t use it here.<br \/>\nHowever, forcing the session date format only works when comparing stand-alone values in date columns, and not always for a date embedded in strings where it may have been converted to some format by the application or the content server itself. For example, the following values are returned from my test repository:<\/p>\n<div>\n<div id=\"highlighter_389114\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">OBJECT_NAME from DM_AUDITTRAIL_S where regexp_like(OBJECT_NAME, <\/code><code class=\"bash string\">'2022'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">2<\/code><code class=\"bash plain\">\/18\/2022<\/code> <code class=\"bash plain\">19:41:29 dm_DataDictionaryPublisher<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">2<\/code><code class=\"bash plain\">\/18\/2022<\/code> <code class=\"bash plain\">19:41:29 dm_DataDictionaryPublisher<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">2<\/code><code class=\"bash plain\">\/18\/2022<\/code> <code class=\"bash plain\">19:41:29 dm_DataDictionaryPublisher<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">2<\/code><code class=\"bash plain\">\/12\/2022<\/code> <code class=\"bash plain\">16:10:48 dm_DataDictionaryPublisher<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash plain\">...<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Here a conversion to M\/D\/YYYY HH24:MI:SS was performed by the content server while setting DM_AUDITTRAIL_S.OBJECT_NAME. A search for the first date regexp would not be able to return those values because their day part uses one digit instead of two; similarly, the second date regexp would not match either because their month part is greater than 12. So, searching dates exhaustively may require several passes with different, more relaxed search strings until all the formats used in strings, or a slightly more flexible regexp such as the following one, are tried out:<\/p>\n<div>\n<div id=\"highlighter_437045\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">[0-9]{1,2}.[0-9]{1,2}(.[0-9]{2}|[0-9]{4})?.[0-9]{1,2}.?[0-9]{1,2}.?[0-9]{1,2}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>where the date components days and months may have 1 or 2 digits, the date and time field separators can be any character (common ones are \/ and &#8211; for dates, : for times), the separator between the date and time part is anything (commonly a space or the letter T such as in logs produced by a java program), and the optional year component has 2 or 4 digits, although this is quite ambiguous even though the rule in Oracle &#8220;RRRR&#8221; datetime format can help solve the ambiguity.<\/p>\n<p>An interesting fact is shown in the output below:<\/p>\n<div>\n<div id=\"highlighter_329192\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2 highlighted\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2 highlighted\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">A_NEXT_CONTINUATION from DM_JOB_S where regexp_like(A_NEXT_CONTINUATION, <\/code><code class=\"bash string\">'[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{4}'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">01<\/code><code class=\"bash plain\">\/01\/0001<\/code> <code class=\"bash plain\">00:00:00<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">01<\/code><code class=\"bash plain\">\/01\/0001<\/code> <code class=\"bash plain\">00:00:00<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">01<\/code><code class=\"bash plain\">\/01\/0001<\/code> <code class=\"bash plain\">00:00:00<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">01<\/code><code class=\"bash plain\">\/01\/0001<\/code> <code class=\"bash plain\">00:00:00<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash plain\">...<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Those seemingly meaningless dates are actually NULLDATEs and show how the content server stores them in the Oracle database. This is RDBMS-dependent; for example, in PostgreSQL (and also in SQL Server), the content server uses 1\/1\/1753 for the NULLDATE. Therefore, the underlying RDBMS is to be considered when searching NULLDATEs and the appropriate date literal be used in such cases.<\/p>\n<h3>A cool wrapper<\/h3>\n<p>To simplify the usage of the db crawler and include the date considerations above, the bash wrapper script below can be used:<\/p>\n<div>\n<div id=\"highlighter_989933\" class=\"syntaxhighlighter  bash\">\n<table style=\"height: 723px\" border=\"0\" width=\"2674\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2\">9<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<div class=\"line number29 index28 alt2\">29<\/div>\n<div class=\"line number30 index29 alt1\">30<\/div>\n<div class=\"line number31 index30 alt2\">31<\/div>\n<div class=\"line number32 index31 alt1\">32<\/div>\n<div class=\"line number33 index32 alt2\">33<\/div>\n<div class=\"line number34 index33 alt1\">34<\/div>\n<div class=\"line number35 index34 alt2\">35<\/div>\n<div class=\"line number36 index35 alt1\">36<\/div>\n<div class=\"line number37 index36 alt2\">37<\/div>\n<div class=\"line number38 index37 alt1\">38<\/div>\n<div class=\"line number39 index38 alt2\">39<\/div>\n<div class=\"line number40 index39 alt1\">40<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash preprocessor bold\">#!\/bin\/bash<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash comments\"># Usage:<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash comments\">#\u00a0\u00a0 db-crawler.sh connect_info search_string<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash comments\"># The script invokes sql*plus with the given connect_info and passes it the search_string; <\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash comments\"># the connect_info are username[\/password][@connect_string];<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash comments\"># if the password is omitted, sqlplus prompts for one;<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash comments\"># If the search string contains spaces, it must be quoted;<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash comments\"># a sql file with a random file name $$.sql will be produced containing the appropriate SELECT statement to search the dictionary for tables in _S and _R;<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"bash comments\"># that file will be executed and generate another SQL file named db-crawler-$$.sql containing all the SELECT statements to search for the given string across all the _S and _R tables;<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"bash comments\"># finally, db-crawler-$$.sql will be executed with its output in db-crawler-$$.out;<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"bash keyword\">if<\/code> <code class=\"bash plain\">[[ $<\/code><code class=\"bash comments\"># -ne 2 ]]; then<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">echo<\/code> <code class=\"bash string\">\"Expected syntax: db-crawler.sh connect_info search_string\"<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">exit<\/code> <code class=\"bash plain\">1<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"bash keyword\">fi<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"bash plain\">connect_info=$1<\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"bash plain\">search_string=<\/code><code class=\"bash string\">\"$2\"<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"bash functions\">cat<\/code> <code class=\"bash plain\">- &lt;&lt;-eoq &gt; .\/$$.sql<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">define search_string = &amp;1<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">spool db-crawler_$$.sql<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">pagesize 0<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">linesize 1000<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">trims on<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">ALTER SESSION SET TIME_ZONE = <\/code><code class=\"bash string\">'0:0'<\/code><code class=\"bash plain\">;<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">alter session <\/code><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">NLS_DATE_FORMAT = <\/code><code class=\"bash string\">'DD\/MM\/YYYY HH24:MI:SS'<\/code><code class=\"bash plain\">;<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">select<\/code> <code class=\"bash string\">'select '<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">' from '<\/code> <code class=\"bash plain\">|| table_name || <\/code><code class=\"bash string\">' where regexp_like('<\/code> <code class=\"bash plain\">|| COLUMN_NAME || <\/code><code class=\"bash string\">', '<\/code><code class=\"bash string\">'&amp;search_string'<\/code><code class=\"bash string\">');'<\/code> <code class=\"bash plain\">from USER_TAB_COLS where (table_name like <\/code><code class=\"bash string\">'%\\_S'<\/code> <code class=\"bash plain\">escape <\/code><code class=\"bash string\">'\\' or table_name like '<\/code><code class=\"bash plain\">\\_%\\_R<\/code><code class=\"bash string\">' escape '<\/code><code class=\"bash plain\">\\') order by 1;<\/code><\/div>\n<div class=\"line number29 index28 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">spool off<\/code><\/div>\n<div class=\"line number30 index29 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">set<\/code> <code class=\"bash functions\">echo<\/code> <code class=\"bash plain\">on<\/code><\/div>\n<div class=\"line number31 index30 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">set<\/code> <code class=\"bash plain\">trims on<\/code><\/div>\n<div class=\"line number32 index31 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">@db-crawler_$$.sql<\/code><\/div>\n<div class=\"line number33 index32 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">spool off<\/code><\/div>\n<div class=\"line number34 index33 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">quit<\/code><\/div>\n<div class=\"line number35 index34 alt2\"><code class=\"bash plain\">eoq<\/code><\/div>\n<div class=\"line number36 index35 alt1\"><\/div>\n<div class=\"line number37 index36 alt2\"><code class=\"bash plain\">sqlplus ${connect_info} @$$.sql <\/code><code class=\"bash string\">\"${search_string}\"<\/code> <code class=\"bash plain\">| <\/code><code class=\"bash functions\">sed<\/code> <code class=\"bash plain\">-e <\/code><code class=\"bash string\">'0,\/EXIT\/d'<\/code> <code class=\"bash plain\">-e <\/code><code class=\"bash string\">'\/quit\/,$d'<\/code> <code class=\"bash plain\">&gt; db-crawler_$$.out<\/code><\/div>\n<div class=\"line number38 index37 alt1\"><\/div>\n<div class=\"line number39 index38 alt2\"><code class=\"bash comments\"># browse the result output and jump to the first match;<\/code><\/div>\n<div class=\"line number40 index39 alt1\"><code class=\"bash functions\">less<\/code> <code class=\"bash plain\">-S --pattern=<\/code><code class=\"bash string\">\"${search_string}\"<\/code> <code class=\"bash plain\">db-crawler_$$.out<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Let&#8217;s apply this wrapper to the use case below.<\/p>\n<h3>Looking for a given host name<\/h3>\n<p>Let&#8217;s suppose now that we want to move or clone a docbase from a host to another one, maybe running a different O\/S with some differences due to the implementation. After we applied to procedure, we suspect that the former host name is still referenced elsewhere in the new repository but we have no idea where. We changed it in the well-known places such as DM_SERVER_CONFIG and DM_MOUNT_POINT but there may still be references to it elsewhere. Clearly, we must search all the columns in all the tables of the repository&#8217;s schema for the given host name string, which is very easy now by using the wrapper:<\/p>\n<div>\n<div id=\"highlighter_194323\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash functions\">export<\/code> <code class=\"bash plain\">TWO_TASK=orcl<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">.<\/code><code class=\"bash plain\">\/db-crawler<\/code><code class=\"bash plain\">.sh dmtest<\/code><code class=\"bash plain\">\/dmtest<\/code> <code class=\"bash functions\">hostname<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Example of execution:<\/p>\n<div>\n<div id=\"highlighter_919219\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2\">9<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<div class=\"line number29 index28 alt2\">29<\/div>\n<div class=\"line number30 index29 alt1\">30<\/div>\n<div class=\"line number31 index30 alt2\">31<\/div>\n<div class=\"line number32 index31 alt1\">32<\/div>\n<div class=\"line number33 index32 alt2\">33<\/div>\n<div class=\"line number34 index33 alt1\">34<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">.<\/code><code class=\"bash plain\">\/db-crawler<\/code><code class=\"bash plain\">.sh dmtest<\/code><code class=\"bash plain\">\/dmtest<\/code> <code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash functions\">egrep<\/code> <code class=\"bash plain\">-B 1 <\/code><code class=\"bash string\">\"^docker\"<\/code> <code class=\"bash plain\">db-crawler_19815.out | <\/code><code class=\"bash functions\">less<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">HOST_NAME from DM_AUDITTRAIL_S where regexp_like(HOST_NAME, <\/code><code class=\"bash string\">'docker'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash plain\">--<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">HOST_NAME from DM_CLIENT_REGISTRATION_S where regexp_like(HOST_NAME, <\/code><code class=\"bash string\">'docker'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"bash plain\">--<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">HOST_NAME from DM_CLIENT_RIGHTS_S where regexp_like(HOST_NAME, <\/code><code class=\"bash string\">'docker'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"bash plain\">--<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">HOST_NAME from DM_MOUNT_POINT_S where regexp_like(HOST_NAME, <\/code><code class=\"bash string\">'docker'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"bash plain\">--<\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">OBJECT_NAME from DM_SYSOBJECT_S where regexp_like(OBJECT_NAME, <\/code><code class=\"bash string\">'docker'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"bash plain\">dockerACS1<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"bash plain\">--<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">R_HOST_NAME from DM_SERVER_CONFIG_S where regexp_like(R_HOST_NAME, <\/code><code class=\"bash string\">'docker'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"bash plain\">--<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">R_LOCK_MACHINE from DM_SYSOBJECT_S where regexp_like(R_LOCK_MACHINE, <\/code><code class=\"bash string\">'docker'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"bash plain\">--<\/code><\/div>\n<div class=\"line number29 index28 alt2\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">SET_CLIENT from DMR_CONTENT_S where regexp_like(SET_CLIENT, <\/code><code class=\"bash string\">'docker'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number30 index29 alt1\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number31 index30 alt2\"><code class=\"bash plain\">docker<\/code><\/div>\n<div class=\"line number32 index31 alt1\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number33 index32 alt2\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">WEB_SERVER_LOC from DM_SERVER_CONFIG_S where regexp_like(WEB_SERVER_LOC, <\/code><code class=\"bash string\">'docker'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number34 index33 alt1\"><code class=\"bash plain\">docker<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>We can see that the host name <em>docker<\/em> was referenced in the attributes DM_AUDITTRAIL.HOST_NAME, DM_CLIENT_REGISTRATION.HOST_NAME, DM_CLIENT_RIGHTS.HOST_NAME, DM_MOUNT_POINT.HOST_NAME, DM_SERVER_CONFIG.R_HOST_NAME but also in DM_SYSOBJECT.OBJECT_NAME and R_LOCK_MACHINE (there were likely locked documents in the source repository), DM_SERVER_CONFIG.WEB_SERVER_LOC, and DMR_CONTENT.SET_CLIENT. Some of those attributes such as DM_MOUNT_POINT.HOST_NAME could explain a potential issue in the new repository if not set adequately, while others such as DMR_CONTENT.SET_CLIENT should have no impact if carried over as-is into the new repository.<\/p>\n<h3>A note about DM_SYSOBJECT_S<\/h3>\n<p>Since DM_SYSOBJECT sits at the top of the type hierarchy of most persistent objects, it is linked by most repository objects and search results such as the ones below may be confusing:<\/p>\n<div>\n<div id=\"highlighter_318044\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2 highlighted\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2 highlighted\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1 highlighted\">8<\/div>\n<div class=\"line number9 index8 alt2 highlighted\">9<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2 highlighted\"><code class=\"bash plain\">$ .<\/code><code class=\"bash plain\">\/db-crawler<\/code><code class=\"bash plain\">.sh dmtest73<\/code><code class=\"bash plain\">\/dmtest73<\/code> <code class=\"bash plain\">dmtest<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number3 index2 alt2 highlighted\"><code class=\"bash plain\">SQL&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">OBJECT_NAME from DM_SYSOBJECT_S where regexp_like(OBJECT_NAME, <\/code><code class=\"bash string\">'dmtest'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">dmtest.cecACS1<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">dmtest73<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash plain\">dmtest73<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash plain\">dmtest73<\/code><\/div>\n<div class=\"line number8 index7 alt1 highlighted\"><code class=\"bash plain\">ContTransferConfig_dmtest73.dmtest73<\/code><\/div>\n<div class=\"line number9 index8 alt2 highlighted\"><code class=\"bash plain\">dfc_dmtest.cec_c0XP4a<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Clearly, due to their technical apparence, these rows may belong to objects deriving from DM_SYSOBJECT and belonging to different types; in order to determine which ones, further digging is necessary, e.g.:<\/p>\n<div>\n<div id=\"highlighter_648749\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2 highlighted\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2 highlighted\">9<\/div>\n<div class=\"line number10 index9 alt1 highlighted\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2 highlighted\"><code class=\"bash plain\">$ idql dmtest73 -Udmadmin -Pxxx <\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">1&gt; <\/code><code class=\"bash functions\">select<\/code> <code class=\"bash plain\">r_object_id, r_object_type, OBJECT_NAME from DM_SYSOBJECT where OBJECT_NAME like <\/code><code class=\"bash string\">'%dmtest%'<\/code><code class=\"bash plain\">);<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">2&gt; go<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash plain\">r_object_id\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 r_object_type\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 object_name\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">----------------\u00a0 --------------------------------\u00a0 ----------------------------------------<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash plain\">0c00c35080000104\u00a0 dm_cabinet\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dmtest73\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash plain\">3c00c35080000103\u00a0 dm_docbase_config\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dmtest73\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash plain\">3d00c35080000102\u00a0 dm_server_config\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dmtest73\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/code><\/div>\n<div class=\"line number9 index8 alt2 highlighted\"><code class=\"bash plain\">0800c35080000495\u00a0 dm_acs_config\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dmtest.cecACS1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/code><\/div>\n<div class=\"line number10 index9 alt1 highlighted\"><code class=\"bash plain\">0800c350800004ba\u00a0 dm_cont_transfer_config\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ContTransferConfig_dmtest73.dmtest73\u00a0\u00a0\u00a0 <\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"bash plain\">0800c35080000585\u00a0 dm_client_rights\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dfc_dmtest.cec_c0XP4a\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"bash plain\">(6 rows affected)<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>We can see for example that lines 8 and 9 from the crawler&#8217;s output correspond to repository&#8217;s types dm_cont_transfer_config and dm_client_rights. Thus, if something needs to be corrected in the repository, that&#8217;s where it should be done preferably in order to minimize the likelyhood of introducing corruptions.<\/p>\n<h3>Renaming a docbase\/changing its docbase id<\/h3>\n<p>Another use case, albeit a far fetched and fragile one, is when a repository must be renamed or its id changed. While the safe, traditional approach is to create a new docbase with the new name\/id and exporting\/importing the content, a more acrobatic approach would use the crawler to identify all the places in the underlying tables where those values are referenced, and change them.<br \/>\nClearly, in addition to the docbase&#8217;s schema, there are several locations in configuration files where such information is referenced too that should be edited. As most of those files are text files, the find command with a sed invocation can quickly do that in one pass. As to the schema&#8217;s tables, a search with the regexp &#8216;[0-9]{2}<em>docbase_id<\/em>[0-9a-f]{8} can identify all the ids to change. Something similar could be used for the repository&#8217;s name to change. Of course, a great deal of testing should be done, and maybe a call to OpenText to discuss this approach wouldn&#8217;t hurt either. Moreover, since they also distribute their own docbase renaming\/id changing tool, MigrationUtil (see the following blog articles <a href=\"https:\/\/www.dbi-services.com\/blog\/documentum-migrationutil-1-change-docbase-id\/\">Documentum \u2013 MigrationUtil \u2013 1 \u2013 Change Docbase ID<\/a> and <a href=\"https:\/\/www.dbi-services.com\/blog\/documentum-migrationutil-2-change-docbase-name\/\">Documentum \u2013 MigrationUtil \u2013 2 \u2013 Change Docbase Name<\/a>), it could be interesting to compare both techniques.<\/p>\n<h3>Conclusion<\/h3>\n<p>The db-crawler has a lot of potential to help troubleshoot puzzling problems, and identify inconsistencies and corruptions in repositories. As all the RDBMS have a dictionary, it is easy to adapt it to a different underlying one. It can even be used outside the context of Documentum repositories, directly in the context of databases.<br \/>\nAs a typical repository&#8217;s schema contains more than 2&#8217;000 tables (more if customized doctypes have been introduced), with possibly millions of documents (corresponding to one or more rows spread over several\u00a0 database tables), a possible enhancement is to speed the search up by parallelizing the execution of the generated SELECT statements, an easy to do task using a divide-and-conquer technique or a tool such as GNU Parallel.<br \/>\nCurrently, the tool is very basic as it addresses a simple need but it does not have to stay this way so feel free to add useful features and optimizations.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Working with Documentum is often a frustrating experience, and one of the main causes is the lack of meaningful error messages. Be it an encouragment to the administrator or developer to refer to the official knowledge base or a gap in the user-friendliness department, this results in the dreaded venture of investigating the origin of [&hellip;]<\/p>\n","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[525,59],"tags":[129,2611,985],"type_dbi":[],"class_list":["post-17820","post","type-post","status-publish","format-standard","hentry","category-enterprise-content-management","category-oracle","tag-documentum","tag-search-database","tag-sqlplus"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>db-crawler, a database search utility for Documentum - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"db-crawler, a database search utility for Documentum\" \/>\n<meta property=\"og:description\" content=\"Working with Documentum is often a frustrating experience, and one of the main causes is the lack of meaningful error messages. Be it an encouragment to the administrator or developer to refer to the official knowledge base or a gap in the user-friendliness department, this results in the dreaded venture of investigating the origin of [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-07-15T18:26:06+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-24T07:38:36+00:00\" \/>\n<meta name=\"author\" content=\"Middleware Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Middleware Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/\"},\"author\":{\"name\":\"Middleware Team\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1\"},\"headline\":\"db-crawler, a database search utility for Documentum\",\"datePublished\":\"2022-07-15T18:26:06+00:00\",\"dateModified\":\"2025-10-24T07:38:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/\"},\"wordCount\":2517,\"commentCount\":0,\"keywords\":[\"Documentum\",\"search database\",\"sqlplus\"],\"articleSection\":[\"Enterprise content management\",\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/\",\"name\":\"db-crawler, a database search utility for Documentum - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2022-07-15T18:26:06+00:00\",\"dateModified\":\"2025-10-24T07:38:36+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"db-crawler, a database search utility for Documentum\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1\",\"name\":\"Middleware Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"caption\":\"Middleware Team\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/middleware-team\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"db-crawler, a database search utility for Documentum - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/","og_locale":"en_US","og_type":"article","og_title":"db-crawler, a database search utility for Documentum","og_description":"Working with Documentum is often a frustrating experience, and one of the main causes is the lack of meaningful error messages. Be it an encouragment to the administrator or developer to refer to the official knowledge base or a gap in the user-friendliness department, this results in the dreaded venture of investigating the origin of [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/","og_site_name":"dbi Blog","article_published_time":"2022-07-15T18:26:06+00:00","article_modified_time":"2025-10-24T07:38:36+00:00","author":"Middleware Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Middleware Team","Est. reading time":"18 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/"},"author":{"name":"Middleware Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1"},"headline":"db-crawler, a database search utility for Documentum","datePublished":"2022-07-15T18:26:06+00:00","dateModified":"2025-10-24T07:38:36+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/"},"wordCount":2517,"commentCount":0,"keywords":["Documentum","search database","sqlplus"],"articleSection":["Enterprise content management","Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/","url":"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/","name":"db-crawler, a database search utility for Documentum - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2022-07-15T18:26:06+00:00","dateModified":"2025-10-24T07:38:36+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/db-crawler-a-database-search-utility-for-documentum\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"db-crawler, a database search utility for Documentum"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1","name":"Middleware Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","caption":"Middleware Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/middleware-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/17820","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=17820"}],"version-history":[{"count":13,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/17820\/revisions"}],"predecessor-version":[{"id":19632,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/17820\/revisions\/19632"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=17820"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=17820"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=17820"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=17820"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}