This commit is contained in:
2019-02-06 00:49:12 +03:00
commit 8dbb1bb605
4796 changed files with 506072 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
<chapter id="ljp.prog-guide.database">
<title>Database</title>
<itemizedlist>
<title>Database</title>
<listitem><simpara>
Check your db index usage... mysql's <function>EXPLAIN</function> is your friend.
</simpara></listitem>
<listitem><simpara>
Between <function>LOCK TABLES</function> &amp; <function>UNLOCK TABLES</function>,
never call a subroutine.
</simpara></listitem>
<listitem><simpara>
Check the DB error code after an SQL statement. Just because it worked once and the SQL is correct,
that doesn't mean the table might not go corrupt, a disk might fill up, or index space within the
file might not fill up. Errors happen. Deal with them.
</simpara></listitem>
<listitem><simpara>
Preferred way to break up a long SQL query:
<programlisting>
$sth = $dbh->prepare("SELECT cola, colb, colc, cold FROM foo ".
"WHERE colb&lt;&gt;cola AND colc=22");
</programlisting>
</simpara></listitem>
<listitem><para>
Note on variable naming:
<informaltable>
<tgroup cols="2">
<tbody>
<row>
<entry><varname>$sth</varname></entry>
<entry>statement handle</entry>
</row>
<row>
<entry><varname>$dbh</varname></entry>
<entry>one database handle (usually the master)</entry>
</row>
<row>
<entry><varname>$dbs</varname></entry>
<entry>set of database handles [master(, slave)]</entry>
</row>
<row>
<entry><varname>$dbr</varname></entry>
<entry>read-only slave db handle (used for selects)</entry>
</row>
<row>
<entry><varname>$dbarg</varname></entry>
<entry>argument that can take a <varname>$dbh/r</varname> or <varname>$dbs</varname></entry>
</row>
<row>
<entry><varname>$remote</varname></entry>
<entry>hashref of remote user, based on cookies. will contain 'userid' and 'user' params,
unless faster get_remote_noauth was used, in which case only 'user' will be present.</entry>
</row>
<row>
<entry><varname>$u</varname></entry>
<entry>a user 'object' (a hashref)</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para></listitem>
<listitem><simpara>
Call for database handles as you need them, instead of predeclaring <varname>$db<replaceable>x</replaceable></varname> variables.
Use <function>LJ::get_db_writer</function> to get a writable handle to the database, and
<function>LJ::get_db_reader</function> to get a read-only handle.
</simpara></listitem>
</itemizedlist>
</chapter>
<!--
Local Variables:
mode:sgml
sgml-parent-document: ("index.xml" "part" "chapter")
End:
-->

View File

@@ -0,0 +1,44 @@
<chapter id="ljp.prog-guide.general">
<title>General</title>
<itemizedlist>
<title>General</title>
<listitem><para>
BML pages shouldn't interface with the database much. <footnote><para>See <xref linkend="ljp.dbschema.index" /></para></footnote>.
</para></listitem>
<listitem><para>
Always use the <function>LJ::</function> functions that take an explicit database handle. Don't use the old <function>main::</function> functions that use the global $dbh.
</para></listitem>
<listitem><para>
All files should have <sgmltag>&lt;LJDEP&gt;</sgmltag> edge dependency somewhere, usually at the bottom.
</para></listitem>
<listitem><para>
Using userids (integers) for things is better than using users (strings), except in URL arguments, where pretty is more important than speed.
</para></listitem>
<listitem><para>
In BML page, use BML blocks defined in global.look: LJUSER, P, H1, H2, STANDOUT, HR, etc...
</para></listitem>
<listitem><para>
All HTML should be XHTML compliant.:
<itemizedlist>
<listitem><para>
Lower case, <acronym>XML</acronym> compliant tags: <informalexample><para><sgmltag>&lt;br /&gt;</sgmltag> instead of <sgmltag>&lt;BR&gt;</sgmltag></para></informalexample>
</para></listitem>
<listitem><para>
Quotes around attributes &lt;span class="test"&gt;
</para></listitem>
<listitem><para>
No bare &amp; chars ... always escape them: &amp;amp; and &lt;a href="foo.bml?a=1&amp;amp;b=2"&gt;...&lt;/a&gt;
</para></listitem>
</itemizedlist>
</para></listitem>
<listitem><para>
Use of multiple files to do one function is deprecated. There should no longer be "foo.bml" and "foo_do.bml" like there used to. That's ugly.
</para></listitem>
<listitem><para>
Tab is a formatting command, not a character <footnote><para>See: <ulink url="http://www.jwz.org/doc/tabs-vs-spaces.html" /></para></footnote>. There should be spaces in the files, not tab characters.
</para></listitem>
<listitem><para>
All subs in a package need LJFUNC documentation. All tables in the database need schema documentation. All files need LJDEP documentation.
</para></listitem>
</itemizedlist>
</chapter>

