Initial commit
This commit is contained in:
commit
ecd5ee5eb0
2 changed files with 292 additions and 0 deletions
280
src/xapian.nim
Normal file
280
src/xapian.nim
Normal file
|
@ -0,0 +1,280 @@
|
|||
# SPDX-FileCopyrightText: 2022 Emery Hemingway
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
{.passC: staticExec("pkg-config --cflags xapian-core").}
|
||||
{.passL: staticExec("pkg-config --libs xapian-core").}
|
||||
|
||||
{.pragma: xapianHeader, header: "xapian.h".}
|
||||
{.pragma: importXapian, xapianHeader, importcpp: "Xapian::$1".}
|
||||
{.pragma: importGetter, importcpp: "#.get_$1()".}
|
||||
|
||||
type CppString {.importcpp: "std::string", header: "<string>", byRef.} = object
|
||||
proc data(s: CppString): pointer {.importcpp.}
|
||||
proc length(s: CppString): csize_t {.importcpp.}
|
||||
|
||||
proc basic_string(str: ptr char; len: int): CppString {.
|
||||
constructor, importcpp: "std::basic_string(@)".}
|
||||
|
||||
proc toCpp(s: string): CppString = basic_string(unsafeAddr s[0], s.len)
|
||||
|
||||
proc `$`(cpp: CppString): string =
|
||||
if cpp.length > 0:
|
||||
result.setLen(cpp.length)
|
||||
copyMem(addr result[0], cpp.data, result.len)
|
||||
|
||||
const
|
||||
DB_CREATE_OR_OPEN* = 0x00
|
||||
DB_CREATE_OR_OVERWRITE* = 0x01
|
||||
DB_CREATE* = 0x02
|
||||
DB_OPEN* = 0x03
|
||||
DB_NO_SYNC* = 0x04
|
||||
DB_FULL_SYNC* = 0x08
|
||||
DB_DANGEROUS* = 0x10
|
||||
DB_NO_TERMLIST* = 0x20
|
||||
DB_RETRY_LOCK* = 0x40
|
||||
DB_BACKEND_GLASS* = 0x100
|
||||
DB_BACKEND_CHERT* = 0x200
|
||||
DB_BACKEND_STUB* = 0x300
|
||||
DB_BACKEND_INMEMORY* = 0x400
|
||||
DB_BACKEND_HONEY* = 0x500
|
||||
|
||||
when defined(enable_64bit_docid):
|
||||
type
|
||||
DocId* = distinct uint64
|
||||
DocCount* = uint64
|
||||
else:
|
||||
type
|
||||
DocId* = distinct uint32
|
||||
DocCount* = uint32
|
||||
|
||||
when defined(enable_64bit_termcount):
|
||||
type TermCount* = uint64
|
||||
else:
|
||||
type TermCount* = uint32
|
||||
|
||||
when defined(enable_64bit_termpos):
|
||||
type TermPos* = uint64
|
||||
else:
|
||||
type TermPos* = uint32
|
||||
|
||||
proc `$`*(id: DocId): string {.borrow.}
|
||||
proc `==`*(a, b: DocId): bool {.borrow.}
|
||||
|
||||
type
|
||||
Rev* = int64
|
||||
TotalLength* = int64
|
||||
|
||||
Error* {.importXapian, inheritable.} = object
|
||||
LogicError* {.importXapian.} = object of Error
|
||||
RuntimeError* {.importXapian.} = object of Error
|
||||
AssertionError* {.importXapian.} = object of LogicError
|
||||
InvalidArgumentError* {.importXapian.} = object of LogicError
|
||||
InvalidOperationError* {.importXapian.} = object of LogicError
|
||||
UnimplementedError* {.importXapian.} = object of LogicError
|
||||
DatabaseError* {.importXapian.} = object of RuntimeError
|
||||
DatabaseCorruptError* {.importXapian.} = object of DatabaseError
|
||||
DatabaseCreateError* {.importXapian.} = object of DatabaseError
|
||||
DatabaseLockError* {.importXapian.} = object of DatabaseError
|
||||
DatabaseModifiedError* {.importXapian.} = object of DatabaseError
|
||||
DatabaseOpeningError* {.importXapian.} = object of DatabaseError
|
||||
DatabaseVersionError* {.importXapian.} = object of DatabaseOpeningError
|
||||
DocNotFoundError* {.importXapian.} = object of RuntimeError
|
||||
FeatureUnavailableError* {.importXapian.} = object of RuntimeError
|
||||
InternalError* {.importXapian.} = object of RuntimeError
|
||||
NetworkError* {.importXapian.} = object of RuntimeError
|
||||
NetworkTimeoutError* {.importXapian.} = object of NetworkError
|
||||
QueryParserError* {.importXapian.} = object of RuntimeError
|
||||
SerialisationError* {.importXapian.} = object of RuntimeError
|
||||
RangeError* {.importXapian.} = object of RuntimeError
|
||||
WildcardError* {.importXapian.} = object of RuntimeError
|
||||
DatabaseNotFoundError* {.importXapian.} = object of DatabaseOpeningError
|
||||
DatabaseClosedError* {.importXapian.} = object of DatabaseError
|
||||
|
||||
Database* {.importXapian, byRef.} = object
|
||||
WritableDatabase* {.importXapian, byRef.} = object
|
||||
Document* {.importXapian, byRef.} = object
|
||||
Enquire* {.importXapian, byRef.} = object
|
||||
MSet* {.importXapian, byRef.} = object
|
||||
MSetIterator {.importXapian, byRef.} = object
|
||||
Query* {.importXapian, byRef.} = object
|
||||
QueryParser* {.importXapian, byRef.} = object
|
||||
Stem* {.importXapian, byRef.} = object
|
||||
TermGenerator* {.importXapian, byRef.} = object
|
||||
|
||||
proc sortable_serialise(n: cdouble): CppString {.importcpp: "Xapian::$1(@)".}
|
||||
proc sortable_unserialise(s: CppString): cdouble {.importcpp: "Xapian::$1(@)".}
|
||||
|
||||
# Database
|
||||
|
||||
proc initDatabase*(path: cstring; flags = cint 0): Database {.
|
||||
constructor, importcpp: "Xapian::Database(@)".}
|
||||
|
||||
proc reopen*(db: Database): bool {.importcpp.}
|
||||
proc close*(db: Database) {.importcpp.}
|
||||
proc has_positions*(db: Database): bool {.importcpp.}
|
||||
proc get_doccount*(db: Database): DocCount {.importcpp.}
|
||||
proc get_lastdocid*(db: Database): DocId {.importcpp.}
|
||||
proc get_average_length*(db: Database): float64 {.importcpp.}
|
||||
proc get_total_length*(db: Database): TotalLength {.importcpp.}
|
||||
proc get_document*(db: Database; id: DocId; flags = cint 0): Document {.importcpp.}
|
||||
proc get_uuid(db: Database): CppString {.importcpp.}
|
||||
proc uuid*(db: Database): string = $get_uuid(db)
|
||||
proc locked*(db: Database): bool {.importcpp.}
|
||||
proc lock*(db: Database; flags = cint 0): WritableDatabase {.importcpp.}
|
||||
proc unlock*(db: Database|WritableDatabase): Database {.importcpp.}
|
||||
|
||||
proc initWritableDatabase*(path: cstring; flags = cint 0; blockSize = cint 0): WritableDatabase {.
|
||||
constructor, importcpp: "Xapian::WritableDatabase(@)".}
|
||||
|
||||
proc add_document*(db: WritableDatabase; doc: Document): DocId {.importcpp.}
|
||||
|
||||
|
||||
# Document
|
||||
|
||||
proc get_data(doc: Document): CppString {.importcpp.}
|
||||
|
||||
proc data*(doc: Document): string = $get_data(doc)
|
||||
|
||||
proc set_data(doc: Document; data: ptr char; len: int) {.
|
||||
importcpp: "#.set_data(std::basic_string(@))".}
|
||||
|
||||
proc `data=`*(doc: Document; data: string) =
|
||||
doc.set_data(unsafeAddr data[0], len data)
|
||||
|
||||
proc get_value(doc: Document; slot: Natural): CppString {.importcpp.}
|
||||
proc add_value(doc: Document; slot: Natural; s: CppString) {.importcpp.}
|
||||
proc remove_value(doc: Document; slot: Natural) {.importcpp.}
|
||||
proc clear_values*(doc: Document) {.importcpp.}
|
||||
proc values_count*(doc: Document): cuint {.importcpp.}
|
||||
|
||||
proc `[]`*(doc: Document; slot: Natural): string =
|
||||
$get_value(doc, slot)
|
||||
proc `[]=`*(doc: Document; slot: Natural; val: string) =
|
||||
add_value(doc, slot, val.toCpp)
|
||||
proc `[]=`*(doc: Document; slot: Natural; val: SomeNumber) =
|
||||
add_value(doc, slot, sortable_serialise(cdouble val))
|
||||
|
||||
proc value*[T : SomeNumber](doc: Document; slot: Natural; default: T): T =
|
||||
var val = doc.get_value(slot)
|
||||
if val.length == 0:
|
||||
result = default
|
||||
else:
|
||||
result = T sortable_unserialise(val)
|
||||
|
||||
proc `del`*(doc: Document; slot: Natural) =
|
||||
remove_value(doc, slot)
|
||||
|
||||
# Enquire
|
||||
|
||||
proc initEnquire*(db: Database): Enquire {.
|
||||
constructor, importcpp: "Xapian::Enquire(@)".}
|
||||
|
||||
proc `query`*(e: Enquire): Query {.
|
||||
importcpp: "#.get_query(@)".}
|
||||
|
||||
proc `query=`*(e: Enquire; q: Query) {.
|
||||
importcpp: "#.set_query(@)".}
|
||||
|
||||
proc `set_query`*(e: Enquire; q: Query; query_length = TermCount 0) {.
|
||||
importcpp.}
|
||||
|
||||
proc get_mset*(e: Enquire;
|
||||
first, maxItems: DocCount;
|
||||
checkAtLeast = DocCount 0): MSet {.
|
||||
importcpp.}
|
||||
|
||||
# MSet
|
||||
proc size*(m: MSet): DocCount {.importcpp.}
|
||||
proc get_matches_estimated*(m: MSet): DocCount {.importcpp.}
|
||||
proc get_matches_upper_bound*(m: MSet): DocCount {.importcpp.}
|
||||
proc get_matches_lower_bound*(m: MSet): DocCount {.importcpp.}
|
||||
proc get_uncollapsed_matches_lower_bound*(m: MSet): DocCount {.importcpp.}
|
||||
proc get_uncollapsed_matches_estimated*(m: MSet): DocCount {.importcpp.}
|
||||
proc get_uncollapsed_matches_upper_bound*(m: MSet): DocCount {.importcpp.}
|
||||
proc get_max_attained*(m: MSet): DocCount {.importcpp.}
|
||||
proc get_max_possible*(m: MSet): DocCount {.importcpp.}
|
||||
proc get_firstitem*(m: MSet): DocCount {.importcpp.}
|
||||
|
||||
proc begin(m: MSet): MSetIterator {.importcpp.}
|
||||
proc `end`(m: MSet): MSetIterator {.importcpp.}
|
||||
proc `[]`*(m: MSet; i: int|DocCount): MSetIterator {.importcpp: "#[#]".}
|
||||
|
||||
proc next(iter: MSetIterator) {.importcpp: "++#".}
|
||||
|
||||
proc `==`(a, b: MSetIterator): bool {.importcpp: "# == #".}
|
||||
|
||||
proc get_docid*(iter: MSetIterator): DocId {.importcpp: "*#".} # C++ dumbfucks
|
||||
proc get_rank(iter: MSetIterator): DocCount {.importcpp.}
|
||||
proc get_document*(iter: MSetIterator): Document {.importcpp.}
|
||||
proc get_weight*(iter: MSetIterator): float {.importcpp.}
|
||||
proc get_collapse_key*(iter: MSetIterator): CppString {.importcpp.}
|
||||
proc get_collapse_count*(iter: MSetIterator): DocCount {.importcpp.}
|
||||
proc get_sort_key*(iter: MSetIterator): CppString {.importcpp.}
|
||||
proc get_percent*(iter: MSetIterator): int {.importcpp.}
|
||||
|
||||
type MSetItem* = object
|
||||
mset: MSet
|
||||
firstItem: DocCount
|
||||
docid*: DocId
|
||||
weight*: float64
|
||||
rank*: DocCount
|
||||
percent*: int
|
||||
collapseKey*: string
|
||||
collapseCount*: DocCount
|
||||
|
||||
proc initMSetItem(iter: MSetIterator; mset: MSet): MSetItem =
|
||||
result = MSetItem(
|
||||
mset: mset,
|
||||
firstitem: mset.get_firstitem(),
|
||||
docid: iter.get_docid(),
|
||||
weight: iter.get_weight(),
|
||||
rank: iter.get_rank(),
|
||||
percent: iter.get_percent(),
|
||||
collapse_key: $iter.get_collapse_key(),
|
||||
collapse_count: iter.get_collapse_count())
|
||||
|
||||
proc document*(item: MSetItem): Document =
|
||||
item.mset[item.rank].get_document()
|
||||
|
||||
iterator items*(mset: MSet): MSetItem =
|
||||
var iter = mset.begin()
|
||||
let `end` = mset.`end`()
|
||||
while iter != `end`:
|
||||
var item = initMSetItem(iter, mset)
|
||||
yield item
|
||||
next(iter)
|
||||
|
||||
# Query
|
||||
|
||||
# QueryParser
|
||||
|
||||
type StemStrategy* {.importcpp: "Xapian::QueryParser::stem_strategy".} = enum
|
||||
STEM_NONE, STEM_SOME, STEM_ALL, STEM_ALL_Z, STEM_SOME_FULL_POS
|
||||
|
||||
proc set_stemmer*(qp: QueryParser; s: Stem) {.importcpp.}
|
||||
proc set_stemming_strategy*(qp: QueryParser; s: StemStrategy) {.importcpp.}
|
||||
proc set_database*(qp: QueryParser; db: Database) {.importcpp.}
|
||||
|
||||
proc parse_query*(qp: QueryParser; query: cstring): Query {.importcpp.}
|
||||
|
||||
# Stem
|
||||
|
||||
proc initStem*(language: cstring; fallback = false): Stem {.
|
||||
constructor, importcpp: "Xapian::Stem(@)".}
|
||||
|
||||
proc `document`*(tg: TermGenerator; doc: Document) {.
|
||||
importcpp: "#.get_document(@)".}
|
||||
|
||||
proc `document=`*(tg: TermGenerator; data: Document) {.
|
||||
importcpp: "#.set_document(@)".}
|
||||
|
||||
proc index_text*(tg: TermGenerator;
|
||||
text: cstring; wdf_inc = TermCount 1; prefix = cstring "") {.
|
||||
importcpp.}
|
||||
|
||||
proc set_stemmer*(tg: TermGenerator; stemmer: Stem) {.importcpp.}
|
||||
|
||||
type Describeable = Enquire | Database | Document | MSet | MSetIterator | Query | QueryParser | Stem
|
||||
proc get_description(x: Describeable): CppString {.importcpp.}
|
||||
proc `$`*(x: Describeable): string = $get_description(x)
|
12
xapian.nimble
Normal file
12
xapian.nimble
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Package
|
||||
|
||||
version = "20220421"
|
||||
author = "Emery Hemingway"
|
||||
description = "Xapian library wrapper"
|
||||
license = "GPL-2.0-or-later"
|
||||
srcDir = "src"
|
||||
|
||||
|
||||
# Dependencies
|
||||
|
||||
requires "nim >= 1.6.4"
|
Loading…
Reference in a new issue