Back to index

php5  5.3.10
copy.c
Go to the documentation of this file.
00001 /*
00002 ** 2003 April 6
00003 **
00004 ** The author disclaims copyright to this source code.  In place of
00005 ** a legal notice, here is a blessing:
00006 **
00007 **    May you do good and not evil.
00008 **    May you find forgiveness for yourself and forgive others.
00009 **    May you share freely, never taking more than you give.
00010 **
00011 *************************************************************************
00012 ** This file contains code used to implement the COPY command.
00013 **
00014 ** $Id: copy.c 195361 2005-09-07 15:11:33Z iliaa $
00015 */
00016 #include "sqliteInt.h"
00017 
00018 /*
00019 ** The COPY command is for compatibility with PostgreSQL and specificially
00020 ** for the ability to read the output of pg_dump.  The format is as
00021 ** follows:
00022 **
00023 **    COPY table FROM file [USING DELIMITERS string]
00024 **
00025 ** "table" is an existing table name.  We will read lines of code from
00026 ** file to fill this table with data.  File might be "stdin".  The optional
00027 ** delimiter string identifies the field separators.  The default is a tab.
00028 */
00029 void sqliteCopy(
00030   Parse *pParse,       /* The parser context */
00031   SrcList *pTableName, /* The name of the table into which we will insert */
00032   Token *pFilename,    /* The file from which to obtain information */
00033   Token *pDelimiter,   /* Use this as the field delimiter */
00034   int onError          /* What to do if a constraint fails */
00035 ){
00036   Table *pTab;
00037   int i;
00038   Vdbe *v;
00039   int addr, end;
00040   char *zFile = 0;
00041   const char *zDb;
00042   sqlite *db = pParse->db;
00043 
00044 
00045   if( sqlite_malloc_failed  ) goto copy_cleanup;
00046   assert( pTableName->nSrc==1 );
00047   pTab = sqliteSrcListLookup(pParse, pTableName);
00048   if( pTab==0 || sqliteIsReadOnly(pParse, pTab, 0) ) goto copy_cleanup;
00049   zFile = sqliteStrNDup(pFilename->z, pFilename->n);
00050   sqliteDequote(zFile);
00051   assert( pTab->iDb<db->nDb );
00052   zDb = db->aDb[pTab->iDb].zName;
00053   if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb)
00054       || sqliteAuthCheck(pParse, SQLITE_COPY, pTab->zName, zFile, zDb) ){
00055     goto copy_cleanup;
00056   }
00057   v = sqliteGetVdbe(pParse);
00058   if( v ){
00059     sqliteBeginWriteOperation(pParse, 1, pTab->iDb);
00060     addr = sqliteVdbeOp3(v, OP_FileOpen, 0, 0, pFilename->z, pFilename->n);
00061     sqliteVdbeDequoteP3(v, addr);
00062     sqliteOpenTableAndIndices(pParse, pTab, 0);
00063     if( db->flags & SQLITE_CountRows ){
00064       sqliteVdbeAddOp(v, OP_Integer, 0, 0);  /* Initialize the row count */
00065     }
00066     end = sqliteVdbeMakeLabel(v);
00067     addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end);
00068     if( pDelimiter ){
00069       sqliteVdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n);
00070       sqliteVdbeDequoteP3(v, addr);
00071     }else{
00072       sqliteVdbeChangeP3(v, addr, "\t", 1);
00073     }
00074     if( pTab->iPKey>=0 ){
00075       sqliteVdbeAddOp(v, OP_FileColumn, pTab->iPKey, 0);
00076       sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
00077     }else{
00078       sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
00079     }
00080     for(i=0; i<pTab->nCol; i++){
00081       if( i==pTab->iPKey ){
00082         /* The integer primary key column is filled with NULL since its
00083         ** value is always pulled from the record number */
00084         sqliteVdbeAddOp(v, OP_String, 0, 0);
00085       }else{
00086         sqliteVdbeAddOp(v, OP_FileColumn, i, 0);
00087       }
00088     }
00089     sqliteGenerateConstraintChecks(pParse, pTab, 0, 0, pTab->iPKey>=0, 
00090                                    0, onError, addr);
00091     sqliteCompleteInsertion(pParse, pTab, 0, 0, 0, 0, -1);
00092     if( (db->flags & SQLITE_CountRows)!=0 ){
00093       sqliteVdbeAddOp(v, OP_AddImm, 1, 0);  /* Increment row count */
00094     }
00095     sqliteVdbeAddOp(v, OP_Goto, 0, addr);
00096     sqliteVdbeResolveLabel(v, end);
00097     sqliteVdbeAddOp(v, OP_Noop, 0, 0);
00098     sqliteEndWriteOperation(pParse);
00099     if( db->flags & SQLITE_CountRows ){
00100       sqliteVdbeAddOp(v, OP_ColumnName, 0, 1);
00101       sqliteVdbeChangeP3(v, -1, "rows inserted", P3_STATIC);
00102       sqliteVdbeAddOp(v, OP_Callback, 1, 0);
00103     }
00104   }
00105   
00106 copy_cleanup:
00107   sqliteSrcListDelete(pTableName);
00108   sqliteFree(zFile);
00109   return;
00110 }