View File

@@ -0,0 +1,14 @@
<part id="ljp.prog-guide" status="prelim">
<title>Programming Guidelines</title>
<partintro>
<para>
Content that goes into CVS needs to follow these guidelines:
</para>
</partintro>
&ljp.prog-guide.general;
&ljp.prog-guide.security;
&ljp.prog-guide.database;
&ljp.prog-guide.performance;
&ljp.prog-guide.perl_style;
&ljp.prog-guide.patches;
</part>

View File

@@ -0,0 +1,12 @@
<chapter id="ljp.prog-guide.patches">
<title>Patches</title>
<itemizedlist>
<title>Patches</title>
<listitem><para>
All patches sent in should be in diff -u format.
</para></listitem>
<listitem><para>
Don't send in patches that comment out old code. If we want the old code, we'll go get it from CVS.. that's what it's for.
</para></listitem>
</itemizedlist>
</chapter>

View File

@@ -0,0 +1,15 @@
<chapter id="ljp.prog-guide.performance">
<title>Performance &amp; Scalability</title>
<itemizedlist>
<title>Performance &amp; Scalability</title>
<listitem><para>
Large chunks of code should be preloaded in libraries. Code in BML pages is re-evaled on every request, so it should be small. If you need a lot of code, put it in a library and load it in cgi-bin/lj-bml-(init|local).pl
</para></listitem>
<listitem><para>
Don't write temporary files to disk... all LJ code should be able to run on a cluster of web servers with no disk-based session persistence.
</para></listitem>
<listitem><para>
If you're calling a function with a <literal>$dbarg</literal> parameter and you have both a <literal>$dbs</literal> and <literal>$dbh</literal> available, call the function with your <literal>$dbs</literal> ... otherwise the function and all its callees can't ever use the slave databases.
</para></listitem>
</itemizedlist>
</chapter>

View File

@@ -0,0 +1,15 @@
<chapter id="ljp.prog-guide.perl">
<title>Perl Style</title>
<itemizedlist>
<title>Perl Style</title>
<listitem><para>
<computeroutput>foo()</computeroutput> looks prettier than <computeroutput>&amp;foo()</computeroutput>. Let perl 4 die.
</para></listitem>
<listitem><para>
Lines longer than 80 characters are okay, but not great.
</para></listitem>
<listitem><para>
If you're in package LJ and calling an LJ::* API function, go ahead and type the extra four characters (LJ::) even if they're not necessary... being explicit is nice for the reader.
</para></listitem>
</itemizedlist>
</chapter>

View File

@@ -0,0 +1,21 @@
<chapter id="ljp.prog-guide.security">
<title>Security</title>
<itemizedlist>
<title>Security</title>
<listitem>
<para>
All GET/POST form values go into %FORM into BML, but check <function>LJ::did_post()</function> on critical actions. GET requests can be easily spoofed, or hidden in images, etc.
</para>
</listitem>
<listitem>
<para>
Never read in arbitrary amounts of input
</para>
</listitem>
<listitem>
<para>
Never use unsanitized data in a command or SQL
</para>
</listitem>
</itemizedlist>
</chapter>