<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: join code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sat, 17 May 2008 13:05:10 GMT</pubDate>
    <description>DZone Snippets: join code</description>
    <item>
      <title>DELETE - SQL</title>
      <link>http://snippets.dzone.com/posts/show/4498</link>
      <description>// description of your code here&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;DELETE ... &lt;br /&gt;    [ FROM ... ] &lt;br /&gt;    [ ... JOIN ... ] &lt;br /&gt;    [ WHERE ... ] &lt;br /&gt;&lt;br /&gt;// FULL Syntax follows:&lt;br /&gt;DELETE [ FROM ] &lt;br /&gt;    {&lt;br /&gt;       [ database. ] [ owner. ] table_name &lt;br /&gt;         [&lt;br /&gt;           WITH (  INDEX ( Index_1,   [ index_2,  ...,  n ] ) &lt;br /&gt;                      | FASTFIRSTROW &lt;br /&gt;                      | HOLDLOCK &lt;br /&gt;                      | PAGLOCK &lt;br /&gt;                      | READCOMMITTED &lt;br /&gt;                      | REPEATABLEREAD &lt;br /&gt;                      | ROWLOCK &lt;br /&gt;                      | SERIALIZABLE &lt;br /&gt;                      | TABLOCK &lt;br /&gt;                      | TABLOCKX &lt;br /&gt;                      [   ...   n  |  ...,  n ] &lt;br /&gt;                     )&lt;br /&gt;       ]&lt;br /&gt;     |&lt;br /&gt;       OPENQUERY( server, 'query' ) &lt;br /&gt;     |&lt;br /&gt;       OPENROWSET( 'provider_name', &lt;br /&gt;                                 { 'datasource';'user_id';'password',  |  'provider_string', }&lt;br /&gt;                                 { [ catalog. ] [ schema. ] object  |  'query' }&lt;br /&gt;                               ) &lt;br /&gt;     |&lt;br /&gt;       view_name &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [&lt;br /&gt;      FROM &lt;br /&gt;      {&lt;br /&gt;          derived_table &lt;br /&gt;            [ [ AS ] table_alias ]&lt;br /&gt;            [ ( column_alias_1,   [ column_alias_2,   ...,  n ]  )  ]&lt;br /&gt;        |&lt;br /&gt;          CONTAINSTABLE ( table, column  |  *, 'search_conditions' ) &lt;br /&gt;            [ [ AS ] table_alias ]&lt;br /&gt;        |&lt;br /&gt;          FREETEXTTABLE ( table, column  |  *, 'free_text_string' ) &lt;br /&gt;            [ [ AS ] table_alias ]&lt;br /&gt;        |&lt;br /&gt;          table_name [ [ AS ] table_alias ]&lt;br /&gt;            [&lt;br /&gt;               WITH (  INDEX ( Index_1,   [ index_2,   ...,  n ]  ) &lt;br /&gt;                          | FASTFIRSTROW &lt;br /&gt;                          | HOLDLOCK &lt;br /&gt;                          | NOLOCK &lt;br /&gt;                          | PAGLOCK &lt;br /&gt;                          | READCOMMITTED &lt;br /&gt;                          | READPAST &lt;br /&gt;                          | READUNCOMMITTED &lt;br /&gt;                          | REPEATABLEREAD &lt;br /&gt;                          | ROWLOCK &lt;br /&gt;                          | SERIALIZABLE &lt;br /&gt;                          | TABLOCK &lt;br /&gt;                          | TABLOCKX &lt;br /&gt;                          | UPDLOCK &lt;br /&gt;                          [ ...   n  |  ...,  n ] &lt;br /&gt;                         )&lt;br /&gt;            ]&lt;br /&gt;        |&lt;br /&gt;          view_name [ [ AS ] table_alias ]&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      [&lt;br /&gt;          INNER JOIN  |  LEFT [ OUTER ] JOIN  |  RIGHT [ OUTER ] JOIN &lt;br /&gt;            {&lt;br /&gt;               derived_table [ ON search_conditions ]&lt;br /&gt;             |&lt;br /&gt;               OPENQUERY( server, 'query' ) [ ON search_conditions ]&lt;br /&gt;             |&lt;br /&gt;               OPENROWSET&lt;br /&gt;                               ( 'provider_name', &lt;br /&gt;                                 { 'datasource';'user_id';'password',  |  'provider_string', }&lt;br /&gt;                                 { [ catalog. ] [ schema. ] object  |  'query' }&lt;br /&gt;                               ) [ ON search_conditions ]&lt;br /&gt;             | &lt;br /&gt;               table_name [ ON search_conditions ]&lt;br /&gt;             | &lt;br /&gt;               view_name [ ON search_conditions ]&lt;br /&gt;            }&lt;br /&gt;            [   ...,  n ]&lt;br /&gt;          |&lt;br /&gt;          CROSS JOIN  |  FULL [ OUTER ] JOIN &lt;br /&gt;            {&lt;br /&gt;               derived_table &lt;br /&gt;             | &lt;br /&gt;               OPENQUERY( server, 'query' ) &lt;br /&gt;             |&lt;br /&gt;               OPENROWSET&lt;br /&gt;                               ( 'provider_name', &lt;br /&gt;                                 { 'datasource';'user_id';'password',  |  'provider_string', }&lt;br /&gt;                                 { [ catalog. ] [ schema. ] object  |  'query' }&lt;br /&gt;                               ) &lt;br /&gt;             | &lt;br /&gt;               table_name &lt;br /&gt;             | &lt;br /&gt;               view_name &lt;br /&gt;            }&lt;br /&gt;            [   ...,  n ]&lt;br /&gt;       ]&lt;br /&gt;   ] &lt;br /&gt;&lt;br /&gt;   [&lt;br /&gt;      {&lt;br /&gt;         WHERE search_conditions &lt;br /&gt;       |&lt;br /&gt;         WHERE CURRENT OF [ GLOBAL ] cursor_name &lt;br /&gt;       |&lt;br /&gt;         WHERE CURRENT OF cursor_variable_name &lt;br /&gt;      }&lt;br /&gt;         [&lt;br /&gt;           OPTION (  FAST number_rows &lt;br /&gt;                          | FORCE ORDER &lt;br /&gt;                          | HASH GROUP &lt;br /&gt;                          | ORDER GROUP &lt;br /&gt;                          | HASH JOIN &lt;br /&gt;                          | LOOP JOIN &lt;br /&gt;                          | MERGE JOIN &lt;br /&gt;                          | KEEP PLAN &lt;br /&gt;                          | MAXDOP &lt;br /&gt;                          | ROBUST PLAN &lt;br /&gt;                          | CONCAT UNION &lt;br /&gt;                          | HASH UNION &lt;br /&gt;                          | MERGE UNION &lt;br /&gt;                          [   ...,  n ]&lt;br /&gt;                        )&lt;br /&gt;         ]&lt;br /&gt;   ]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;//Full explanation follows:&lt;br /&gt;&lt;br /&gt;KEYWORDS	Keywords are denoted with upper case letters. Obey the spelling.&lt;br /&gt;&lt;br /&gt;variables	All user-supplied variables are denoted with lower case letters.&lt;br /&gt;&lt;br /&gt;...,   n	Signifies that there can be more than one value in a comma delimited list. Note that the dots and n are not part of the code and must not appear in the SQL query.&lt;br /&gt;&lt;br /&gt;...   n	Signifies that there can be more than one value in a blank space delimited list. Note that the dots and n are not part of the code and must not appear in the SQL query.&lt;br /&gt;&lt;br /&gt;{  } 	Signifies that all, or some portion, of the code elements between the braces are required elements and must appear in the SQL query. Note that these braces are not part of the code and must not appear in the SQL query.&lt;br /&gt;&lt;br /&gt;[  ] 	Signifies that the code elements between the square brackets can optionally appear in the SQL query, but are not required. Note that these brackets are not part of the code and must not appear in the SQL query.&lt;br /&gt;&lt;br /&gt;|	The or symbol signifies that you may use only one of the code elements or values from the possible choices. Note that the or symbol is not part of the code and must not appear in the SQL query.</description>
      <pubDate>Thu, 06 Sep 2007 10:30:33 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4498</guid>
      <author>dubby (Dave)</author>
    </item>
    <item>
      <title>fractionfiles.py</title>
      <link>http://snippets.dzone.com/posts/show/3541</link>
      <description>// Splits a file into smaller ones, and joins them together.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;&lt;br /&gt;"""Splits and joins files. Helpful when media can't fit a file.&lt;br /&gt;Be prepared for a lot of output files!"""&lt;br /&gt;&lt;br /&gt;__author__="Andrew Pennebaker (andrew.pennebaker@gmail.com)"&lt;br /&gt;__date__="6 Jan 3006 - 12 Feb 2006"&lt;br /&gt;__copyright__="Copyright 2006 Andrew Pennebaker"&lt;br /&gt;__license__="GPL"&lt;br /&gt;__version__="0.3"&lt;br /&gt;__URL__="http://snippets.dzone.com/posts/show/3541"&lt;br /&gt;&lt;br /&gt;import sys, os&lt;br /&gt;from getopt import getopt&lt;br /&gt;&lt;br /&gt;SPLIT_MODE="SPLIT"&lt;br /&gt;JOIN_MODE="JOIN"&lt;br /&gt;&lt;br /&gt;def splitFile(name, length, number):&lt;br /&gt;	if length==None:&lt;br /&gt;		infile=open(name, "rb")&lt;br /&gt;		size=0&lt;br /&gt;		while infile.read(1)!="":&lt;br /&gt;			size+=1&lt;br /&gt;&lt;br /&gt;		infile.close()&lt;br /&gt;&lt;br /&gt;		maxlength=size/number&lt;br /&gt;		if number*maxlength&lt;size:&lt;br /&gt;			maxlength+=1&lt;br /&gt;&lt;br /&gt;	else:&lt;br /&gt;		if length&lt;1:&lt;br /&gt;			raise Exception&lt;br /&gt;&lt;br /&gt;	infile=None&lt;br /&gt;	try:&lt;br /&gt;		infile=open(name, "rb")&lt;br /&gt;	except Exception, e:&lt;br /&gt;		raise e&lt;br /&gt;&lt;br /&gt;	i=0&lt;br /&gt;	j=0&lt;br /&gt;	c=infile.read(1)&lt;br /&gt;	while c!="":&lt;br /&gt;		outfile=None&lt;br /&gt;		try:&lt;br /&gt;			outfile=open("%s.%d" % (name, j), "wb")&lt;br /&gt;		except Exception, e:&lt;br /&gt;			raise e&lt;br /&gt;&lt;br /&gt;		while i&lt;length and c!="":&lt;br /&gt;			outfile.write(c)&lt;br /&gt;			c=infile.read(1)&lt;br /&gt;			i+=1&lt;br /&gt;&lt;br /&gt;		outfile.close()&lt;br /&gt;		i=0&lt;br /&gt;		j+=1&lt;br /&gt;&lt;br /&gt;	infile.close()&lt;br /&gt;&lt;br /&gt;def joinFiles(filenames):&lt;br /&gt;	if len(filenames)&lt;1:&lt;br /&gt;		raise Exception&lt;br /&gt;&lt;br /&gt;	filenames.sort() # ...0 must be first&lt;br /&gt;&lt;br /&gt;	origFilename=filenames[0][0:-2] # take ".0" off the first file name&lt;br /&gt;	origFile=None&lt;br /&gt;&lt;br /&gt;	try:&lt;br /&gt;		origFile=open(origFilename, "wb")&lt;br /&gt;	except Exception, e:&lt;br /&gt;		raise e&lt;br /&gt;&lt;br /&gt;	c="&amp;" # dummy&lt;br /&gt;&lt;br /&gt;	for filename in filenames:&lt;br /&gt;		smallFile=None&lt;br /&gt;		try:&lt;br /&gt;			smallFile=open(filename, "rb")&lt;br /&gt;		except Exception, e:&lt;br /&gt;			raise e&lt;br /&gt;&lt;br /&gt;		c=smallFile.read(1)&lt;br /&gt;		while c!="":&lt;br /&gt;			origFile.write(c)&lt;br /&gt;			c=smallFile.read(1)&lt;br /&gt;&lt;br /&gt;		smallFile.close()&lt;br /&gt;&lt;br /&gt;	origFile.close()&lt;br /&gt;&lt;br /&gt;def usage():&lt;br /&gt;	print "Usage: %s [options] [files]" % (sys.argv[0])&lt;br /&gt;	print "\n--split &lt;file1 file 2 file 3...&gt;"&lt;br /&gt;	print "--join &lt;dir1 dir2 dir3 ...&gt;"&lt;br /&gt;	print "--maxlength &lt;bytes&gt;"&lt;br /&gt;	print "--maxfiles &lt;number&gt;"&lt;br /&gt;	print "--help (usage)"&lt;br /&gt;&lt;br /&gt;	sys.exit()&lt;br /&gt;&lt;br /&gt;def main():&lt;br /&gt;	global SPLIT_MODE&lt;br /&gt;	global JOIN_MODE&lt;br /&gt;&lt;br /&gt;	mode=SPLIT_MODE&lt;br /&gt;	filenames=[]&lt;br /&gt;	maxlength=1024&lt;br /&gt;	maxfiles=None&lt;br /&gt;&lt;br /&gt;	systemArgs=sys.argv[1:] # ignore program name&lt;br /&gt;&lt;br /&gt;	optlist=[]&lt;br /&gt;	args=[]&lt;br /&gt;&lt;br /&gt;	try:&lt;br /&gt;		optlist, args=getopt(systemArgs, None, ["split", "join", "maxlength=", "maxfiles=", "help"])&lt;br /&gt;	except Exception, e:&lt;br /&gt;		usage()&lt;br /&gt;&lt;br /&gt;	if len(optlist)&lt;1 or len(args)&lt;1:&lt;br /&gt;		usage()&lt;br /&gt;&lt;br /&gt;	for option, value in optlist:&lt;br /&gt;		if option=="--help":&lt;br /&gt;			usage()&lt;br /&gt;&lt;br /&gt;		elif option=="--split":&lt;br /&gt;			mode=SPLIT_MODE&lt;br /&gt;		elif option=="--join":&lt;br /&gt;			mode=JOIN_MODE&lt;br /&gt;		elif option=="--maxlength":&lt;br /&gt;			try:&lt;br /&gt;				maxlength=int(value)&lt;br /&gt;				if maxlength&lt;1:&lt;br /&gt;					raise Exception&lt;br /&gt;				maxfiles=None&lt;br /&gt;			except Exception, e:&lt;br /&gt;				raise "Length must be at least one"&lt;br /&gt;		elif option=="--maxfiles":&lt;br /&gt;			try:&lt;br /&gt;				maxfiles=int(value)&lt;br /&gt;				if maxfiles&lt;1:&lt;br /&gt;					raise Exception&lt;br /&gt;				maxlength=None&lt;br /&gt;			except Exception, e:&lt;br /&gt;				raise "Number must be at least one"&lt;br /&gt;&lt;br /&gt;	filenames=args&lt;br /&gt;&lt;br /&gt;	if mode==SPLIT_MODE:&lt;br /&gt;		for filename in filenames:&lt;br /&gt;			try:&lt;br /&gt;				splitFile(filename, maxlength, maxfiles)&lt;br /&gt;			except Exception, e:&lt;br /&gt;				raise e&lt;br /&gt;&lt;br /&gt;	elif mode==JOIN_MODE:&lt;br /&gt;		for directory in filenames:&lt;br /&gt;			files=["%s%s%s" % (directory, os.sep, file) for file in os.listdir(directory)]&lt;br /&gt;&lt;br /&gt;			try:&lt;br /&gt;				joinFiles(files)&lt;br /&gt;			except Exception, e:&lt;br /&gt;				raise e&lt;br /&gt;&lt;br /&gt;if __name__=="__main__":&lt;br /&gt;	main()&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 19 Feb 2007 01:01:02 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3541</guid>
      <author>mcandre (Andrew Pennebaker)</author>
    </item>
    <item>
      <title>Files Joiner/Unjoiner //Pascal class</title>
      <link>http://snippets.dzone.com/posts/show/2197</link>
      <description>This is just a snippet since I didn't added some units that can be replaced without major efforts:&lt;br /&gt;- PathParser.pas: parses paths shortcuts (it's on my bigbold snippets, search on my tags)&lt;br /&gt;- Stack.pas: implements a simple stack (it's on my bigbold snippets, search on my tags)&lt;br /&gt;- ZlibEx.pas: used to compress/decompress the file contents (My ZlibEx is a modified version of this file: http://www.dellapasqua.com/delphizlib)&lt;br /&gt;- MD5.pas: used to calculate the file hash and check consistency when unjoining files&lt;br /&gt;- SysUtils2: Some idiot functions =b&lt;br /&gt;&lt;br /&gt;I used this in a personalized installer that I've made in my first job =b&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;unit FileJoiner;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, SysUtils2, Classes, MD5, ZlibEx, PathParser, Stack;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TOverwriteMode = ( omNo, omAskUser, omIfNewer, omIfOlder, omIfDiff );&lt;br /&gt;  TOverwriteAction = ( oaOverwriteAll, oaNoOverwriteAll, oaYes, oaNo );&lt;br /&gt;&lt;br /&gt;  TFileHeader = record&lt;br /&gt;    MD5Hash: TDigestStr;&lt;br /&gt;    ModificationDate: TDateTime;&lt;br /&gt;    Attributes: LongWord;&lt;br /&gt;    Overwrite: TOverwriteMode;&lt;br /&gt;    Size: Int64;&lt;br /&gt;    MustKeep: Boolean;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TFileJoinerItem = class&lt;br /&gt;  public&lt;br /&gt;    Source, Destiny: string;&lt;br /&gt;    MustKeep, Recurse: Boolean;&lt;br /&gt;    Overwrite: TOverwriteMode;&lt;br /&gt;&lt;br /&gt;    constructor Create( const FromPath, ToPath: string; const OverwriteMode: TOverwriteMode = omIfNewer; const Recursive: Boolean = True; const MustKeepFile: Boolean = False ); overload;&lt;br /&gt;    function Assign( Item: TFileJoinerItem ): TFileJoinerItem;&lt;br /&gt;&lt;br /&gt;    procedure Save( const Stream: TStream );&lt;br /&gt;    procedure Load( const Stream: TStream );&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TCustomFileJoiner = class;&lt;br /&gt;&lt;br /&gt;  TFileJoinerFilesCallback = procedure( Sender: TCustomFileJoiner; Item: TFileJoinerItem ) of object;&lt;br /&gt;  TFileJoinerNotifyEvent = procedure( Sender: TCustomFileJoiner ) of object;&lt;br /&gt;  TFileJoinerFileExists = procedure( Sender: TCustomFileJoiner; var CanOverwrite: TOverwriteAction ) of object;&lt;br /&gt;&lt;br /&gt;  TJoinerStatus = ( jsIdle, jsJoining, jsUnjoining );&lt;br /&gt;&lt;br /&gt;  TCustomFileJoiner = class&lt;br /&gt;  private&lt;br /&gt;    FStream: TStream;&lt;br /&gt;    FCurFile, FTotalFiles: LongWord;&lt;br /&gt;    FCurSize, FTotalSize, FCurPosition, FCurWrittenBytes: Int64;&lt;br /&gt;    FCurFilename: string;&lt;br /&gt;    FCurFileInfo: TFileHeader;&lt;br /&gt;    FOnFileExists: TFileJoinerFileExists;&lt;br /&gt;    FOnWorkEnd, FOnWorkBegin, FOnWork, FOnProcessFile: TFileJoinerNotifyEvent;&lt;br /&gt;&lt;br /&gt;    procedure ProgressNotifier( Sender: TObject );&lt;br /&gt;&lt;br /&gt;  public&lt;br /&gt;    //properties&lt;br /&gt;    property CurFilename: string read FCurFilename;&lt;br /&gt;    property CurFileInfo: TFileHeader read FCurFileInfo;&lt;br /&gt;    property CurFilePosition: Int64 read FCurPosition;&lt;br /&gt;    property CurWrittenBytes: Int64 read FCurWrittenBytes;&lt;br /&gt;    property CurSize: Int64 read FCurSize;&lt;br /&gt;    property CurFile: LongWord read FCurFile;&lt;br /&gt;&lt;br /&gt;    property TotalSize: Int64 read FTotalSize;&lt;br /&gt;    property TotalFiles: LongWord read FTotalFiles;&lt;br /&gt;&lt;br /&gt;    //events&lt;br /&gt;    property OnWorkBegin: TFileJoinerNotifyEvent read FOnWorkBegin write FOnWorkBegin;&lt;br /&gt;    property OnWork: TFileJoinerNotifyEvent read FOnWork write FOnWork;&lt;br /&gt;    property OnWorkEnd: TFileJoinerNotifyEvent read FOnWorkEnd write FOnWorkEnd;&lt;br /&gt;    property OnProcessFile: TFileJoinerNotifyEvent read FOnProcessFile write FOnProcessFile;&lt;br /&gt;    property OnFileExists: TFileJoinerFileExists read FOnFileExists write FOnFileExists;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TFileJoiner = class( TCustomFileJoiner )&lt;br /&gt;  private&lt;br /&gt;    FPaths: TList;&lt;br /&gt;&lt;br /&gt;    function GetItem(const Index: Integer): TFileJoinerItem;&lt;br /&gt;    function GetCount: Integer;&lt;br /&gt;    procedure StreamFile( Sender: TCustomFileJoiner; Item: TFileJoinerItem );&lt;br /&gt;    procedure Compress( Input: TStream );&lt;br /&gt;&lt;br /&gt;  public&lt;br /&gt;    constructor Create;&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;&lt;br /&gt;    procedure Join( const Filename: string ); overload;&lt;br /&gt;    procedure Join( const Stream: TStream ); overload;&lt;br /&gt;&lt;br /&gt;    procedure SaveList( const Filename: string ); overload;&lt;br /&gt;    procedure SaveList( Stream: TStream ); overload;&lt;br /&gt;    procedure LoadList( const Filename: string ); overload;&lt;br /&gt;    procedure LoadList( Stream: TStream ); overload;&lt;br /&gt;&lt;br /&gt;    procedure CountFiles;&lt;br /&gt;&lt;br /&gt;    function Add( const FromPath, ToPath: string; const OverwriteMode: TOverwriteMode = omIfNewer; const Recursive: Boolean = False; const MustKeep: Boolean = False ): Integer;&lt;br /&gt;    procedure Clear;&lt;br /&gt;    procedure Remove( const Index: Integer );&lt;br /&gt;    procedure ListFiles( const Callback: TFileJoinerFilesCallback );&lt;br /&gt;&lt;br /&gt;    property Count: Integer read GetCount;&lt;br /&gt;    property Items[ const Index: Integer ]: TFileJoinerItem read GetItem; default;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TFileUnjoiner = class( TCustomFileJoiner )&lt;br /&gt;  private&lt;br /&gt;    FDataBegin: Int64;&lt;br /&gt;    procedure Decompress( Output: TStream );&lt;br /&gt;&lt;br /&gt;  public&lt;br /&gt;    procedure Assign( const Filename: string ); overload;&lt;br /&gt;    procedure Assign( Stream: TStream ); overload;&lt;br /&gt;    procedure UnJoin;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TCustomFileJoiner }&lt;br /&gt;&lt;br /&gt;procedure TCustomFileJoiner.ProgressNotifier(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;  if Assigned( FOnWork ) then&lt;br /&gt;    with TStream( Sender ) do&lt;br /&gt;    begin&lt;br /&gt;      FCurWrittenBytes := Position - FCurPosition;&lt;br /&gt;      FCurPosition := Position;&lt;br /&gt;      FOnWork( Self );&lt;br /&gt;    end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TFileJoiner }&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.Join( const Filename: string );&lt;br /&gt;begin&lt;br /&gt;  FStream := TFileStream.Create( Filename, fmCreate );&lt;br /&gt;  try&lt;br /&gt;    Join( FStream );&lt;br /&gt;  finally&lt;br /&gt;    FStream.Free;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.Join( const Stream: TStream );&lt;br /&gt;var&lt;br /&gt;  Pos: array[0..1] of Int64;&lt;br /&gt;begin&lt;br /&gt;  FStream := Stream;&lt;br /&gt;  if Assigned( FOnWorkBegin ) then&lt;br /&gt;    FOnWorkBegin( Self );&lt;br /&gt;&lt;br /&gt;  FCurFile := 0;&lt;br /&gt;  FCurSize := 0;&lt;br /&gt;&lt;br /&gt;  //record position to get back later and reserve space on the file to record the "totals"&lt;br /&gt;  Pos[0] := FStream.Position;&lt;br /&gt;  FStream.Seek( SizeOf( FCurFile ) + SizeOf( FCurSize ), soCurrent );&lt;br /&gt;&lt;br /&gt;  //write files&lt;br /&gt;  ListFiles( StreamFile );&lt;br /&gt;&lt;br /&gt;  //write the totals and get back&lt;br /&gt;  Pos[1] := Stream.Position;&lt;br /&gt;  FStream.Position := Pos[0];&lt;br /&gt;  FStream.Write( FCurFile, SizeOf( FCurFile ) );&lt;br /&gt;  FStream.Write( FCurSize, SizeOf( FCurSize ) );&lt;br /&gt;  FStream.Position := Pos[1];&lt;br /&gt;&lt;br /&gt;  //job done&lt;br /&gt;  if Assigned( FOnWorkEnd ) then&lt;br /&gt;    FOnWorkEnd( Self );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.StreamFile( Sender: TCustomFileJoiner; Item: TFileJoinerItem );&lt;br /&gt;var&lt;br /&gt;  InputFile: TFileStream;&lt;br /&gt;  Pos: array[0..1] of Int64;&lt;br /&gt;begin&lt;br /&gt;  try&lt;br /&gt;    Inc( FCurFile );&lt;br /&gt;    FCurPosition := 0;&lt;br /&gt;    FCurFilename := Item.Source;&lt;br /&gt;&lt;br /&gt;    FCurFileInfo.MD5Hash := FileMD5Digest( Item.Source );&lt;br /&gt;    FCurFileInfo.ModificationDate := FileDateToDateTime( FileAge( Item.Source ) );&lt;br /&gt;    FCurFileInfo.Attributes := FileGetAttr( Item.Source );&lt;br /&gt;    FCurFileInfo.Overwrite := Item.Overwrite;&lt;br /&gt;&lt;br /&gt;    InputFile := TFileStream.Create( Item.Source, fmOpenRead or fmShareDenyWrite );&lt;br /&gt;    try&lt;br /&gt;      FCurFileInfo.Size := InputFile.Size;&lt;br /&gt;      if Assigned( FOnProcessFile ) then&lt;br /&gt;        FOnProcessFile( Self );&lt;br /&gt;&lt;br /&gt;      Pos[0] := FStream.Position;&lt;br /&gt;      //reserve space for the file header and EOF position&lt;br /&gt;      FStream.Seek( SizeOf( FCurFileInfo ) + SizeOf( Pos[0] ), soCurrent );&lt;br /&gt;      StringWrite( FStream, Item.Destiny );&lt;br /&gt;&lt;br /&gt;      Compress( InputFile );&lt;br /&gt;&lt;br /&gt;      //update the header and get back&lt;br /&gt;      Pos[1] := FStream.Position;&lt;br /&gt;      FStream.Position := Pos[0];&lt;br /&gt;      FStream.Write( FCurFileInfo, SizeOf( FCurFileInfo ) );&lt;br /&gt;      FStream.Write( Pos[1], SizeOf( Pos[1] ) );&lt;br /&gt;      FStream.Position := Pos[1];&lt;br /&gt;&lt;br /&gt;      //update summary&lt;br /&gt;      Inc( FCurSize, FCurFileInfo.Size );&lt;br /&gt;    finally&lt;br /&gt;      InputFile.Free;&lt;br /&gt;    end;&lt;br /&gt;  except&lt;br /&gt;    on E: Exception do&lt;br /&gt;      raise EWriteError.CreateFmt( '%s.StreamFile: Error on joining: "%s" - %s',  [ ClassName, FCurFilename, E.Message ] );&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TFileJoiner.Add(const FromPath, ToPath: string;&lt;br /&gt;  const OverwriteMode: TOverwriteMode; const Recursive: Boolean; const MustKeep: Boolean ): Integer;&lt;br /&gt;begin&lt;br /&gt;  Result := FPaths.Add( TFileJoinerItem.Create( FromPath, ToPath, OverwriteMode, Recursive, MustKeep ) );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.Clear;&lt;br /&gt;var&lt;br /&gt;  I: Integer;&lt;br /&gt;begin&lt;br /&gt;  for I := FPaths.Count - 1 downto 0 do&lt;br /&gt;  begin&lt;br /&gt;    TFileJoinerItem( FPaths[I] ).Free;&lt;br /&gt;    FPaths.Delete( I );&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;constructor TFileJoiner.Create;&lt;br /&gt;begin&lt;br /&gt;  FPaths := TList.Create;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;destructor TFileJoiner.Destroy;&lt;br /&gt;begin&lt;br /&gt;  Clear;&lt;br /&gt;  FPaths.Free;&lt;br /&gt;  inherited;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.CountFiles;&lt;br /&gt;type&lt;br /&gt;  PStackItem = ^TStackItem;&lt;br /&gt;  TStackItem = record&lt;br /&gt;    Data: PChar;&lt;br /&gt;    Searcher: TSearchRec;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  I: Integer;&lt;br /&gt;  Path, Filter: string;&lt;br /&gt;  Stack: TStack;&lt;br /&gt;  CurStack, X: PStackItem;&lt;br /&gt;begin&lt;br /&gt;  FTotalFiles := 0;&lt;br /&gt;  FTotalSize := 0;&lt;br /&gt;&lt;br /&gt;  Stack := TStack.Create;&lt;br /&gt;  try&lt;br /&gt;    for I := 0 to FPaths.Count - 1 do&lt;br /&gt;    begin&lt;br /&gt;      Path := Self[I].Source;&lt;br /&gt;      if LastDelimiter( '*?', ExtractFileName( Path ) ) &lt;&gt; 0 then&lt;br /&gt;      begin&lt;br /&gt;        Filter := ExtractFileName( Path );&lt;br /&gt;        Path := ExtractFilePath( Path );&lt;br /&gt;      end&lt;br /&gt;      else if FileExists( Path ) then&lt;br /&gt;      else if DirectoryExists( Path ) then&lt;br /&gt;      begin&lt;br /&gt;        Filter := '*';&lt;br /&gt;        Path := AddSlash( Path );&lt;br /&gt;      end&lt;br /&gt;      else&lt;br /&gt;        raise Exception.CreateFmt( '%s.GetFilesSumary: "%s" n&#227;o encontrado', [ ClassName, Path ] );&lt;br /&gt;&lt;br /&gt;      New( CurStack );&lt;br /&gt;      CurStack^.Data := CopyString( Path );&lt;br /&gt;      repeat&lt;br /&gt;        with CurStack^ do&lt;br /&gt;        begin&lt;br /&gt;          if FindFirst( Data + Filter, faDirectory, Searcher ) = 0 then&lt;br /&gt;          begin&lt;br /&gt;            repeat&lt;br /&gt;              Inc( FTotalFiles );&lt;br /&gt;              Inc( FTotalSize, Searcher.Size );&lt;br /&gt;            until FindNext( Searcher ) &lt;&gt; 0;&lt;br /&gt;            FindClose( Searcher );&lt;br /&gt;          end;&lt;br /&gt;&lt;br /&gt;          if Self[I].Recurse and ( FindFirst( Data + Filter, faArchive, Searcher ) = 0 ) then&lt;br /&gt;          begin&lt;br /&gt;            repeat&lt;br /&gt;              if Searcher.Name[1] &lt;&gt; '.' then&lt;br /&gt;              begin&lt;br /&gt;                New( X );&lt;br /&gt;                X^.Data := CopyString( AddSlash( Data + Searcher.Name ) );&lt;br /&gt;                Stack.Push( X );&lt;br /&gt;              end;&lt;br /&gt;            until FindNext( Searcher ) &lt;&gt; 0;&lt;br /&gt;            FindClose( Searcher );&lt;br /&gt;          end;&lt;br /&gt;          FreeMem( Data );&lt;br /&gt;          Dispose( CurStack );&lt;br /&gt;          CurStack := Stack.Pop;&lt;br /&gt;        end;&lt;br /&gt;      until CurStack = nil;&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    Stack.Free;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TFileJoiner.GetItem(const Index: Integer): TFileJoinerItem;&lt;br /&gt;begin&lt;br /&gt;  Result := FPaths.Items[ Index ];&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TFileJoiner.GetCount: Integer;&lt;br /&gt;begin&lt;br /&gt;  Result := FPaths.Count;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.ListFiles( const Callback: TFileJoinerFilesCallback);&lt;br /&gt;type&lt;br /&gt;  PStackItem = ^TStackItem;&lt;br /&gt;  TStackItem = record&lt;br /&gt;    Source, Destiny: PChar;&lt;br /&gt;    Searcher: TSearchRec;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  Stack: TStack;&lt;br /&gt;  Filter: string;&lt;br /&gt;  Current, X: PStackItem;&lt;br /&gt;  Data: TFileJoinerItem;&lt;br /&gt;  I: Integer;&lt;br /&gt;begin&lt;br /&gt;  Stack := TStack.Create;&lt;br /&gt;  try&lt;br /&gt;    Data := TFileJoinerItem.Create;&lt;br /&gt;    try&lt;br /&gt;      for I := 0 to FPaths.Count - 1 do&lt;br /&gt;      begin&lt;br /&gt;        Data.Assign( Self[I] );&lt;br /&gt;        with Data do&lt;br /&gt;        begin&lt;br /&gt;          Destiny := AddSlash( Destiny );&lt;br /&gt;          if LastDelimiter( '*?', ExtractFileName( Source ) ) &lt;&gt; 0 then&lt;br /&gt;          begin&lt;br /&gt;            Filter := ExtractFileName( Source );&lt;br /&gt;            Source := ExtractFilePath( Source );&lt;br /&gt;          end&lt;br /&gt;          else if FileExists( Source ) then&lt;br /&gt;          begin&lt;br /&gt;            Destiny := Destiny + ExtractFileName( Data.Source );&lt;br /&gt;            Callback( Self, Data );&lt;br /&gt;            Continue;&lt;br /&gt;          end&lt;br /&gt;          else if DirectoryExists( Source ) then&lt;br /&gt;          begin&lt;br /&gt;            Filter := '*';&lt;br /&gt;            Destiny := AddSlash( Destiny + ExtractFileName( RemoveSlash( Source ) ) );&lt;br /&gt;            Source := AddSlash( Source );&lt;br /&gt;          end&lt;br /&gt;          else&lt;br /&gt;            raise Exception.CreateFmt( '%s.ListFiles: "%s" n&#227;o encontrado', [ ClassName, Source ] );&lt;br /&gt;        end;&lt;br /&gt;&lt;br /&gt;        New( Current );&lt;br /&gt;        with Current^ do&lt;br /&gt;        begin&lt;br /&gt;          Source := CopyString( Data.Source );&lt;br /&gt;          Destiny := CopyString( Data.Destiny );&lt;br /&gt;        end;&lt;br /&gt;&lt;br /&gt;        repeat&lt;br /&gt;          with Current^ do&lt;br /&gt;          begin&lt;br /&gt;            if FindFirst( Source + Filter, faDirectory, Searcher ) = 0 then&lt;br /&gt;            begin&lt;br /&gt;              repeat&lt;br /&gt;                Data.Source := Source + Searcher.Name;&lt;br /&gt;                Data.Destiny := Destiny + Searcher.Name;&lt;br /&gt;                Callback( Self, Data )&lt;br /&gt;              until FindNext( Searcher ) &lt;&gt; 0;&lt;br /&gt;              FindClose( Searcher );&lt;br /&gt;            end;&lt;br /&gt;&lt;br /&gt;            if Data.Recurse and ( FindFirst( Source + '*', faArchive, Searcher ) = 0 ) then&lt;br /&gt;            begin&lt;br /&gt;              repeat&lt;br /&gt;                if Searcher.Name[1] &lt;&gt; '.' then&lt;br /&gt;                begin&lt;br /&gt;                  New( X );&lt;br /&gt;                  X^.Source := CopyString( AddSlash( Source + Searcher.Name ) );&lt;br /&gt;                  X^.Destiny := CopyString( AddSlash( Destiny + Searcher.Name ) );&lt;br /&gt;                  Stack.Push( X );&lt;br /&gt;                end;&lt;br /&gt;              un</description>
      <pubDate>Thu, 15 Jun 2006 19:09:02 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2197</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
    <item>
      <title>Rails: Inner joins by association names</title>
      <link>http://snippets.dzone.com/posts/show/2119</link>
      <description>From http://habtm.com/articles/2006/05/10/inner-joins-by-association-names:&lt;br /&gt;&lt;br /&gt;We can enjoy eager loading with association names.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Member.find(:all, :include=&gt;[:group, :profile])&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;But :joins option forces us to write raw SQL like this.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Member.count(:joins=&gt;"INNER JOIN groups ON groups.id = members.group_id ...")&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Why should we do it by hand although those AR classes know their reflections? It&#8217;s too boring and painful, and far from DRY.&lt;br /&gt;expand join query&lt;br /&gt;&lt;br /&gt;So, why don&#8217;t you put this code to &#8216;vendor/plugins/expandjoinquery/init.rb&#8217;?&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class ActiveRecord::Base&lt;br /&gt;  class &lt;&lt; self&lt;br /&gt;    private&lt;br /&gt;    def add_joins!(sql, options, scope = :auto)&lt;br /&gt;      scope = scope(:find) if :auto == scope&lt;br /&gt;      join = (scope &amp;&amp; scope[:joins]) || options[:joins]&lt;br /&gt;      sql &lt;&lt; " #{expand_join_query(join)} " if join&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def expand_join_query(*joins)&lt;br /&gt;      joins.flatten.map{|join|&lt;br /&gt;        case join&lt;br /&gt;        when Symbol&lt;br /&gt;          ref = reflections[join] or&lt;br /&gt;            raise ActiveRecord::ActiveRecordError, "Could not find the source association :#{join} in model #{self}"&lt;br /&gt;          case ref.macro&lt;br /&gt;          when :belongs_to&lt;br /&gt;            "INNER JOIN %s ON %s.%s = %s.%s" % [ref.table_name, ref.table_name, primary_key, table_name, ref.primary_key_name]&lt;br /&gt;          else&lt;br /&gt;            "INNER JOIN %s ON %s.%s = %s.%s" % [ref.table_name, ref.table_name, ref.primary_key_name, table_name, primary_key]&lt;br /&gt;          end&lt;br /&gt;        else&lt;br /&gt;          join.to_s&lt;br /&gt;        end&lt;br /&gt;      }.join(" ")&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now, we can enjoy :joins option as same as :include one!&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# simply inner join&lt;br /&gt;Member.find(:first, :joins=&gt;:group)&lt;br /&gt;=&gt; SELECT * FROM members INNER JOIN groups ON groups.id = members.group_id LIMIT 1&lt;br /&gt;&lt;br /&gt;# two inner joins&lt;br /&gt;Member.count(:joins=&gt;[:group, :profile])&lt;br /&gt;=&gt; SELECT count(*) AS count_all FROM members&lt;br /&gt;   INNER JOIN groups   ON groups.id = members.group_id&lt;br /&gt;   INNER JOIN profiles ON profiles.member_id = members.id &lt;br /&gt;&lt;br /&gt;# symbol and raw SQL&lt;br /&gt;Member.find(:all, :joins=&gt;[:group, "INNER JOIN addresses USING(address_id)"])&lt;br /&gt;=&gt; SELECT * FROM members&lt;br /&gt;   INNER JOIN groups ON groups.id = members.group_id &lt;br /&gt;   INNER JOIN addresses USING(address_id) &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;restrictions&lt;br /&gt;&lt;br /&gt;This is just an idea and not deeply considered yet. So, there are following restrictions.&lt;br /&gt;&lt;br /&gt;    * cascading is not supported&lt;br /&gt;    * not work with :include option (i think)&lt;br /&gt;&lt;br /&gt;I hope someone will polish this up :)&lt;br /&gt;</description>
      <pubDate>Tue, 30 May 2006 08:58:02 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2119</guid>
      <author>MattScilipoti (Matt Scilipoti)</author>
    </item>
  </channel>
</rss>
