Use the Mork reader class to import old history files, removing the dependency on Mork itself. Bug 322369, r=brettw.
git-svn-id: svn://10.0.0.236/trunk@187735 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
c061f4eb23
commit
08a296f11c
@ -69,7 +69,7 @@ REQUIRES += \
|
||||
locale \
|
||||
layout \
|
||||
dom \
|
||||
mork \
|
||||
morkreader \
|
||||
history \
|
||||
storage \
|
||||
places \
|
||||
@ -97,6 +97,10 @@ EXTRA_DSO_LDOPTS += \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_PLACES
|
||||
EXTRA_DSO_LDOPTS += $(DIST)/lib/$(LIB_PREFIX)morkreader_s.$(LIB_SUFFIX)
|
||||
endif
|
||||
|
||||
# Need to link to CoreFoundation for Mac Migrators (PList reading code)
|
||||
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
|
||||
@ -111,3 +111,9 @@
|
||||
|
||||
#define NS_LIVEMARKSERVICE_CONTRACTID \
|
||||
"@mozilla.org/browser/livemark-service;1"
|
||||
|
||||
#define NS_MORKHISTORYIMPORTER_CID \
|
||||
{ 0x428e6d12, 0x9c6d, 0x436f, {0xb7, 0xa3, 0x6c, 0xa5, 0xf4, 0x80, 0x92, 0x12}}
|
||||
|
||||
#define NS_MORKHISTORYIMPORTER_CONTRACTID \
|
||||
"@mozilla.org/browser/history-importer;1"
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#include "nsNavBookmarks.h"
|
||||
#include "nsFaviconService.h"
|
||||
#include "nsLivemarkService.h"
|
||||
#include "nsMorkHistoryImporter.h"
|
||||
#else
|
||||
#include "nsBookmarksService.h"
|
||||
#include "nsForwardProxyDataSource.h"
|
||||
@ -86,6 +87,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAnnotationService, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNavBookmarks, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFaviconService, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsLivemarkService, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMorkHistoryImporter)
|
||||
#else
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsBookmarksService, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsForwardProxyDataSource, Init)
|
||||
@ -174,6 +176,12 @@ static const nsModuleComponentInfo components[] =
|
||||
NS_LIVEMARKSERVICE_CID,
|
||||
NS_LIVEMARKSERVICE_CONTRACTID,
|
||||
nsLivemarkServiceConstructor },
|
||||
|
||||
{ "Mork History Importer",
|
||||
NS_MORKHISTORYIMPORTER_CID,
|
||||
NS_MORKHISTORYIMPORTER_CONTRACTID,
|
||||
nsMorkHistoryImporterConstructor },
|
||||
|
||||
#else
|
||||
|
||||
{ "Bookmarks",
|
||||
|
||||
@ -44,6 +44,7 @@ interface nsINavHistoryQuery;
|
||||
interface nsINavHistoryQueryOptions;
|
||||
interface nsITransactionManager;
|
||||
interface nsITreeColumn;
|
||||
interface nsIFile;
|
||||
|
||||
[scriptable, uuid(acae2b2d-5fcd-4419-b1bc-b7dc92a1836c)]
|
||||
interface nsINavHistoryResultNode : nsISupports
|
||||
@ -814,3 +815,13 @@ interface nsINavHistoryService : nsISupports
|
||||
*/
|
||||
readonly attribute nsITransactionManager transactionManager;
|
||||
};
|
||||
|
||||
/**
|
||||
* nsIMorkHistoryImporter is a service which handles importing old
|
||||
* history files.
|
||||
*/
|
||||
[scriptable, uuid(be935aed-6929-4e44-be29-17ec89e5c8bd)]
|
||||
interface nsIMorkHistoryImporter : nsISupports
|
||||
{
|
||||
void importHistory(in nsIFile file, in nsINavHistoryService history);
|
||||
};
|
||||
|
||||
@ -54,7 +54,7 @@ REQUIRES = xpcom \
|
||||
docshell \
|
||||
rdf \
|
||||
dom \
|
||||
mork \
|
||||
morkreader \
|
||||
pref \
|
||||
necko \
|
||||
intl \
|
||||
@ -89,6 +89,7 @@ CPPSRCS = \
|
||||
nsLivemarkService.cpp \
|
||||
nsBookmarksFeedHandler.cpp \
|
||||
nsMaybeWeakPtr.cpp \
|
||||
nsMorkHistoryImporter.cpp \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
230
mozilla/browser/components/places/src/nsMorkHistoryImporter.cpp
Normal file
230
mozilla/browser/components/places/src/nsMorkHistoryImporter.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Ryner <bryner@brianryner.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsMorkHistoryImporter.h"
|
||||
#include "nsNavHistory.h"
|
||||
#include "mozStorageHelper.h"
|
||||
#include "prprf.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsMorkHistoryImporter, nsIMorkHistoryImporter)
|
||||
|
||||
// Columns for entry (non-meta) history rows
|
||||
enum {
|
||||
kURLColumn,
|
||||
kNameColumn,
|
||||
kVisitCountColumn,
|
||||
kHiddenColumn,
|
||||
kTypedColumn,
|
||||
kLastVisitColumn,
|
||||
kColumnCount // keep me last
|
||||
};
|
||||
|
||||
static const char * const gColumnNames[] = {
|
||||
"URL", "Name", "VisitCount", "Hidden", "Typed", "LastVisitDate"
|
||||
};
|
||||
|
||||
struct TableReadClosure
|
||||
{
|
||||
TableReadClosure(nsMorkReader *aReader, nsINavHistoryService *aHistory)
|
||||
: reader(aReader), history(aHistory), swapBytes(PR_FALSE)
|
||||
{
|
||||
voidString.SetIsVoid(PR_TRUE);
|
||||
}
|
||||
|
||||
// Backpointers to the importer and history we're operating on
|
||||
nsMorkReader *reader;
|
||||
nsINavHistoryService *history;
|
||||
|
||||
// A voided string to use for the user title
|
||||
nsString voidString;
|
||||
|
||||
// Whether we need to swap bytes (file format is other-endian)
|
||||
PRBool swapBytes;
|
||||
|
||||
// Column ids if the columns that we care about
|
||||
nsCString columnIDs[kColumnCount];
|
||||
nsCString byteOrderColumn;
|
||||
};
|
||||
|
||||
// Enumerator callback to build up the column list
|
||||
/* static */ PLDHashOperator PR_CALLBACK
|
||||
nsMorkHistoryImporter::EnumerateColumnsCB(const nsACString &aColumnID,
|
||||
nsCString aName, void *aData)
|
||||
{
|
||||
TableReadClosure *data = NS_STATIC_CAST(TableReadClosure*, aData);
|
||||
for (PRUint32 i = 0; i < kColumnCount; ++i) {
|
||||
if (aName.Equals(gColumnNames[i])) {
|
||||
data->columnIDs[i].Assign(aColumnID);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
}
|
||||
if (aName.EqualsLiteral("ByteOrder")) {
|
||||
data->byteOrderColumn.Assign(aColumnID);
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// Reverses the high and low bytes in a PRUnichar buffer.
|
||||
// This is used if the file format has a different endianness from the
|
||||
// current architecture.
|
||||
static void
|
||||
SwapBytes(PRUnichar *buffer)
|
||||
{
|
||||
for (PRUnichar *b = buffer; *b; ++b) {
|
||||
PRUnichar c = *b;
|
||||
*b = (c << 8) | (c >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
// Enumerator callback to add a table row to the NavHistoryService
|
||||
/* static */ PLDHashOperator PR_CALLBACK
|
||||
nsMorkHistoryImporter::AddToHistoryCB(const nsACString &aRowID,
|
||||
const nsMorkReader::StringMap *aMap,
|
||||
void *aData)
|
||||
{
|
||||
TableReadClosure *data = NS_STATIC_CAST(TableReadClosure*, aData);
|
||||
nsMorkReader *reader = data->reader;
|
||||
nsCString values[kColumnCount];
|
||||
nsCString *columnIDs = data->columnIDs;
|
||||
|
||||
for (PRInt32 i = 0; i < kColumnCount; ++i) {
|
||||
aMap->Get(columnIDs[i], &values[i]);
|
||||
reader->NormalizeValue(values[i]);
|
||||
}
|
||||
|
||||
// title is really a UTF-16 string at this point
|
||||
nsCString &titleC = values[kNameColumn];
|
||||
|
||||
PRUint32 titleLength;
|
||||
const char *titleBytes;
|
||||
if (titleC.IsEmpty()) {
|
||||
titleBytes = "\0";
|
||||
titleLength = 0;
|
||||
} else {
|
||||
titleLength = titleC.Length() / 2;
|
||||
|
||||
// add an extra null byte onto the end, so that the buffer ends
|
||||
// with a complete unicode null character.
|
||||
titleC.Append('\0');
|
||||
|
||||
// Swap the bytes in the unicode characters if necessary.
|
||||
if (data->swapBytes) {
|
||||
SwapBytes(NS_REINTERPRET_CAST(PRUnichar*, titleC.BeginWriting()));
|
||||
}
|
||||
titleBytes = titleC.get();
|
||||
}
|
||||
|
||||
const PRUnichar *title = NS_REINTERPRET_CAST(const PRUnichar*, titleBytes);
|
||||
|
||||
PRInt32 err;
|
||||
PRInt32 count = values[kVisitCountColumn].ToInteger(&err);
|
||||
if (err != 0 || count == 0) {
|
||||
count = 1;
|
||||
}
|
||||
|
||||
PRTime date;
|
||||
if (PR_sscanf(values[kLastVisitColumn].get(), "%lld", &date) != 1) {
|
||||
date = -1;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), values[kURLColumn]);
|
||||
|
||||
if (uri) {
|
||||
PRBool isTyped = values[kTypedColumn].EqualsLiteral("1");
|
||||
nsINavHistoryService *history = data->history;
|
||||
history->SetPageDetails(uri, nsDependentString(title, titleLength),
|
||||
data->voidString, count,
|
||||
values[kHiddenColumn].EqualsLiteral("1"), isTyped);
|
||||
|
||||
if (date != -1) {
|
||||
PRInt32 transition = isTyped ? nsINavHistoryService::TRANSITION_TYPED
|
||||
: nsINavHistoryService::TRANSITION_LINK;
|
||||
// Referrer is not handled at present -- doing this requires adding
|
||||
// visits in such an order that we have a visit id for the referring
|
||||
// page already.
|
||||
|
||||
PRInt64 visitID;
|
||||
history->AddVisit(uri, date, 0, transition, 0, &visitID);
|
||||
}
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// ImportHistory is the main entry point to the importer.
|
||||
// It sets up the file stream and loops over the lines in the file to
|
||||
// parse them, then adds the resulting row set to history.
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMorkHistoryImporter::ImportHistory(nsIFile *aFile,
|
||||
nsINavHistoryService *aHistory)
|
||||
{
|
||||
// Read in the mork file
|
||||
nsMorkReader reader;
|
||||
nsresult rv = reader.Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = reader.Read(aFile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Gather up the column ids so we don't need to find them on each row
|
||||
TableReadClosure data(&reader, aHistory);
|
||||
reader.EnumerateColumns(EnumerateColumnsCB, &data);
|
||||
|
||||
// Determine the byte order from the table's meta-row.
|
||||
nsCString byteOrder;
|
||||
if (reader.GetMetaRow().Get(data.byteOrderColumn, &byteOrder)) {
|
||||
// Note whether the file uses a non-native byte ordering.
|
||||
// If it does, we'll have to swap bytes for PRUnichar values.
|
||||
reader.NormalizeValue(byteOrder);
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
data.swapBytes = !byteOrder.EqualsLiteral("LE");
|
||||
#else
|
||||
data.swapBytes = !byteOrder.EqualsLiteral("BE");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Now add the results to history
|
||||
nsNavHistory *history = NS_STATIC_CAST(nsNavHistory*, aHistory);
|
||||
mozIStorageConnection *conn = history->GetStorageConnection();
|
||||
mozStorageTransaction transaction(conn, PR_FALSE);
|
||||
|
||||
reader.EnumerateRows(AddToHistoryCB, &data);
|
||||
return transaction.Commit();
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Ryner <bryner@brianryner.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsMorkHistoryImporter_h_
|
||||
#define nsMorkHistoryImporter_h_
|
||||
|
||||
#include "nsINavHistoryService.h"
|
||||
#include "nsMorkReader.h"
|
||||
|
||||
// The nsMorkHistoryImporter object parses a Mork-format history file and
|
||||
// adds the history items to the NavHistoryService. It is invoked the first
|
||||
// time the history service is created for a given profile, if a Mork history
|
||||
// (history.dat) file exists.
|
||||
|
||||
class nsMorkHistoryImporter : public nsIMorkHistoryImporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMORKHISTORYIMPORTER
|
||||
|
||||
private:
|
||||
// Enumerator callback to build up a list of columns
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
EnumerateColumnsCB(const nsACString &aColumnID,
|
||||
nsCString aName,
|
||||
void *aData);
|
||||
|
||||
// Enumerator callback to add a single row to the NavHistory.
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
AddToHistoryCB(const nsACString &aRowID,
|
||||
const nsMorkReader::StringMap *aMap,
|
||||
void *aData);
|
||||
};
|
||||
|
||||
#endif // nsMorkHistoryImporter_h_
|
||||
@ -39,6 +39,7 @@
|
||||
#include <stdio.h>
|
||||
#include "nsNavHistory.h"
|
||||
#include "nsNavBookmarks.h"
|
||||
#include "nsMorkHistoryImporter.h"
|
||||
|
||||
#include "nsArray.h"
|
||||
#include "nsArrayEnumerator.h"
|
||||
@ -70,12 +71,7 @@
|
||||
#include "mozIStorageFunction.h"
|
||||
#include "mozStorageCID.h"
|
||||
#include "mozStorageHelper.h"
|
||||
|
||||
// mork
|
||||
#include "mdb.h"
|
||||
#include "nsMorkCID.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsIMdbFactoryFactory.h"
|
||||
|
||||
// Microsecond timeout for "recent" events such as typed and bookmark following.
|
||||
// If you typed it more than this time ago, it's not recent.
|
||||
@ -234,7 +230,6 @@ nsNavHistory::Init()
|
||||
|
||||
rv = InitDB();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
//ImportFromMork();
|
||||
|
||||
// commonly used prefixes that should be chopped off all history and input
|
||||
// urls before comparison
|
||||
@ -332,9 +327,11 @@ nsNavHistory::InitDB()
|
||||
}
|
||||
|
||||
// moz_history
|
||||
PRBool doImport = PR_FALSE;
|
||||
rv = mDBConn->TableExists(NS_LITERAL_CSTRING("moz_history"), &tableExists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (! tableExists) {
|
||||
doImport = PR_TRUE;
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE TABLE moz_history ("
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"url LONGVARCHAR, "
|
||||
@ -456,6 +453,19 @@ nsNavHistory::InitDB()
|
||||
"VALUES (?1, ?2, ?3, ?4, ?5)"),
|
||||
getter_AddRefs(mDBInsertVisit));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (doImport) {
|
||||
nsCOMPtr<nsIMorkHistoryImporter> importer = new nsMorkHistoryImporter();
|
||||
NS_ENSURE_TRUE(importer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<nsIFile> historyFile;
|
||||
rv = NS_GetSpecialDirectory(NS_APP_HISTORY_50_FILE,
|
||||
getter_AddRefs(historyFile));
|
||||
if (NS_SUCCEEDED(rv) && historyFile) {
|
||||
importer->ImportHistory(historyFile, this);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2878,228 +2888,6 @@ nsNavHistory::SetPageTitleInternal(nsIURI* aURI, PRBool aIsUserTitle,
|
||||
}
|
||||
|
||||
|
||||
// nsNavHistory::ImportFromMork
|
||||
//
|
||||
// FIXME: this is basically a hack, but it works.
|
||||
//
|
||||
// This is for development/testing purposes only. Uncomment the call to it
|
||||
// from nsNavHistory::Init, run the app, and recomment the call. If you call
|
||||
// this more than once, you'll get duplicate entries. Also, this assumes you
|
||||
// have no history. If there is a URL that already exists, you'll get
|
||||
// a duplicate entry and everything will break.
|
||||
//
|
||||
// This will be replaced by an importer that does not depend on the Mork
|
||||
// library for release (since the library is very large).
|
||||
|
||||
nsresult nsNavHistory::ImportFromMork()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFile> historyFile;
|
||||
rv = NS_GetSpecialDirectory(NS_APP_HISTORY_50_FILE, getter_AddRefs(historyFile));
|
||||
|
||||
static NS_DEFINE_CID(kMorkCID, NS_MORK_CID);
|
||||
nsIMdbFactory* mdbFactory;
|
||||
nsCOMPtr<nsIMdbFactoryFactory> factoryfactory =
|
||||
do_CreateInstance(kMorkCID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = factoryfactory->GetMdbFactory(&mdbFactory);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mdb_err err;
|
||||
|
||||
nsIMdbEnv* env;
|
||||
err = mdbFactory->MakeEnv(nsnull, &env);
|
||||
env->SetAutoClear(PR_TRUE);
|
||||
NS_ASSERTION((err == 0), "unable to create mdb env");
|
||||
NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
|
||||
|
||||
// MDB requires native file paths
|
||||
nsCAutoString filePath;
|
||||
rv = historyFile->GetNativePath(filePath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool exists = PR_TRUE;
|
||||
historyFile->Exists(&exists);
|
||||
if (! exists) {
|
||||
printf("No MDB file, not importing\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mdb_bool canopen = 0;
|
||||
mdbYarn outfmt = { nsnull, 0, 0, 0, 0, nsnull };
|
||||
|
||||
nsIMdbHeap* dbHeap = 0;
|
||||
mdb_bool dbFrozen = mdbBool_kFalse; // not readonly, we want modifiable
|
||||
nsCOMPtr<nsIMdbFile> oldFile; // ensures file is released
|
||||
err = mdbFactory->OpenOldFile(env, dbHeap, PromiseFlatCString(filePath).get(),
|
||||
dbFrozen, getter_AddRefs(oldFile));
|
||||
if ((err !=0) || !oldFile) {
|
||||
printf("Some error, not importing.\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
err = mdbFactory->CanOpenFilePort(env, oldFile, // the file to investigate
|
||||
&canopen, &outfmt);
|
||||
if ((err !=0) || !canopen) {
|
||||
printf("Some error 2, not importing.\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsIMdbThumb* thumb = nsnull;
|
||||
mdbOpenPolicy policy = { { 0, 0 }, 0, 0 };
|
||||
|
||||
err = mdbFactory->OpenFileStore(env, dbHeap, oldFile, &policy, &thumb);
|
||||
if ((err !=0) || !thumb) return NS_ERROR_FAILURE;
|
||||
|
||||
mdb_count total;
|
||||
mdb_count current;
|
||||
mdb_bool done;
|
||||
mdb_bool broken;
|
||||
|
||||
do {
|
||||
err = thumb->DoMore(env, &total, ¤t, &done, &broken);
|
||||
} while ((err == 0) && !broken && !done);
|
||||
|
||||
nsIMdbStore* store;
|
||||
if ((err == 0) && done) {
|
||||
err = mdbFactory->ThumbToOpenStore(env, thumb, &store);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(thumb);
|
||||
|
||||
NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
|
||||
|
||||
//rv = CreateTokens();
|
||||
//NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mdb_scope kToken_HistoryRowScope;
|
||||
err = store->StringToToken(env, "ns:history:db:row:scope:history:all", &kToken_HistoryRowScope);
|
||||
|
||||
mdbOid oid = { kToken_HistoryRowScope, 1 };
|
||||
nsIMdbTable* table;
|
||||
err = store->GetTable(env, &oid, &table);
|
||||
NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
|
||||
if (!table) {
|
||||
NS_WARNING("Your history file is somehow corrupt.. deleting it.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMdbRow> metaRow;
|
||||
err = table->GetMetaRow(env, &oid, nsnull, getter_AddRefs(metaRow));
|
||||
NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
|
||||
if (err != 0) {
|
||||
printf("Some error 3, not importing\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// FIXME: init byte order, may need to swap strings
|
||||
|
||||
nsIMdbTableRowCursor* cursor;
|
||||
table->GetTableRowCursor(env, -1, &cursor);
|
||||
NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
|
||||
|
||||
nsIMdbRow* currentRow;
|
||||
mdb_pos pos;
|
||||
|
||||
mdb_column urlColumn, hiddenColumn, typedColumn, titleColumn,
|
||||
visitCountColumn, visitDateColumn;
|
||||
err = store->StringToToken(env, "URL", &urlColumn);
|
||||
err = store->StringToToken(env, "Hidden", &hiddenColumn);
|
||||
err = store->StringToToken(env, "Typed", &typedColumn);
|
||||
err = store->StringToToken(env, "Name", &titleColumn);
|
||||
err = store->StringToToken(env, "VisitCount", &visitCountColumn);
|
||||
err = store->StringToToken(env, "LastVisitDate", &visitDateColumn);
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> insertHistory, insertVisit;
|
||||
rv = mDBConn->CreateStatement(
|
||||
NS_LITERAL_CSTRING("INSERT INTO moz_history (url, title, rev_host, visit_count, hidden, typed) VALUES (?1, ?2, ?3, ?4, ?5, ?6)"),
|
||||
getter_AddRefs(insertHistory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBConn->CreateStatement(
|
||||
NS_LITERAL_CSTRING("INSERT INTO moz_historyvisit (from_visit, page_id, visit_date, visit_type, session) VALUES (0, ?1, ?2, 0, 0)"),
|
||||
getter_AddRefs(insertVisit));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mDBConn->BeginTransaction();
|
||||
|
||||
PRInt32 insertCount = 0;
|
||||
while(1) {
|
||||
cursor->NextRow(env, ¤tRow, &pos);
|
||||
NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
|
||||
if (! currentRow)
|
||||
break;
|
||||
|
||||
// url
|
||||
mdbYarn yarn;
|
||||
err = currentRow->AliasCellYarn(env, urlColumn, &yarn);
|
||||
if (err != 0 || !yarn.mYarn_Buf) continue;
|
||||
nsCString urlString((char*)yarn.mYarn_Buf);
|
||||
|
||||
// typed
|
||||
PRBool typed = PR_TRUE;
|
||||
currentRow->AliasCellYarn(env, typedColumn, &yarn);
|
||||
if (err != 0 || !yarn.mYarn_Buf) typed = PR_FALSE;
|
||||
|
||||
// hidden
|
||||
PRBool hidden = PR_TRUE;
|
||||
currentRow->AliasCellYarn(env, hiddenColumn, &yarn);
|
||||
if (err != 0 || !yarn.mYarn_Buf) hidden = PR_FALSE;
|
||||
|
||||
// title
|
||||
nsAutoString title;
|
||||
err = currentRow->AliasCellYarn(env, titleColumn, &yarn);
|
||||
if (err == 0 && yarn.mYarn_Buf)
|
||||
title = nsString((PRUnichar*)yarn.mYarn_Buf);
|
||||
|
||||
// visit count
|
||||
PRInt32 visitCount = 0;
|
||||
currentRow->AliasCellYarn(env, visitCountColumn, &yarn);
|
||||
if (err == 0 && yarn.mYarn_Buf)
|
||||
sscanf((char*)yarn.mYarn_Buf, "%d", &visitCount);
|
||||
if (visitCount == 0)
|
||||
continue;
|
||||
|
||||
// last visit date (if none, don't add to history
|
||||
PRTime visitDate;
|
||||
currentRow->AliasCellYarn(env, visitDateColumn, &yarn);
|
||||
if (err != 0 || ! yarn.mYarn_Buf)
|
||||
continue;
|
||||
sscanf((char*)yarn.mYarn_Buf, "%lld", &visitDate);
|
||||
|
||||
NS_RELEASE(currentRow);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), PromiseFlatCString(urlString).get());
|
||||
nsAutoString revhost;
|
||||
rv = GetReversedHostname(uri, revhost);
|
||||
|
||||
insertHistory->BindUTF8StringParameter(0, urlString);
|
||||
insertHistory->BindStringParameter(1, title);
|
||||
insertHistory->BindStringParameter(2, revhost);
|
||||
insertHistory->BindInt32Parameter(3, visitCount);
|
||||
insertHistory->BindInt32Parameter(4, hidden);
|
||||
insertHistory->BindInt32Parameter(5, typed);
|
||||
rv = insertHistory->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt64 pageid;
|
||||
rv = mDBConn->GetLastInsertRowID(&pageid);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
insertVisit->BindInt64Parameter(0, pageid);
|
||||
insertVisit->BindInt64Parameter(1, visitDate);
|
||||
rv = insertVisit->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
insertCount ++;
|
||||
}
|
||||
mDBConn->CommitTransaction();
|
||||
printf("INSERTED %d ROWS FROM MORK\n", insertCount);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Local function **************************************************************
|
||||
|
||||
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
#include "nsINavHistoryService.h"
|
||||
#include "nsIAutoCompleteSearch.h"
|
||||
#include "nsIAutoCompleteResult.h"
|
||||
#include "nsIAutoCompleteResultTypes.h"
|
||||
#include "nsIAutoCompleteSimpleResult.h"
|
||||
#include "nsIBrowserHistory.h"
|
||||
#include "nsICollation.h"
|
||||
@ -386,8 +385,6 @@ protected:
|
||||
nsCOMArray<nsINavHistoryQuery>* aQueries,
|
||||
nsNavHistoryQueryOptions* aOptions);
|
||||
|
||||
nsresult ImportFromMork();
|
||||
|
||||
// Transaction Manager
|
||||
nsCOMPtr<nsITransactionManager> mTransactionManager;
|
||||
};
|
||||
|
||||
@ -44,5 +44,9 @@ include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = mdb mork
|
||||
|
||||
ifdef MOZ_PLACES
|
||||
DIRS += morkreader
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user