Compare commits

..

No commits in common. "master" and "0.2.7.25" have entirely different histories.

484 changed files with 2186 additions and 100237 deletions

View File

@ -1,48 +0,0 @@
version: 0.2.7.build{build}
image: Visual Studio 2019
clone_folder: C:\projects\welsonjs
environment:
ORGANIZATION_ID: 8ee5ec82-36dc-4619-ac33-5bc1117428fe
PROJECT_SLUG: welsonjs
ARTIFACT_CONFIGURATION_SLUG: initial
matrix:
- CONFIGURATION: Debug
SIGNING_POLICY_SLUG: test-signing
- CONFIGURATION: Release
SIGNING_POLICY_SLUG: release-signing
before_build:
- nuget restore WelsonJS.Toolkit
build_script:
- msbuild "C:\projects\welsonjs\WelsonJS.Toolkit\WelsonJS.Toolkit.sln" /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /p:Configuration=%CONFIGURATION% /p:Platform="x86"
after_build:
- cmd: mkdir artifacts
#- cmd: xcopy /s /y WelsonJS.Toolkit\WelsonJS.Toolkit\bin\x86\%CONFIGURATION%\* artifacts\
- cmd: xcopy /s /y WelsonJS.Toolkit\WelsonJS.Service\bin\x86\%CONFIGURATION%\* artifacts\
- cmd: xcopy /s /y WelsonJS.Toolkit\WelsonJS.Launcher\bin\x86\%CONFIGURATION%\* artifacts\
- cmd: xcopy /s /y WelsonJS.Toolkit\EsentInterop\bin\%CONFIGURATION%\* artifacts\
- cmd: nuget pack WelsonJS.Toolkit\WelsonJS.Toolkit\ -properties Configuration=%CONFIGURATION% -properties Platform=x86 -OutputDirectory artifacts\
- cmd: 7z a artifacts.zip artifacts\*
artifacts:
- path: artifacts.zip
name: WelsonJS.Toolkit
deploy:
- provider: Webhook
url: https://app.signpath.io/API/v1/%ORGANIZATION_ID%/Integrations/AppVeyor?ProjectSlug=%PROJECT_SLUG%&SigningPolicySlug=%SIGNING_POLICY_SLUG%&ArtifactConfigurationSlug=%ARTIFACT_CONFIGURATION_SLUG%
authorization:
secure: nABfe+lksIRfS7lVnkq3EdIYNH8KOka+5ZFTUJqUW2nckBubhrlAXarbCPJHLp9FWWf3zxAWhNwT0It+qyqPRQ==
notifications:
- provider: Email
to:
- gnh1201@catswords.re.kr
subject: 'Build #{{build}} {{status}}'
on_build_success: false
on_build_failure: true

2
.github/FUNDING.yml vendored
View File

@ -1,2 +0,0 @@
github: gnh1201
custom: ['https://gnh1201.link']

View File

@ -1,38 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -32,7 +32,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
language: [ 'javascript' ] language: [ 'csharp', 'javascript', 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support # Learn more about CodeQL language support at https://git.io/codeql-language-support
@ -42,7 +42,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v1
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@ -53,7 +53,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@ -67,4 +67,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v1

View File

@ -1,23 +0,0 @@
name: AI Code Review
on:
pull_request:
types: [opened, synchronize, reopened]
issues:
types: [opened, reopened]
jobs:
repofix:
runs-on: ubuntu-latest
steps:
- name: Run RepoFixAI
uses: Manav916/llm-code-review@main
with:
groq_api_key: ${{ secrets.GROQ_API_KEY }}
groq_model: 'llama-3.3-70b-versatile'
github_token: ${{ secrets.GITHUB_TOKEN }}
# exclude_extensions: 'txt'
repo_owner: ${{ github.repository_owner }}
repo_name: ${{ github.event.repository.name }}
event_number: ${{ github.event.number || github.event.issue.number }} # when listening for both pull requests and issues
event_name: ${{ github.event_name }}

12
.gitignore vendored
View File

@ -103,13 +103,5 @@ dist
# TernJS port file # TernJS port file
.tern-port .tern-port
# user private assets # ChatGPT API Key
bin data/chatgpt-apikey.txt
data/*-apikey.txt
data/*.nomedia.txt
app/assets/img/_templates
app/assets/img/_captured
settings.ini
defaultService.js
lib/*.private.js
data/python313.zip

View File

@ -28,18 +28,21 @@ All types of contributions are encouraged and valued. See the [Table of Contents
## Code of Conduct ## Code of Conduct
This project and everyone participating in it is governed by the [WelsonJS Code of Conduct](https://github.com/gnh1201/welsonjs/blob/master/CODE_OF_CONDUCT.md). This project and everyone participating in it is governed by the
By participating, you are expected to uphold this code. Please report unacceptable behavior to <abuse@catswords.net>. [WelsonJS Code of Conduct](https://github.com/gnh1201/welsonjs/blob/master/CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable behavior
to <abuse@catswords.net>.
## I Have a Question ## I Have a Question
> If you want to ask a question, we assume that you have read the available [Documentation](https://catswords-oss.rdbl.io/5719744820/5330609327). > If you want to ask a question, we assume that you have read the available [Documentation](https://catswords.social/@catswords_oss).
Before you ask a question, it is best to search for existing [Issues](https://github.com/gnh1201/welsonjs/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. Before you ask a question, it is best to search for existing [Issues](https://github.com/gnh1201/welsonjs//issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first.
If you then still feel the need to ask a question and need clarification, we recommend the following: If you then still feel the need to ask a question and need clarification, we recommend the following:
- Open an [Issue](https://github.com/gnh1201/welsonjs/issues/new). - Open an [Issue](https://github.com/gnh1201/welsonjs//issues/new).
- Provide as much context as you can about what you're running into. - Provide as much context as you can about what you're running into.
- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant. - Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant.
@ -84,7 +87,7 @@ A good bug report shouldn't leave others needing to chase you up for more inform
We use GitHub issues to track bugs and errors. If you run into an issue with the project: We use GitHub issues to track bugs and errors. If you run into an issue with the project:
- Open an [Issue](https://github.com/gnh1201/welsonjs/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.) - Open an [Issue](https://github.com/gnh1201/welsonjs//issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.)
- Explain the behavior you would expect and the actual behavior. - Explain the behavior you would expect and the actual behavior.
- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. - Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case.
- Provide the information you collected in the previous section. - Provide the information you collected in the previous section.
@ -106,14 +109,14 @@ This section guides you through submitting an enhancement suggestion for WelsonJ
#### Before Submitting an Enhancement #### Before Submitting an Enhancement
- Make sure that you are using the latest version. - Make sure that you are using the latest version.
- Read the [documentation](https://catswords-oss.rdbl.io/5719744820/5330609327) carefully and find out if the functionality is already covered, maybe by an individual configuration. - Read the [documentation](https://catswords.social/@catswords_oss) carefully and find out if the functionality is already covered, maybe by an individual configuration.
- Perform a [search](https://github.com/gnh1201/welsonjs/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. - Perform a [search](https://github.com/gnh1201/welsonjs/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. - Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library.
<!-- omit in toc --> <!-- omit in toc -->
#### How Do I Submit a Good Enhancement Suggestion? #### How Do I Submit a Good Enhancement Suggestion?
Enhancement suggestions are tracked as [GitHub issues](https://github.com/gnh1201/welsonjs/issues). Enhancement suggestions are tracked as [GitHub issues](https://github.com/gnh1201/welsonjs//issues).
- Use a **clear and descriptive title** for the issue to identify the suggestion. - Use a **clear and descriptive title** for the issue to identify the suggestion.
- Provide a **step-by-step description of the suggested enhancement** in as many details as possible. - Provide a **step-by-step description of the suggested enhancement** in as many details as possible.
@ -138,9 +141,7 @@ Flexible. We will respect your style.
Contact us: Contact us:
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss) * ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
* XMPP [catswords@conference.omemo.id](xmpp:catswords@conference.omemo.id?join) * abuse@catswords.net
* [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
* [Join Catswords OSS #welsonjs on Discord (discord.gg)](https://discord.gg/XKG5CjtXEj)
## Attribution ## Attribution
This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)! This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)!

8
FUNDING.yml Normal file
View File

@ -0,0 +1,8 @@
# These are supported funding model platforms
github: gnh1201
open_collective: welsonjs
liberapay: catswords
custom: ['https://www.buymeacoffee.com/catswords', 'https://toss.me/catswords']
patreon: catswords # Replace with a single Patreon username
ko_fi: catswords

View File

@ -1,4 +1,5 @@
Microsoft Reciprocal License (Ms-RL) Microsoft Reciprocal License (MS-RL)
SPDX Short identifier: MS-RL
This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
@ -28,3 +29,35 @@ A "contributor" is any person that distributes its contribution under this licen
(E) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. (E) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. (F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
Microsoft 상호 라이선스(MS-RL)
SPDX 짧은 식별자: MS-RL
이 라이센스는 함께 제공되는 소프트웨어의 사용에 적용됩니다. 소프트웨어를 사용하는 경우 이 라이센스에 동의하는 것입니다. 라이센스에 동의하지 않으면 소프트웨어를 사용하지 마십시오.
1. 정의
"복제", "복제물", "파생 저작물" 및 "배포"라는 용어는 여기에서 미국 저작권법과 동일한 의미를 갖습니다.
"기여"은 원본 소프트웨어 또는 소프트웨어에 대한 추가 또는 변경 사항입니다.
"기여자"는 이 라이선스에 따라 기여를 배포하는 모든 사람입니다.
"라이선스 지적재산권"은 기여에 대해 직접 읽는 기여자의 지적재산권 주장입니다.
2. 권리 부여
(A) 저작권 부여 - 섹션 3의 라이선스 조건 및 제한 사항을 포함하여 이 라이선스의 조건에 따라 각 기여자는 자신의 기여를 복제하고 파생 작업을 준비할 수 있는 비독점적이고 전세계적인 로열티 없는 저작권 라이선스를 부여합니다. 기여 및 귀하가 만든 기여 또는 파생 작업을 배포합니다.
(B) 지적재산권 부여 - 섹션 3의 라이선스 조건 및 제한 사항을 포함하여 이 라이선스의 조건에 따라 각 기여자는 라이선스가 부여된 지적재산권에 따라 귀하에게 비독점적이고 전 세계적으로 사용료가 없는 라이선스를 부여합니다. 여기에는 판매, 판매 제안, 수입 및 또는 소프트웨어에 대한 기여 또는 소프트웨어 기여의 파생물을 처분하는 행위를 포함합니다.
3. 조건 및 제한
(A) 상호 부여 - 소프트웨어의 코드(소스코드 또는 바이너리 형식)가 포함된 배포하는 모든 파일의 경우 해당 파일에 적용되는 라이선스의 사본과 함께 해당 파일의 소스코드를 수신자에게 제공해야 합니다. . 귀하는 전적으로 귀하의 저작물이며 귀하가 선택한 조건에 따라 소프트웨어의 코드를 포함하지 않는 다른 파일에 라이선스를 부여할 수 있습니다.
(B) 상표 사용권 없음 - 이 사용권은 기여자의 이름, 로고 또는 상표를 사용할 수 있는 권한을 부여하지 않습니다.
(C) 귀하가 소프트웨어에 의해 침해되었다고 주장하는 지적재산권에 대해 기여자에 대해 지적재산권 청구를 제기하는 경우 해당 기여자의 소프트웨어에 대한 귀하의 지적재산권 라이선스는 자동으로 종료됩니다.
(D) 소프트웨어의 일부를 배포하는 경우 소프트웨어에 있는 모든 저작권, 지적재산권, 상표 및 귀속 고지를 보유해야 합니다.
(E) 소프트웨어의 일부를 소스코드 형식으로 배포하는 경우 배포와 함께 이 라이센스의 전체 사본을 포함하여 이 라이센스 하에서만 그렇게 할 수 있습니다. 소프트웨어의 일부를 컴파일된 또는 개체 코드 형식으로 배포하는 경우 이 라이센스를 준수하는 라이센스 하에서만 배포할 수 있습니다.
(F) 소프트웨어는 "있는 그대로" 사용이 허가됩니다. 당신은 그것을 사용할 위험을 감수합니다. 기여자는 명시적 보증, 보증 또는 조건을 제공하지 않습니다. 귀하는 현지 법률에 따라 이 라이선스가 변경할 수 없는 추가적인 소비자 권리를 가질 수 있습니다. 현지 법률에서 허용하는 범위 내에서 기여자는 상품성, 특정 목적에의 적합성 및 비침해성에 대한 묵시적 보증을 배제합니다.

233
README.md
View File

@ -1,86 +1,86 @@
# welsonjs # welsonjs
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs?ref=badge_shield) [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs?ref=badge_shield)
[![AppVeyor Status](https://ci.appveyor.com/api/projects/status/github/gnh1201/welsonjs?svg=true)](https://ci.appveyor.com/project/gnh1201/welsonjs) [![DOI](https://zenodo.org/badge/275600068.svg)](https://zenodo.org/doi/10.5281/zenodo.11382384)
[![DOI 10.5281/zenodo.11382384](https://zenodo.org/badge/DOI/10.5281/zenodo.11382384.svg)](https://doi.org/10.5281/zenodo.11382384)
[![ChatGPT available](https://img.shields.io/badge/ChatGPT-74aa9c?logo=openai&logoColor=white)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![Anthropic available](https://img.shields.io/badge/Anthropic-000000?logo=Anthropic&logoColor=white)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![Grok available](https://img.shields.io/badge/Grok-000000?logo=x&logoColor=white)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![Google Gemini available](https://img.shields.io/badge/Google%20Gemini-886FBF?logo=googlegemini&logoColor=fff)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![slideshare.net presentation](https://img.shields.io/badge/SlideShare-black?logo=slideshare)](https://www.slideshare.net/slideshow/welsonjs-javascript-framework-presentation-2024/276005486)
[![YouTube promotion video](https://img.shields.io/badge/YouTube-red?logo=youtube)](https://youtu.be/JavH7Dms8-U)
[![Discord chat](https://img.shields.io/discord/359930650330923008?logo=discord)](https://discord.gg/XKG5CjtXEj)
[![Open to work](https://img.shields.io/badge/%23-OPENTOWORK-green)](https://github.com/gnh1201/welsonjs/discussions/167)
<img src="app/assets/img/logo.svg" height="32" alt=""/> WelsonJS - Build a Windows app on the Windows built-in JavaScript engine. WelsonJS - Build a Windows app on the Windows built-in JavaScript engine.
![A Cover Image: Windows in 1999](https://ics.catswords.net/cover.png) ![(Cover Image) A man programming against a power plant facility, the screen that the man is watching shows the Windows logo](app/assets/img/overture.jpg)
Now, You can build a Windows desktop app with JavaScript, TypeScript, CoffeeScript, ReScript, and HTML/CSS on Windows built-in ECMAScript engine. Now, You can build an Windows desktop app with JavaScript, TypeScript, CoffeeScript, ReScript, and HTML/CSS on Windows built-in ECMAScript engine.
WelsonJS = ***W***indows + ***El***ectr***on***-like + ***Javascript(JS)*** + :heart:[Contributions](https://github.com/sponsors/gnh1201) WelsonJS = ***W***indows + ***El***ectr***on***-like + ***Javascript(JS)*** + [Your contribution](FUNDING.yml)
* :kissing_cat: [Download Latest WelsonJS Launcher (ics.catswords.net)](https://ics.catswords.net/welsonjs_launcher_latest.zip) Dual license notice: The default license for this project is GPL 3.0. However, if the GPL 3.0 license is not compatible with Microsoft products, it is subject to the MS-RL license.
* :rocket: [Launch the WelsonJS environment on Microsoft Azure (azuremarketplace.microsoft.com)](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/catswords.catswords-welsonjs-feb2025-02?tab=Overview)
**Note**: The default license for this project is GPL 3.0. However, if the GPL 3.0 license is not compatible with Microsoft products, it is subject to the MS-RL license.
## Sponsors
* :octocat: [GitHub Sponsors](https://github.com/sponsors/gnh1201), :coffee: [Buy me a coffee](https://buymeacoffee.com/catswords)
* <img src="https://ics.catswords.net/serpapi_logo_32.png" height="32" alt=""/> [SerpApi](https://serpapi.com/?utm_source=welsonjs): Search API - Scrape search engines results with simple API.
* <img src="https://ics.catswords.net/logo_oss.gif" height="32" alt=""/> [Open SW Portal](https://oss.kr), NIPA National IT Industry Promotion Agency<sup>(정보통신산업진흥원)</sup>
* <img src="https://ics.catswords.net/signpath_logo.png" height="32" alt=""/> Free code signing provided by [SignPath.io](https://signpath.io), certificate by [SignPath Foundation](https://signpath.org/)
* <img src="https://ics.catswords.net/f1security_logo.png" height="32" alt=""/> [F1Security<sup>(에프원시큐리티)</sup>](https://f1security.co.kr/) provides [industry-leading](https://www.ksecurity.or.kr/kisis/subIndex/469.do) web security services.
* <img src="https://ics.catswords.net/microsoft_logo.png" height="32" alt=""/> [Microsoft ISV Success Program](https://www.microsoft.com/en-us/isv/isv-success), Grow your business with powerful tools.
* :zap: [Integrations](https://catswords-oss.rdbl.io/5719744820/8278298336) ([ScrapeOps](https://scrapeops.io?fpr=namhyeon75), [AviationStack](https://aviationstack.com?utm_source=FirstPromoter&utm_medium=Affiliate&fpr=namhyeon71), [Coupang](https://link.coupang.com/a/b7HV3V)...)
## System Requirements
* **Operating Systems**: Windows XP SP3 or later (Currently, Windows 11 24H2)
* For systems running Windows 2000 or earlier versions (e.g., 95, 98, Me), please contact us separately.
## Why Choose WelsonJS?
WelsonJS is an advanced JavaScript framework designed to operate in extreme conditions where conventional solutions may fail. Unlike traditional JavaScript frameworks, WelsonJS focuses on executing scripts in constrained environments, ensuring reliable performance even with minimal system resources.
### Key Features
* **Lightweight and Efficient**: Optimized for environments with limited computing power, WelsonJS delivers efficient script execution without unnecessary overhead.
* **Windows ECMAScript Compatibility**: Designed to run seamlessly on Windows-based systems, adhering to the ECMAScript standard while maintaining lightweight execution.
* **Standalone Execution**: Unlike well-known JavaScript runtimes, which require external dependencies, a WelsonJS application can operate as a self-contained app, making it suitable for embedded systems and isolated environments.
* **Security-Oriented**: Built with security in mind, ensuring controlled execution of scripts without compromising system integrity.
* **Minimalist Design**: WelsonJS strips away unnecessary complexities, focusing on core functionalities that maximize performance and reliability.
### Use Cases
* **Legacy System Integration**: WelsonJS provides a practical solution for running JavaScript on older Windows environments where modern frameworks are not feasible.
* **Automation and Scripting**: Ideal for executing scripts in constrained environments, enabling automated workflows and system-level scripting.
* **Embedded Applications**: Suitable for devices and systems with strict resource constraints, such as industrial controllers and embedded platforms.
* **Security-Focused Environments**: Useful in security-sensitive applications where dependencies on external network connections are limited.
* **Office Automation**: Suitable for office automation tasks using Microsoft Office and various LLM-based AI (such as ChatGPT).
WelsonJS is tailored for developers who need a reliable, lightweight JavaScript framework in environments where traditional solutions are impractical. Whether working with legacy systems, embedded devices, or security-critical applications, WelsonJS ensures that JavaScript remains a viable and efficient option.
## Structure ## Structure
![The structure of the WelsonJS framework can be extended based on whether it operates in a console (command prompt) environment, a GUI (with HTML/CSS) environment, or a service environment, with the `app.js` file at its core.](https://ics.catswords.net/structure.png) ![Structure Overview](app/assets/img/structure.png)
## Specifications ## Specifications
* Built-in transpilers: [TypeScript](https://www.typescriptlang.org/), [Rescript](https://rescript-lang.org/), [CoffeeScript 2](https://coffeescript.org/), [LiveScript](https://livescript.net/) - Built-in transpilers: [TypeScript](https://www.typescriptlang.org/), [Rescript](https://rescript-lang.org/), [CoffeeScript 2](https://coffeescript.org/), [LiveScript](https://livescript.net/)
* **Ready to use on Windows machine immediately. No additional software installation is required.** - Ready to use on Windows machine immediately. No require additional software installation.
* **WelsonJS Launcher**: Manage instances (Like a container), User-defined variable editor, [Microsoft Monaco Editor](https://github.com/microsoft/monaco-editor) and [React](https://react.dev/) (Pre-embedded rich code editor), [Microsoft Copilot](https://copilot.microsoft.com), and [Azure AI Services](https://azure.microsoft.com/en-us/products/ai-services), Network tools (Whois, DNS Query, [Criminal IP CTI](https://www.criminalip.io/)) on the code editor. - ES5(ECMAScript 5), XML, JSON, YAML compatibility
* ES5(ECMAScript 5), XML, JSON, YAML compatibility: [core-js](https://github.com/zloirock/core-js), [JSON2.js](https://github.com/douglascrockford/JSON-js), [js-yaml](https://github.com/nodeca/js-yaml) - [github.com/zloirock/core-js](https://github.com/zloirock/core-js)
* HTML5 compatibility on the built-in HTML rendering engine: [html5shiv](https://github.com/aFarkas/html5shiv), [jquery-html5-placeholder-shim](https://github.com/parndt/jquery-html5-placeholder-shim), [Respond](https://github.com/scottjehl/Respond), [selectivizr](https://github.com/keithclark/selectivizr), [ExplorerCanvas](https://github.com/arv/ExplorerCanvas), [Modernizr](https://github.com/Modernizr/Modernizr) - [github.com/douglascrockford/JSON-js](https://github.com/douglascrockford/JSON-js) (aka. JSON2.js)
* Classical CSS Frameworks: [cascadeframework](https://github.com/jslegers/cascadeframework), [golden-layout](https://github.com/golden-layout/golden-layout) - [github.com/nodeca/js-yaml](https://github.com/nodeca/js-yaml)
* WYSIWYG HTML Editor: [summernote](https://github.com/summernote/summernote) - HTML5, CSS3 compatibility
* Included libraries: [jQuery](https://jquery.com/), [jQuery UI](https://jqueryui.com/), [jquery-toast-plugin](https://github.com/kamranahmedse/jquery-toast-plugin), [squel](https://github.com/hiddentao/squel), [jsrender](https://github.com/BorisMoore/jsrender), [linq](https://github.com/mihaifm/linq), [pegjs](https://github.com/pegjs/pegjs), [numbers.js](https://github.com/numbers/numbers.js) - [github.com/aFarkas/html5shiv](https://github.com/aFarkas/html5shiv)
* Compatible with modern JavaScript specifications: [module.exports](https://nodejs.org/api/modules.html#moduleexports), CommonJS, UMD compatibility, [NPM(Node Package Manager)](https://www.npmjs.com/) compatibility - [github.com/parndt/jquery-html5-placeholder-shim](https://github.com/parndt/jquery-html5-placeholder-shim)
* Support a device debugging protocol clients: [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/), [ADB(Android Debug Bridge)](https://source.android.com/docs/setup/build/adb) - [github.com/scottjehl/Respond](https://github.com/scottjehl/Respond)
* RPC(Remote Procedure Call) protocol clients: [gRPC](https://grpc.io/), [JSON-RPC 2.0](https://www.jsonrpc.org/specification) - [github.com/keithclark/selectivizr](https://github.com/keithclark/selectivizr)
* Various types of HTTP clients: [XHR(MSXML)](https://developer.mozilla.org/docs/Glossary/XMLHttpRequest), [cURL](https://curl.se/), [BITS](https://en.m.wikipedia.org/w/index.php?title=Background_Intelligent_Transfer_Service), [CERT](https://github.com/MicrosoftDocs/windowsserverdocs/blob/main/WindowsServerDocs/administration/windows-commands/certutil.md), [Web Proxy, SEO/SERP](https://catswords-oss.rdbl.io/5719744820/1706431912) - [github.com/arv/ExplorerCanvas](https://github.com/arv/ExplorerCanvas)
* The native toolkit for Windows environments: Write a Windows Service Application with JavaScript, Control a window handle, Cryptography (e.g., [ISO/IEC 18033-3:2010](https://www.iso.org/standard/54531.html) aka. [HIGHT](https://seed.kisa.or.kr/kisa/algorithm/EgovHightInfo.do)), [Named Shared Memory](https://learn.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory) based [IPC](https://qiita.com/gnh1201/items/4e70dccdb7adacf0ace5), [NuGet package](https://www.nuget.org/packages/WelsonJS.Toolkit) - [github.com/Modernizr/Modernizr](https://github.com/Modernizr/Modernizr)
* Generative AI integrations: [Multiple LLM and sLLM](https://catswords-oss.rdbl.io/5719744820/5510319392) (e.g., ChatGPT, Claude, ...) - Default CSS Framework
* Aviation Data integrations: [AviationStack](https://aviationstack.com?utm_source=FirstPromoter&utm_medium=Affiliate&fpr=namhyeon71), [SerpApi Google Flights API](https://serpapi.com/google-flights-api?utm_source=welsonjs) - [github.com/jslegers/cascadeframework](https://github.com/jslegers/cascadeframework)
* VM infrastructure tool integrations: [OVFTool for Broadcom/VMware infrastructures](https://developer.broadcom.com/tools/open-virtualization-format-ovf-tool/latest) - WYSIWYG HTML Editor
* ***:fire: NEW!*** Windows bulit-in database engine AKA. [ESENT (ESE) database](https://learn.microsoft.com/en-us/windows/win32/extensible-storage-engine/database-overview) interface library (WelsonJS.Esent) - [github.com/summernote/summernote](https://github.com/summernote/summernote)
* Everything you can imagine. - Included libraries
- [jQuery](https://jquery.com/)
- [jQuery UI](https://jqueryui.com/)
- [github.com/kamranahmedse/jquery-toast-plugin](https://github.com/kamranahmedse/jquery-toast-plugin)
- [github.com/hiddentao/squel](https://github.com/hiddentao/squel)
- [github.com/BorisMoore/jsrender](https://github.com/BorisMoore/jsrender) - Templating engine
- [github.com/mihaifm/linq](https://github.com/mihaifm/linq) - LINQ for JavaScript
- [Includes binaries](https://github.com/gnh1201/welsonjs/blob/master/bin/README.MD)
- [module.exports](https://nodejs.org/api/modules.html#moduleexports), CommonJS, UMD compatibility
- [NPM](https://www.npmjs.com/) compatibility
- [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/) support
- [ADB(Android Debug Bridge)](https://source.android.com/docs/setup/build/adb) support
- RPC(Remote Procedure Call) protocol support
- [gRPC](https://grpc.io/)
- [JSON-RPC 2.0](https://www.jsonrpc.org/specification)
## Quick start ## Included modules
- lib/std (Standard library)
- lib/system (System interface)
- lib/base64 (BASE64 encode and decode)
- lib/file (File I/O interface)
- lib/http (HTTP client with MSXML/cURL)
- lib/registry (Windows Registry interface)
- lib/security (Windows Security Policy interface)
- lib/shell (Windows Shell (Command Prompt) interface)
- lib/powershell (Windows Powershell interface)
- lib/service (Windows Service interface)
- lib/browser (Modern web compatibility layer)
- lib/uri (URI scheme interface)
- lib/winlibs (Windows DLL(Dynamic-link library) interface)
- lib/autohotkey ([AutoHotkey](https://www.autohotkey.com/) interface)
- lib/autoit ([AutoIt3/AutoItX](https://www.autoitscript.com/) interface)
- lib/msoffice (Microsoft Office (e.g. Excel, PowerPoint, Word) interface)
- lib/gtk (GTK-server and GladeXML supported GUI interface)
- lib/chrome ([Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/) based Chrome/Chromium web browser testing interface)
- lib/pipe-ipc (PIPE-based IPC(Inter-Process Communication) implementation)
- lib/toolkit (`WelsonJS.Toolkit` native component)
- Find and attach a handle of the window
- alert(), prompt() implementation in console mode
- Virtualized Human Interfaces
- Cryptography
- [Named Shared Memory](https://learn.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory) based IPC(Inter-Process Communication) implementation [#](https://qiita.com/gnh1201/items/4e70dccdb7adacf0ace5)
- Can be write Windows Services application with JavaScript! (`WelsonJS.Service` component)
- lib/chatgpt ([ChatGPT](https://openai.com/chatgpt) integration)
- Everything you can imagine.
## Make your own `sayhello` example
### 1. Write a file `lib/sayhello.js` ### 1. Write a file `lib/sayhello.js`
```js ```js
@ -91,8 +91,8 @@ function say() {
exports.say = say; exports.say = say;
exports.VERSIONINFO = "SayHello (sayhello.js) version 0.1"; exports.VERSIONINFO = "SayHello Library (sayhello.js) version 0.1";
exports.AUTHOR = "gnh1201@catswords.re.kr"; exports.AUTHOR = "abuse@catswords.net"; // e.g. YOUR EMAIL ADDRESS
exports.global = global; exports.global = global;
exports.require = global.require; exports.require = global.require;
``` ```
@ -111,74 +111,57 @@ function main() {
exports.main = main; exports.main = main;
``` ```
### 3. Execute script on the console ### 3. Execute file on the command prompt
```cmd ```cmd
C:\Users\JohnDoe\Documents\GitHub\welsonjs> cscript app.js sayhello C:\Users\oss\Documents\GitHub\welsonjs> cscript app.js sayhello
calling say() calling say()
hello hello
ended say() ended say()
``` ```
## How to release my application? ## How to make your own setup file
The WelsonJS framework suggests the following application release methods: - Please check `setup.iss` file it could be compile with [Inno Setup](https://jrsoftware.org/isinfo.php)
* **Compress to Zip, and use the launcher**: Compress the files and directories necessary for running the project into a Zip file, and distribute it along with the [WelsonJS Launcher](https://catswords-oss.rdbl.io/5719744820/4131485779).
* **Build a setup file**: Use [Inno Setup](https://jrsoftware.org/isinfo.php). The setup profile (the `setup.iss` file) is already included.
* **Copy all directories and files**: This is the simplest and most straightforward method.
## Screenshots ## Screenshots
![(Screenshot 1) GUI environment](https://ics.catswords.net/screenshot.png) ![(Screenshot 1) GUI environment](app/assets/img/screenshot.png)
![(Screenshot 2) Command-line environment](https://ics.catswords.net/screenshot2.png) ![(Screenshot 2) Command-line environment](app/assets/img/screenshot2.png)
![(Screenshot 3) WelsonJS with Microsoft Excel](https://ics.catswords.net/screenshot3.png) ![(Screenshot 3) WelsonJS with Microsoft Excel](app/assets/img/screenshot3.png)
![(Screenshot 4) Write a Windows Services with JavaScript](https://ics.catswords.net/screenshot4.png) ![(Screenshot 4) Write a Windows Services with JavaScript](app/assets/img/screenshot4.png)
![(Screenshot 5) Template Matching on the computer screen](https://ics.catswords.net/screenshot5.png)
![(Screenshot 6) The Launcher for WelsonJS Application Packages](https://ics.catswords.net/screenshot6.png)
![(Screenshot 7) Microsoft Monaco Editor on WelsonJS Launcher](https://ics.catswords.net/screenshot7.png)
## Thanks to ## Thanks to
* :heart: Artwork (Logo image): [@druidesse](https://github.com/druidesse) - <img src="app/assets/img/logo_oss.gif" height="30" alt=""/> Open Software Portal, Korea National Industry Promotion Agency - Awarded Prize
* :heart: Artwork (Cover image): [@_bag0@x.com](https://x.com/_bag0) - Heavy-industry specialized CSP(Cloud Service Provider) in Republic of Korea - Use case establishment
* :heart: Special Contributors: [@hcho3](https://github.com/hcho3), :octocat: [GitHub Sponsors](https://github.com/sponsors/gnh1201) - Live-commerce specialized online advertisement companies in Republic of Korea - Use case establishment
* :sunglasses: Heavy-industry specialized CSP(Cloud Service Provider) in Republic of Korea - Use case establishment - Information security companies in Republic of Korea - Use case establishment
* :sunglasses: Live-commerce specialized online advertisement companies in Republic of Korea - Use case establishment - <img src="app/assets/img/morioh.svg" height="30" alt=""/> morioh.com - Mentioned
* :sunglasses: Information security companies in Republic of Korea - Use case establishment - <img src="app/assets/img/CSDN_Logo.svg" height="30" alt=""/> CSDN - Mentioned
* :eyes: [Facebook Group "Javascript Programming"(javascript4u)](https://www.facebook.com/javascript4u/posts/build-a-windows-desktop-apps-with-javascript-html-and-cssmorioh-javascript-html-/1484014618472735/) - <img src="app/assets/img/qiita-logo.png" height="30" alt=""/> Qiita - Knowledge-base about WSH environment
* :eyes: [morioh.com](https://morioh.com/a/23c427a82bf1/build-a-windows-desktop-apps-with-javascript-html-and-css) - <img src="app/assets/img/RedSky-logo-web.webp" height="30" alt=""/> Redsky Software - PoC(Proof of Concept) of the CommonJS on WSH environment
* :eyes: CSDN - Inspired by a small-sized JavaScript payload demonstrated by a cybersecurity related group.
* :eyes: Qiita - Knowledge-base about WSH environment - Inspired by the use of Named Shared Memory in an inter-language IPC implementation devised by an unidentified developer.
* :sunglasses: Redsky Software - PoC(Proof of Concept) of the CommonJS on WSH environment - <img src="app/assets/img/Fediverse_logo_proposal.svg" height="30" alt=""/> Fediverse - Mentioned
* :sunglasses: Inspired by a small-sized JavaScript payload demonstrated by a cybersecurity related group. - [GitHub Sponsors](https://github.com/sponsors/gnh1201)
* :sunglasses: Inspired by the use of Named Shared Memory in a cross-runtime IPC implementation written by the unidentified developer.
* :eyes: Fediverse ## Related projects
* :eyes: [Hacker News](https://news.ycombinator.com/item?id=41316782) - [gnh1201/wsh-js-gtk](https://github.com/gnh1201/wsh-js-gtk) - GTK GUI ported to Windows Scripting Host - Javascript (Microsoft JScript) (wsh-js)
* :eyes: [WebToolsWeekly](https://webtoolsweekly.com/archives/issue-585/) - [gnh1201/wsh-json](https://github.com/gnh1201/wsh-json) - JSON stringify/parse (encode/decode) for Windows Scripting Host
* :eyes: [GeekNews](https://news.hada.io/weekly/202441) in GeekNews Weekly (2024-09-30 ~ 2024-10-06) - [redskyit/wsh-appjs](https://github.com/redskyit/wsh-appjs) - require-js and app framework for Windows Scripting Host JavaScript
* :eyes: [daily.dev](https://app.daily.dev/posts/js-libraries-svg-tools-json-databases-8quregz3a) - [JohnLaTwC's gist](https://gist.github.com/JohnLaTwC/4315bbbd89da0996f5c08c032b391799) - JavaScript RAT
* :eyes: [PitchHut](https://www.pitchhut.com/project/proj_Ya136OLSW5at) - [JSMan-/JS-Framework](https://github.com/JSMan-/JS-Framework) - No description
* :eyes: [Disquiet](https://dis.qa/nv6T6) - [iconjack/setTimeout-for-windows-script-host](https://github.com/iconjack/setTimeout-for-windows-script-host) - Replacement for the missing setTimeout and clearTimeout function in Windows Script Host
* :eyes: [Node Weekly](https://nodeweekly.com/issues/582) - [johnjohnsp1/WindowsScriptHostExtension](https://github.com/johnjohnsp1/WindowsScriptHostExtension) - Inject DLL Prototype using Microsoft.Windows.ACTCTX COM Object
- [kuntashov/jsunit](https://github.com/kuntashov/jsunit) - JSUnit port for Windows Scripting Host
- [nickdoth/WSHHttpServer](https://github.com/nickdoth/WSHHttpServer) - HTTP server based on Windows Script Host
- FOSSA report [HTML](https://pub-f926e14287b340cd9eff33731bb25329.r2.dev/fossa_report.html) [CSV](https://pub-f926e14287b340cd9eff33731bb25329.r2.dev/fossa_report.csv) [TXT](https://pub-f926e14287b340cd9eff33731bb25329.r2.dev/fossa_report.txt)
- [License attributions of a stock images](https://policy.catswords.social/stock_images.html)
## Report abuse ## Report abuse
* [GitHub Security Advisories (gnh1201/welsonjs)](https://github.com/gnh1201/welsonjs/security) - abuse@catswords.net
* [abuse@catswords.net](mailto:abuse@catswords.net) - ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
- [Join Catswords on Microsoft Teams](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
## Join the community
I am always open. Collaboration, opportunities, and community activities are all welcome.
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
* XMPP [catswords@conference.omemo.id](xmpp:catswords@conference.omemo.id?join)
* [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
* [Join Catswords OSS #welsonjs on Discord (discord.gg)](https://discord.gg/XKG5CjtXEj)
## Special channels
* [A paid consultation channel (m.expert.naver.com)](https://m.expert.naver.com/mobile/expert/product/detail?storeId=100051156&productId=100144540) is available for Korean<sup>(한국어)</sup> region.
* [Join the private operations channel (forms.gle)](https://forms.gle/ZKAAaGTiGamksHoo8) is available for all regions.
## License ## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs?ref=badge_large) [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs?ref=badge_large)

View File

@ -1,21 +1,18 @@
# Security Note for WelsonJS # Security Note for WelsonJS
## License
The WelsonJS project is available under either the GPLv3 or MS-RL opensource licenses. If the GPLv3 license is not compatible with Microsoft products, the MS-RL license applies; otherwise, the GPLv3 license is used. Under these licenses, if you distribute modified versions of this project's source code to third parties, you may be required to disclose the source code. For more details, please refer to the `LICENSE` and `LICENSE_MSRL` files.
## Caution ## Caution
This repository contains information on accessing Windows APIs and functions in the JavaScript runtime, along with recent case studies. While this can provide a flexible development environment for anyone, it can also be misused for malicious purposes. Please be aware that using this project to create abuse tools, such as for DoS attacks, may result in legal consequences in your country. We encourage you to use this project only for creating web technology-based applications, like Electron, or legally permitted testing tools. This repository contains information on accessing Windows APIs and functions on the JavaScript runtime, along with recent case studies. While this can provide a flexible development environment for anyone, it can also be misused for malicious purposes. Please be aware that using this project to create abuse tools, such as a DoS attack, may result in legal punishment in your country. We encourage you to use this project only for creating web technology-based applications, like Electron, or legally permitted testing tools.
## Known Use Cases ## Known use cases
WelsonJS is typically used for the following purposes: WelsonJS is typically used for the following purposes:
* Testing web accessibility and compliance, including adherence to W3C standards (WEB-ARIA, WCAG), national laws (ADA/DDA, GDPR), and other relevant regulations. * Testing web accessibility and compliance, including adherence to W3C standards (WEB-ARIA, WCAG), national laws (ADA/DDA, GDPR), and other relevant regulations.
* Exploring vulnerabilities of equipment within the local network. * Exploring vulnerabilities of equipment within the local network.
* Improving the availability of VPN or proxy clients. * Improving the availability of VPN or Proxy clients.
* Building automation, CI/CD (Continuous Integration/Continuous Delivery), DevOps, and SecOps. * Building automation, CD/CI (Continuous Integration/Continuous Delivery), DevOps, and SecOps.
* Asset evaluation (e.g., obtaining purchase history from online shopping and delivery websites). * Asset evaluation (e.g. Get a purchase history from online shopping and delivery websites)
* Online video streaming quality testing and improvement. * Online video streaming quality testing and improvement.
* Office automation and integration with LLM-based AI (e.g., ChatGPT) services. * Office automation and integration with LLM based AI(e.g., ChatGPT) services.
## Notes ## Notes
1. If you plan to use WelsonJS for a purpose other than those mentioned above, please contact us beforehand. 1. If you plan to use WelsonJS for a purpose other than those mentioned above, please contact us beforehand.
@ -23,41 +20,29 @@ WelsonJS is typically used for the following purposes:
## Guidelines ## Guidelines
### Use of Online Shopping and Delivery Websites ### For the use of online shopping and delivery websites
We are aware of cases where WelsonJS has been used to access the websites of online shopping or delivery companies for asset valuation. This is a good use case, but there have been reports of website downtime caused by excessive concurrent requests. Please exercise caution and avoid excessive simultaneous executions. We are aware of cases where WelsonJS has been used for asset valuation to access websites of online shopping or delivery companies. This is a good use case, but there have been reports of website downtime caused by excessive concurrent requests. Please exercise caution and avoid excessive simultaneous executions.
### Use for Online Video Streaming Quality Testing and Improvement ### For the use of online video streaming quality testing and improvement
We are aware of cases where WelsonJS is used for video streaming quality testing and improvement. It should be used solely for expert-level streaming quality testing, often referred to by terms like 4K, 8K, HD, FHD, UHD, 720p, 1080p, etc. For such purposes, it is recommended to use videos provided by television manufacturers (e.g., LG, Samsung) or graphics card manufacturers (e.g., NVIDIA, AMD) specifically for testing purposes. It is essential to avoid using videos that contain content not legally permitted in your region. The WelsonJS developers and maintainers take no responsibility for the use of videos containing illegal content. We are aware of cases where WelsonJS is used for the purpose of video streaming quality testing and improvement. It should be used solely for expert-level streaming quality testing, often referred to by terms like 4K, 8K, HD, FHD, UHD, 720p, 1080p, etc. For such purposes, it is recommended to use videos provided by television manufacturers (e.g., LG, Samsung) or graphics card manufacturers (e.g., NVIDIA, AMD) specifically for testing purposes. It is essential to avoid using videos that contain content not legally permitted in the region. The WelsonJS developers and maintainers take no responsibility for the use of videos containing illegal content.
### Use for Scientific Research Institutes ### For the use of security testing
WelsonJS is designed for flexible industrial facility control (a.k.a. Industrial Scripting) in environments where modifying compiled binaries is restricted. Parts or all of this project's source code may be found in use within scientific research institutes. In such cases, appropriate safety measures tailored to the specific application area may be required. If support is needed for these applications, please do not hesitate to contact us.
### Use for Security Testing
We are aware of instances where WelsonJS has been used by legitimate cybersecurity firms to discover and test vulnerabilities (such as credential stuffing) in IoT devices. If you intend to use WelsonJS as a security testing tool, it should be done in a controlled environment that complies with legal regulations. We are aware of instances where WelsonJS has been used by legitimate cybersecurity firms to discover and test vulnerabilities (such as credential stuffing) in IoT devices. If you intend to use WelsonJS as a security testing tool, it should be done in a controlled environment that complies with legal regulations.
### Use for Cloud Monitoring ### For the use of cloud monitoring
WelsonJS is a project inspired by the requirements of a cloud service provider to develop lightweight software (e.g., agents) for collecting metrics on Windows systems. While using WelsonJS for this purpose is desirable, ensuring security in the server-client communication is entirely the responsibility of the user. WelsonJS is a project initiated by a cloud service provider in response to a request to develop a lightweight software (e.g., agent) for collecting metrics on Windows systems. While using WelsonJS for this purpose is desirable, ensuring security in the server-client communication is entirely the responsibility of the user.
## Alternative Names ## Alternative names
This program is also known by the following names. These names are used solely for the purpose of identifying the work and do not impact the license: This program is also known by the following name. This name is used solely for the purpose of identifying the work and does not impact the license:
* DOI [10.5281/zenodo.11382384](https://zenodo.org/doi/10.5281/zenodo.11382384)(2024) (CERN/OpenAIRE Zenodo) - DOI [10.5281/zenodo.11382384](https://zenodo.org/doi/10.5281/zenodo.11382384)
* ["284757291"](https://ics.catswords.net/1494315-Certificate%2BSoR-284757291.pdf)(2024) (Registered with the [UK Copyright Service](https://copyrightservice.co.uk/)) - "A0562"(2023) (2023 Open-source Development Contest, NIPA National IT Industry Promotion Agency, Republic of Korea)
* ["A0562"](https://www.oss.kr/dev_competition_activities/show/544723e6-850a-4956-9194-79640420c19a)(2023) (2023 Open-source Development Contest, NIPA National IT Industry Promotion Agency<sup>(정보통신산업진흥원)</sup>, Republic of Korea) - "C-2021-000237"(2021) (Copyright Registration Online System, Korea Copyright Commission, Republic of Korea)
* ["2025-02-08-1952"](https://ics.catswords.net/20250410092300005.pdf)(2025) (Technical Data Bailment System (Technology Escrow), "Korea Foundation for Cooperation of Large & Small Business, Rural Affairs"<sup>(대·중소기업·농어업협력재단)</sup>, Republic of Korea) - "Codename Macadamia"(2020) (Heavy industry specialized CSP in the Republic of Korea)
* "C-2021-000237"(2021) (Copyright Registration Online System, Korea Copyright Commission<sup>(한국저작권위원회)</sup>, Republic of Korea)
* "Codename Macadamia"(2020) (Heavy industry specialized CSP in the Republic of Korea)
## Report abuse ## Report abuse
* [GitHub Security Advisories](https://github.com/gnh1201/welsonjs/security) If you discover any instances of this project being misused, please report them.
* [abuse@catswords.net](mailto:abuse@catswords.net)
## Join the community - abuse@catswords.net
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss) - ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
* XMPP [catswords@conference.omemo.id](xmpp:catswords@conference.omemo.id?join) - [Join Catswords on Microsoft Teams](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
* [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
* [Join Catswords OSS #welsonjs on Discord (discord.gg)](https://discord.gg/XKG5CjtXEj)
## Special channels
* [A paid consultation channel (m.expert.naver.com)](https://m.expert.naver.com/mobile/expert/product/detail?storeId=100051156&productId=100144540) is available for Korean<sup>(한국어)</sup> region.
* [Join the private operations channel (forms.gle)](https://forms.gle/ZKAAaGTiGamksHoo8) is available for all regions.

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ApiConstants.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Constants for the ESENT API. These don't have to be looked up via
/// system parameters.
/// </summary>
public static partial class SystemParameters
{
/// <summary>
/// The length of the prefix used to name files used by the database
/// engine.
/// </summary>
public const int BaseNameLength = 3;
/// <summary>
/// Maximum size of a table/column/index name.
/// </summary>
public const int NameMost = 64;
/// <summary>
/// Maximum size for columns which are not JET_coltyp.LongBinary
/// or JET_coltyp.LongText.
/// </summary>
public const int ColumnMost = 255;
/// <summary>
/// Maximum number of columns allowed in a table.
/// </summary>
public const int ColumnsMost = 65248;
/// <summary>
/// Maximum number of fixed columns allowed in a table.
/// </summary>
public const int ColumnsFixedMost = 127;
/// <summary>
/// Maximum number of variable-length columns allowed
/// in a table.
/// </summary>
public const int ColumnsVarMost = 128;
/// <summary>
/// Maximum number of tagged columns allowed in a table.
/// </summary>
public const int ColumnsTaggedMost = 64993;
/// <summary>
/// The number of pages that gives the smallest possible
/// temporary database.
/// </summary>
public const int PageTempDBSmallest = 14;
/// <summary>
/// The maximum length of a locale name (LOCALE_NAME_MAX_LENGTH from winnt.h).
/// </summary>
public const int LocaleNameMaxLength = 85;
}
}

View File

@ -1,96 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="BoolColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A <see cref="bool"/> column value.
/// </summary>
public class BoolColumnValue : ColumnValueOfStruct<bool>
{
/// <summary>
/// A boxed true value that can be used by ValueAsObject.
/// </summary>
private static readonly object BoxedTrue = true;
/// <summary>
/// A boxed false value that can be used by ValueAsObject.
/// </summary>
private static readonly object BoxedFalse = false;
/// <summary>
/// Gets the last set or retrieved value of the column. The
/// value is returned as a generic object.
/// </summary>
public override object ValueAsObject
{
get
{
if (!this.Value.HasValue)
{
return null;
}
return this.Value.Value ? BoxedTrue : BoxedFalse;
}
}
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(bool); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
byte data = this.Value.GetValueOrDefault() ? (byte)0xFF : (byte)0x00;
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(byte), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToBoolean(value, startIndex);
}
}
}
}

View File

@ -1,51 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="BoxedValueCache.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// A cache for boxed values.
/// </summary>
/// <typeparam name="T">The type of object to cache.</typeparam>
internal static class BoxedValueCache<T> where T : struct, IEquatable<T>
{
/// <summary>
/// Number of boxed values to cache.
/// </summary>
private const int NumCachedBoxedValues = 257;
/// <summary>
/// Cached boxed values.
/// </summary>
private static readonly object[] BoxedValues = new object[NumCachedBoxedValues];
/// <summary>
/// Gets a boxed version of the value. A cached copy is used if possible.
/// </summary>
/// <param name="value">The value to box.</param>
/// <returns>A boxed version of the value.</returns>
public static object GetBoxedValue(T? value)
{
if (!value.HasValue)
{
return null;
}
T valueToBox = value.Value;
int index = (valueToBox.GetHashCode() & 0x7fffffff) % NumCachedBoxedValues;
object boxedValue = BoxedValues[index];
if (null == boxedValue || !((T)boxedValue).Equals(valueToBox))
{
boxedValue = valueToBox;
BoxedValues[index] = boxedValue;
}
return boxedValue;
}
}
}

View File

@ -1,68 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ByteColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Diagnostics;
/// <summary>
/// A <see cref="byte"/> column value.
/// </summary>
public class ByteColumnValue : ColumnValueOfStruct<byte>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(byte); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(byte), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = value[startIndex];
}
}
}
}

View File

@ -1,136 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="BytesColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A byte array column value.
/// </summary>
public class BytesColumnValue : ColumnValue
{
/// <summary>
/// Internal value.
/// </summary>
private byte[] internalValue;
/// <summary>
/// Gets the last set or retrieved value of the column. The
/// value is returned as a generic object.
/// </summary>
public override object ValueAsObject
{
[DebuggerStepThrough]
get { return this.Value; }
}
/// <summary>
/// Gets or sets the value of the column. Use <see cref="Api.SetColumns"/> to update a
/// record with the column value.
/// </summary>
public byte[] Value
{
get
{
return this.internalValue;
}
set
{
this.internalValue = value;
this.Error = value == null ? JET_wrn.ColumnNull : JET_wrn.Success;
}
}
/// <summary>
/// Gets the byte length of a column value, which is zero if column is null, otherwise
/// matches the actual length of the byte array.
/// </summary>
public override int Length
{
get { return this.Value != null ? this.Value.Length : 0; }
}
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return 0; }
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="BytesColumnValue"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="BytesColumnValue"/>.
/// </returns>
public override string ToString()
{
if (null == this.Value)
{
return string.Empty;
}
return BitConverter.ToString(this.Value, 0, Math.Min(this.Value.Length, 16));
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
if (null != this.Value)
{
fixed (void* buffer = this.Value)
{
return this.SetColumns(
sesid, tableid, columnValues, nativeColumns, i, buffer, this.Value.Length, true);
}
}
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, null, 0, false);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
var copiedValue = new byte[count];
Buffer.BlockCopy(value, startIndex, copiedValue, 0, count);
this.Value = copiedValue;
}
}
}
}

View File

@ -1,79 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Caches.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Diagnostics;
/// <summary>
/// Static class containing MemoryCaches for different ESENT buffers.
/// Use these to avoid memory allocations when the memory will be
/// used for a brief time.
/// </summary>
internal static class Caches
{
/// <summary>
/// The maximum key size that any version of ESENT can have for
/// any page size. This is also the maximum bookmark size.
/// </summary>
private const int KeyMostMost = 2000;
/// <summary>
/// Reserve 1 extra space for keys made with prefix or wildcard.
/// </summary>
private const int LimitKeyMostMost = KeyMostMost + 1;
/// <summary>
/// The maximum number of buffers we want in a cache.
/// </summary>
private const int MaxBuffers = 16;
/// <summary>
/// Cached buffers for columns.
/// </summary>
private static readonly MemoryCache TheColumnCache = new MemoryCache(128 * 1024, MaxBuffers);
/// <summary>
/// Cached buffers for keys and bookmarks.
/// </summary>
private static readonly MemoryCache TheBookmarkCache = new MemoryCache(LimitKeyMostMost, MaxBuffers);
/// <summary>
/// Cached buffers for keys and bookmarks.
/// </summary>
private static readonly MemoryCache TheSecondaryBookmarkCache = new MemoryCache(LimitKeyMostMost, MaxBuffers);
/// <summary>
/// Gets the cached buffers for columns.
/// </summary>
public static MemoryCache ColumnCache
{
[DebuggerStepThrough]
get { return TheColumnCache; }
}
/// <summary>
/// Gets the cached buffers for keys and bookmarks.
/// </summary>
public static MemoryCache BookmarkCache
{
[DebuggerStepThrough]
get { return TheBookmarkCache; }
}
/// <summary>
/// Gets the cached buffers for keys and secondary bookmarks.
/// </summary>
public static MemoryCache SecondaryBookmarkCache
{
[DebuggerStepThrough]
get
{
return TheSecondaryBookmarkCache;
}
}
}
}

View File

@ -1,98 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="CallbackWrappers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Collections.Generic;
/// <summary>
/// <para>
/// A collection of wrapped callbacks. This is used when the wrapped callback
/// can be garbage collected. The wrappers should be removed from the collection
/// when the callback is collected.
/// </para>
/// <para>
/// Removing the wrappers can lead to crashes. In this case we trust
/// the client code to keep its callback alive until ESENT doesn't need it any
/// more. Once the wrapped callback is garbage collected we allow the wrapper
/// to be collected as well. If ESENT subsequently uses the callback there will
/// be a crash.
/// </para>
/// <para>
/// The reason this is hard to deal with is that the lifetime of a JET_CALLBACK
/// isn't very clear. Table callbacks can stick around until the table meta-data
/// is purged, while a JetDefragment callback can be used until defrag ends. On
/// the other hand, keeping the callback wrapper alive indefinitely would lead
/// to unbounded memory use.
/// </para>
/// </summary>
internal sealed class CallbackWrappers
{
/// <summary>
/// Used to synchronize access to this object.
/// </summary>
private readonly object lockObject = new object();
/// <summary>
/// A list of the wrapped callbacks.
/// </summary>
private readonly List<JetCallbackWrapper> callbackWrappers = new List<JetCallbackWrapper>();
/// <summary>
/// Wrap a callback and returns its wrapper. If the callback is
/// already wrapped then the existing wrapper is returned.
/// </summary>
/// <param name="callback">The callback to add.</param>
/// <returns>The callback wrapper for the callback.</returns>
public JetCallbackWrapper Add(JET_CALLBACK callback)
{
lock (this.lockObject)
{
JetCallbackWrapper wrapper;
if (!this.TryFindWrapperFor(callback, out wrapper))
{
wrapper = new JetCallbackWrapper(callback);
this.callbackWrappers.Add(wrapper);
}
return wrapper;
}
}
/// <summary>
/// Go through the collection of callback wrappers and remove any dead callbacks.
/// </summary>
public void Collect()
{
lock (this.lockObject)
{
this.callbackWrappers.RemoveAll(wrapper => !wrapper.IsAlive);
}
}
/// <summary>
/// Look in the list of callback wrappers to see if there is already an entry for
/// this callback.
/// </summary>
/// <param name="callback">The callback to look for.</param>
/// <param name="wrapper">Returns the wrapper, if found.</param>
/// <returns>True if a wrapper was found, false otherwise.</returns>
private bool TryFindWrapperFor(JET_CALLBACK callback, out JetCallbackWrapper wrapper)
{
foreach (JetCallbackWrapper w in this.callbackWrappers)
{
if (w.IsWrapping(callback))
{
wrapper = w;
return true;
}
}
wrapper = null;
return false;
}
}
}

View File

@ -1,101 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ColumnInfo.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
/// <summary>
/// Information about one Esent column. This is not an interop
/// class, but is used by the meta-data helper methods.
/// </summary>
public sealed class ColumnInfo
{
/// <summary>
/// The default value of the column.
/// </summary>
private readonly ReadOnlyCollection<byte> defaultValue;
/// <summary>
/// Initializes a new instance of the ColumnInfo class.
/// </summary>
/// <param name="name">Name of the column.</param>
/// <param name="columnid">ID of the column.</param>
/// <param name="coltyp">Type of the column.</param>
/// <param name="cp">Codepage of the column.</param>
/// <param name="maxLength">Maximum length of the column.</param>
/// <param name="defaultValue">Column default value.</param>
/// <param name="grbit">Column option.</param>
internal ColumnInfo(
string name,
JET_COLUMNID columnid,
JET_coltyp coltyp,
JET_CP cp,
int maxLength,
byte[] defaultValue,
ColumndefGrbit grbit)
{
this.Name = name;
this.Columnid = columnid;
this.Coltyp = coltyp;
this.Cp = cp;
this.MaxLength = maxLength;
this.defaultValue = (null == defaultValue) ? null : new ReadOnlyCollection<byte>(defaultValue);
this.Grbit = grbit;
}
/// <summary>
/// Gets the name of the column.
/// </summary>
public string Name { get; private set; }
/// <summary>
/// Gets the ID of the column.
/// </summary>
public JET_COLUMNID Columnid { get; private set; }
/// <summary>
/// Gets the type of the column.
/// </summary>
public JET_coltyp Coltyp { get; private set; }
/// <summary>
/// Gets the code page of the column.
/// </summary>
public JET_CP Cp { get; private set; }
/// <summary>
/// Gets the maximum length of the column.
/// </summary>
public int MaxLength { get; private set; }
/// <summary>
/// Gets the default value of the column.
/// </summary>
public IList<byte> DefaultValue
{
get { return this.defaultValue; }
}
/// <summary>
/// Gets the column options.
/// </summary>
public ColumndefGrbit Grbit { get; private set; }
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="ColumnInfo"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="ColumnInfo"/>.
/// </returns>
public override string ToString()
{
return this.Name;
}
}
}

View File

@ -1,78 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ColumnInfoEnumerator.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Text;
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// Base class for enumerators that return ColumnInfo objects. Subclasses differ
/// by how they open the table.
/// </summary>
internal abstract class ColumnInfoEnumerator : TableEnumerator<ColumnInfo>
{
/// <summary>
/// Initializes a new instance of the <see cref="ColumnInfoEnumerator"/> class.
/// </summary>
/// <param name="sesid">
/// The session to use.
/// </param>
protected ColumnInfoEnumerator(JET_SESID sesid) : base(sesid)
{
}
/// <summary>
/// Gets or sets the columnlist used to retrieve data.
/// </summary>
protected JET_COLUMNLIST Columnlist { get; set; }
/// <summary>
/// Gets the entry the cursor is currently positioned on.
/// </summary>
/// <returns>The entry the cursor is currently positioned on.</returns>
protected override ColumnInfo GetCurrent()
{
return GetColumnInfoFromColumnlist(this.Sesid, this.Columnlist);
}
/// <summary>
/// Create a ColumnInfo object from the data in the current JET_COLUMNLIST entry.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="columnlist">The columnlist to take the data from.</param>
/// <returns>A ColumnInfo object containing the information from that record.</returns>
private static ColumnInfo GetColumnInfoFromColumnlist(JET_SESID sesid, JET_COLUMNLIST columnlist)
{
// As of Sep 2015, JetGetColumnInfoW is only called for Win8+. Even though Unicode should have
// worked in Win7, it wasn't reliable until Win8.
Encoding encodingOfTextColumns = EsentVersion.SupportsWindows8Features ? Encoding.Unicode : LibraryHelpers.EncodingASCII;
string name = Api.RetrieveColumnAsString(
sesid,
columnlist.tableid,
columnlist.columnidcolumnname,
encodingOfTextColumns,
RetrieveColumnGrbit.None);
name = StringCache.TryToIntern(name);
var columnidValue = (uint)Api.RetrieveColumnAsUInt32(sesid, columnlist.tableid, columnlist.columnidcolumnid);
var coltypValue = (uint)Api.RetrieveColumnAsUInt32(sesid, columnlist.tableid, columnlist.columnidcoltyp);
uint codepageValue = (ushort)Api.RetrieveColumnAsUInt16(sesid, columnlist.tableid, columnlist.columnidCp);
var maxLength = (uint)Api.RetrieveColumnAsUInt32(sesid, columnlist.tableid, columnlist.columnidcbMax);
byte[] defaultValue = Api.RetrieveColumn(sesid, columnlist.tableid, columnlist.columnidDefault);
var grbitValue = (uint)Api.RetrieveColumnAsUInt32(sesid, columnlist.tableid, columnlist.columnidgrbit);
return new ColumnInfo(
name,
new JET_COLUMNID { Value = columnidValue },
(JET_coltyp)coltypValue,
(JET_CP)codepageValue,
unchecked((int)maxLength),
defaultValue,
(ColumndefGrbit)grbitValue);
}
}
}

View File

@ -1,357 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ColumnStream.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
/// <summary>
/// This class provides a streaming interface to a long-value column
/// (i.e. a column of type <see cref="JET_coltyp.LongBinary"/> or
/// <see cref="JET_coltyp.LongText"/>).
/// </summary>
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules",
"SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
public class ColumnStream : Stream
{
/// <summary>
/// The size of the biggest long-value column ESENT supports.
/// </summary>
private const int MaxLongValueSize = 0x7fffffff;
/// <summary>
/// Session to use.
/// </summary>
private readonly JET_SESID sesid;
/// <summary>
/// Cursor to use.
/// </summary>
private readonly JET_TABLEID tableid;
/// <summary>
/// Columnid to use.
/// </summary>
private readonly JET_COLUMNID columnid;
/// <summary>
/// Current LV offset.
/// </summary>
private int ibLongValue;
/// <summary>
/// Initializes a new instance of the ColumnStream class.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to use.</param>
/// <param name="columnid">The columnid of the column to set/retrieve data from.</param>
public ColumnStream(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid)
{
// In some cases we rely on Int32 arithmetic overflow checking to catch
// errors, which assumes that a long-value can store Int32.MaxValue bytes.
Debug.Assert(MaxLongValueSize == int.MaxValue, "Expected maximum long value size to be Int32.MaxValue");
this.sesid = sesid;
this.tableid = tableid;
this.columnid = columnid;
this.Itag = 1;
}
/// <summary>
/// Gets or sets the itag of the column.
/// </summary>
public int Itag { get; set; }
/// <summary>
/// Gets a value indicating whether the stream supports reading.
/// </summary>
public override bool CanRead
{
[DebuggerStepThrough]
get { return true; }
}
/// <summary>
/// Gets a value indicating whether the stream supports writing.
/// </summary>
public override bool CanWrite
{
[DebuggerStepThrough]
get { return true; }
}
/// <summary>
/// Gets a value indicating whether the stream supports seeking.
/// </summary>
public override bool CanSeek
{
[DebuggerStepThrough]
get { return true; }
}
/// <summary>
/// Gets or sets the current position in the stream.
/// </summary>
public override long Position
{
[DebuggerStepThrough]
get
{
return this.ibLongValue;
}
set
{
if (value < 0 || value > MaxLongValueSize)
{
throw new ArgumentOutOfRangeException("value", value, "A long-value offset has to be between 0 and 0x7fffffff bytes");
}
this.ibLongValue = checked((int)value);
}
}
/// <summary>
/// Gets the current length of the stream.
/// </summary>
public override long Length
{
get
{
int size;
var retinfo = new JET_RETINFO { itagSequence = this.Itag, ibLongValue = 0 };
Api.JetRetrieveColumn(this.sesid, this.tableid, this.columnid, null, 0, out size, RetrieveGrbit, retinfo);
return size;
}
}
/// <summary>
/// Gets the options that should be used with JetRetrieveColumn.
/// </summary>
private static RetrieveColumnGrbit RetrieveGrbit
{
[DebuggerStepThrough]
get
{
// Always use the RetrieveCopy options. This makes the ColumnStream work
// well when setting a column. If we don't always use RetrieveCopy then
// things like seeking from the end of a column might not work properly.
return RetrieveColumnGrbit.RetrieveCopy;
}
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="ColumnStream"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="ColumnStream"/>.
/// </returns>
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "ColumnStream(0x{0:x}:{1})", this.columnid.Value, this.Itag);
}
/// <summary>
/// Flush the stream.
/// </summary>
public override void Flush()
{
// nothing is required
}
/// <summary>
/// Writes a sequence of bytes to the current stream and advances the current
/// position within this stream by the number of bytes written.
/// </summary>
/// <param name="buffer">The buffer to write from.</param>
/// <param name="offset">The offset in the buffer to write.</param>
/// <param name="count">The number of bytes to write.</param>
public override void Write(byte[] buffer, int offset, int count)
{
CheckBufferArguments(buffer, offset, count);
int length = checked((int)this.Length);
JET_SETINFO setinfo;
int newIbLongValue = checked(this.ibLongValue + count);
// If our current position is beyond the end of the LV extend
// the LV to the write point
if (this.ibLongValue > length)
{
setinfo = new JET_SETINFO { itagSequence = this.Itag };
Api.JetSetColumn(this.sesid, this.tableid, this.columnid, null, this.ibLongValue, SetColumnGrbit.SizeLV, setinfo);
length = this.ibLongValue;
}
SetColumnGrbit grbit;
if (this.ibLongValue == length)
{
grbit = SetColumnGrbit.AppendLV;
}
else if (newIbLongValue >= length)
{
grbit = SetColumnGrbit.OverwriteLV | SetColumnGrbit.SizeLV;
}
else
{
grbit = SetColumnGrbit.OverwriteLV;
}
setinfo = new JET_SETINFO { itagSequence = this.Itag, ibLongValue = this.ibLongValue };
Api.JetSetColumn(this.sesid, this.tableid, this.columnid, buffer, count, offset, grbit, setinfo);
checked
{
this.ibLongValue += count;
}
}
/// <summary>
/// Reads a sequence of bytes from the current stream and advances the
/// position within the stream by the number of bytes read.
/// </summary>
/// <param name="buffer">The buffer to read into.</param>
/// <param name="offset">The offset in the buffer to read into.</param>
/// <param name="count">The number of bytes to read.</param>
/// <returns>The number of bytes read into the buffer.</returns>
public override int Read(byte[] buffer, int offset, int count)
{
CheckBufferArguments(buffer, offset, count);
if (this.ibLongValue >= this.Length)
{
return 0;
}
int length;
var retinfo = new JET_RETINFO { itagSequence = this.Itag, ibLongValue = this.ibLongValue };
Api.JetRetrieveColumn(this.sesid, this.tableid, this.columnid, buffer, count, offset, out length, RetrieveGrbit, retinfo);
int bytesRead = Math.Min(length, count);
checked
{
this.ibLongValue += bytesRead;
}
return bytesRead;
}
/// <summary>
/// Sets the length of the stream.
/// </summary>
/// <param name="value">The desired length, in bytes.</param>
public override void SetLength(long value)
{
if (value > MaxLongValueSize || value < 0)
{
throw new ArgumentOutOfRangeException("value", value, "A LongValueStream cannot be longer than 0x7FFFFFF or less than 0 bytes");
}
if (value < this.Length && value > 0)
{
// BUG: Shrinking the column multiple times and then growing it can sometimes hit an unpleasant
// ESENT defect which causes a hang. To make sure we never have that problem we read out the data,
// and insert into a new long-value. This is not efficient.
var data = new byte[value];
var retinfo = new JET_RETINFO { itagSequence = this.Itag, ibLongValue = 0 };
int actualDataSize;
Api.JetRetrieveColumn(
this.sesid,
this.tableid,
this.columnid,
data,
data.Length,
out actualDataSize,
RetrieveGrbit,
retinfo);
var setinfo = new JET_SETINFO { itagSequence = this.Itag };
Api.JetSetColumn(this.sesid, this.tableid, this.columnid, data, data.Length, SetColumnGrbit.None, setinfo);
}
else
{
var setinfo = new JET_SETINFO { itagSequence = this.Itag };
SetColumnGrbit grbit = (0 == value) ? SetColumnGrbit.ZeroLength : SetColumnGrbit.SizeLV;
Api.JetSetColumn(this.sesid, this.tableid, this.columnid, null, checked((int)value), grbit, setinfo);
}
// Setting the length moves the offset back to the end of the data
if (this.ibLongValue > value)
{
this.ibLongValue = checked((int)value);
}
}
/// <summary>
/// Sets the position in the current stream.
/// </summary>
/// <param name="offset">Byte offset relative to the origin parameter.</param>
/// <param name="origin">A SeekOrigin indicating the reference point for the new position.</param>
/// <returns>The new position in the current stream.</returns>
public override long Seek(long offset, SeekOrigin origin)
{
long newOffset;
switch (origin)
{
case SeekOrigin.Begin:
newOffset = offset;
break;
case SeekOrigin.End:
newOffset = checked(this.Length + offset);
break;
case SeekOrigin.Current:
newOffset = checked(this.ibLongValue + offset);
break;
default:
throw new ArgumentOutOfRangeException("origin", origin, "Unknown origin");
}
if (newOffset < 0 || newOffset > MaxLongValueSize)
{
throw new ArgumentOutOfRangeException("offset", offset, "invalid offset/origin combination");
}
this.ibLongValue = checked((int)newOffset);
return this.ibLongValue;
}
/// <summary>
/// Check the buffer arguments given to Read/Write .
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <param name="offset">The offset in the buffer to read/write to.</param>
/// <param name="count">The number of bytes to read/write.</param>
private static void CheckBufferArguments(ICollection<byte> buffer, int offset, int count)
{
if (null == buffer)
{
throw new ArgumentNullException("buffer");
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException("offset", offset, "cannot be negative");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count", count, "cannot be negative");
}
if (checked(buffer.Count - offset) < count)
{
throw new ArgumentOutOfRangeException("count", count, "cannot be larger than the size of the buffer");
}
}
}
}

View File

@ -1,382 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
/// <summary>
/// Base class for objects that represent a column value to be set.
/// </summary>
public abstract partial class ColumnValue
{
/// <summary>
/// Internal grbit.
/// </summary>
private RetrieveColumnGrbit grbit;
/// <summary>
/// Initializes a new instance of the ColumnValue class.
/// </summary>
protected ColumnValue()
{
this.ItagSequence = 1;
}
/// <summary>
/// Gets or sets the columnid to be set or retrieved.
/// </summary>
public JET_COLUMNID Columnid { get; set; }
/// <summary>
/// Gets the last set or retrieved value of the column. The
/// value is returned as a generic object.
/// </summary>
public abstract object ValueAsObject { get; }
/// <summary>
/// Gets or sets column update options.
/// </summary>
public SetColumnGrbit SetGrbit { get; set; }
/// <summary>
/// Gets or sets column retrieval options.
/// </summary>
public RetrieveColumnGrbit RetrieveGrbit
{
get
{
return this.grbit;
}
set
{
this.ValidateRetrieveGrbit(value);
this.grbit = value;
}
}
/// <summary>
/// Gets or sets the column itag sequence.
/// </summary>
public int ItagSequence { get; set; }
/// <summary>
/// Gets the warning generated by retrieving or setting this column.
/// </summary>
public JET_wrn Error { get; internal set; }
/// <summary>
/// Gets the byte length of a column value, which is zero if column is null, otherwise
/// it matches the Size for fixed-size columns and represent the actual value byte
/// length for variable sized columns (i.e. binary and string). For strings the length
/// is determined in assumption two bytes per character.
/// </summary>
public abstract int Length { get; }
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected abstract int Size { get; }
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="ColumnValue"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="ColumnValue"/>.
/// </returns>
public abstract override string ToString();
/// <summary>
/// Recursive RetrieveColumns method for data pinning. This should pin a buffer and
/// call the inherited RetrieveColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to retrieve the columns from.
/// </param>
/// <param name="columnValues">
/// Column values to retrieve.
/// </param>
internal static void RetrieveColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues)
{
const int MaxColumnValues = 1024;
if (columnValues.Length > MaxColumnValues)
{
throw new ArgumentOutOfRangeException("columnValues", columnValues.Length, "Too many column values");
}
unsafe
{
byte[] buffer = null;
NATIVE_RETRIEVECOLUMN* nativeRetrievecolumns = stackalloc NATIVE_RETRIEVECOLUMN[columnValues.Length];
try
{
buffer = Caches.ColumnCache.Allocate();
Debug.Assert(MaxColumnValues * 16 < buffer.Length, "Maximum size of fixed columns could exceed buffer size");
fixed (byte* pinnedBuffer = buffer)
{
byte* currentBuffer = pinnedBuffer;
int numVariableLengthColumns = columnValues.Length;
// First the fixed-size columns
for (int i = 0; i < columnValues.Length; ++i)
{
if (0 != columnValues[i].Size)
{
columnValues[i].MakeNativeRetrieveColumn(ref nativeRetrievecolumns[i]);
nativeRetrievecolumns[i].pvData = new IntPtr(currentBuffer);
nativeRetrievecolumns[i].cbData = checked((uint)columnValues[i].Size);
currentBuffer += nativeRetrievecolumns[i].cbData;
Debug.Assert(currentBuffer <= pinnedBuffer + buffer.Length, "Moved past end of pinned buffer");
numVariableLengthColumns--;
}
}
// Now the variable-length columns
if (numVariableLengthColumns > 0)
{
int bufferUsed = checked((int)(currentBuffer - pinnedBuffer));
int bufferRemaining = checked(buffer.Length - bufferUsed);
int bufferPerColumn = bufferRemaining / numVariableLengthColumns;
Debug.Assert(bufferPerColumn > 0, "Not enough buffer left to retrieve variable length columns");
// Now the variable-size columns
for (int i = 0; i < columnValues.Length; ++i)
{
if (0 == columnValues[i].Size)
{
columnValues[i].MakeNativeRetrieveColumn(ref nativeRetrievecolumns[i]);
nativeRetrievecolumns[i].pvData = new IntPtr(currentBuffer);
nativeRetrievecolumns[i].cbData = checked((uint)bufferPerColumn);
currentBuffer += nativeRetrievecolumns[i].cbData;
Debug.Assert(currentBuffer <= pinnedBuffer + buffer.Length, "Moved past end of pinned buffer");
}
}
}
// Retrieve the columns
Api.Check(Api.Impl.JetRetrieveColumns(sesid, tableid, nativeRetrievecolumns, columnValues.Length));
// Propagate the warnings and output.
for (int i = 0; i < columnValues.Length; ++i)
{
columnValues[i].Error = (JET_wrn)nativeRetrievecolumns[i].err;
columnValues[i].ItagSequence = (int)nativeRetrievecolumns[i].itagSequence;
}
// Now parse out the columns that were retrieved successfully
for (int i = 0; i < columnValues.Length; ++i)
{
if (nativeRetrievecolumns[i].err != (int)JET_wrn.BufferTruncated)
{
byte* columnBuffer = (byte*)nativeRetrievecolumns[i].pvData;
int startIndex = checked((int)(columnBuffer - pinnedBuffer));
columnValues[i].GetValueFromBytes(
buffer,
startIndex,
checked((int)nativeRetrievecolumns[i].cbActual),
nativeRetrievecolumns[i].err);
}
}
}
// Finally retrieve the buffers where the columns weren't large enough.
RetrieveTruncatedBuffers(sesid, tableid, columnValues, nativeRetrievecolumns);
}
finally
{
if (buffer != null)
{
Caches.ColumnCache.Free(ref buffer);
}
}
}
}
/// <summary>
/// Recursive SetColumns method for data pinning. This should populate the buffer and
/// call the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal abstract unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i);
/// <summary>
/// Recursive SetColumns function used to pin data.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <param name="buffer">The buffer for this object.</param>
/// <param name="bufferSize">Size of the buffer for ths object.</param>
/// <param name="hasValue">True if this object is non null.</param>
/// <returns>An error code.</returns>
/// <remarks>
/// This is marked as internal because it uses the NATIVE_SETCOLUMN type
/// which is also marked as internal. It should be treated as a protected
/// method though.
/// </remarks>
internal unsafe int SetColumns(
JET_SESID sesid,
JET_TABLEID tableid,
ColumnValue[] columnValues,
NATIVE_SETCOLUMN* nativeColumns,
int i,
void* buffer,
int bufferSize,
bool hasValue)
{
Debug.Assert(this == columnValues[i], "SetColumns should be called on the current object");
this.MakeNativeSetColumn(ref nativeColumns[i]);
if (hasValue)
{
nativeColumns[i].cbData = checked((uint)bufferSize);
nativeColumns[i].pvData = new IntPtr(buffer);
if (0 == bufferSize)
{
nativeColumns[i].grbit |= (uint)SetColumnGrbit.ZeroLength;
}
}
int err = i == columnValues.Length - 1
? Api.Impl.JetSetColumns(sesid, tableid, nativeColumns, columnValues.Length)
: columnValues[i + 1].SetColumns(sesid, tableid, columnValues, nativeColumns, i + 1);
this.Error = (JET_wrn)nativeColumns[i].err;
return err;
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected abstract void GetValueFromBytes(byte[] value, int startIndex, int count, int err);
/// <summary>
/// Validation for the requested retrieve options for the column.
/// </summary>
/// <param name="grbit">The retrieve options to validate.</param>
protected virtual void ValidateRetrieveGrbit(RetrieveColumnGrbit grbit)
{
// We cannot support this request when there is no way to indicate that a column reference is returned.
if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord
{
throw new EsentInvalidGrbitException();
}
}
/// <summary>
/// Retrieve the value for columns whose buffers were truncated.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to use.</param>
/// <param name="columnValues">The column values.</param>
/// <param name="nativeRetrievecolumns">
/// The native retrieve columns that match the column values.
/// </param>
private static unsafe void RetrieveTruncatedBuffers(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_RETRIEVECOLUMN* nativeRetrievecolumns)
{
for (int i = 0; i < columnValues.Length; ++i)
{
if (nativeRetrievecolumns[i].err == (int)JET_wrn.BufferTruncated)
{
var buffer = new byte[nativeRetrievecolumns[i].cbActual];
int actualSize;
int err;
var retinfo = new JET_RETINFO { itagSequence = columnValues[i].ItagSequence };
// Pin the buffer and retrieve the data
fixed (byte* pinnedBuffer = buffer)
{
err = Api.Impl.JetRetrieveColumn(
sesid,
tableid,
columnValues[i].Columnid,
new IntPtr(pinnedBuffer),
buffer.Length,
out actualSize,
columnValues[i].RetrieveGrbit,
retinfo);
}
if (JET_wrn.BufferTruncated == (JET_wrn)err)
{
string error = string.Format(
CultureInfo.CurrentCulture,
"Column size changed from {0} to {1}. The record was probably updated by another thread.",
buffer.Length,
actualSize);
Trace.TraceError(error);
throw new InvalidOperationException(error);
}
// Throw errors, but put warnings in the structure
Api.Check(err);
columnValues[i].Error = (JET_wrn)err;
// For BytesColumnValue this will copy the data to a new array.
// If this situation becomes common we should simply use the array.
columnValues[i].GetValueFromBytes(buffer, 0, actualSize, err);
}
}
}
/// <summary>
/// Create a native SetColumn from this object.
/// </summary>
/// <param name="setcolumn">The native setcolumn structure to fill in.</param>
private void MakeNativeSetColumn(ref NATIVE_SETCOLUMN setcolumn)
{
setcolumn.columnid = this.Columnid.Value;
setcolumn.grbit = (uint)this.SetGrbit;
setcolumn.itagSequence = checked((uint)this.ItagSequence);
}
/// <summary>
/// Create a native RetrieveColumn from this object.
/// </summary>
/// <param name="retrievecolumn">
/// The retrieve column structure to fill in.
/// </param>
private void MakeNativeRetrieveColumn(ref NATIVE_RETRIEVECOLUMN retrievecolumn)
{
retrievecolumn.columnid = this.Columnid.Value;
retrievecolumn.grbit = (uint)this.RetrieveGrbit;
retrievecolumn.itagSequence = checked((uint)this.ItagSequence);
}
}
}

View File

@ -1,82 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ColumnValueOfStruct.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// Set a column of a struct type (e.g. <see cref="Int32"/>/<see cref="Guid"/>).
/// </summary>
/// <typeparam name="T">Type to set.</typeparam>
public abstract class ColumnValueOfStruct<T> : ColumnValue where T : struct, IEquatable<T>
{
/// <summary>
/// Internal value.
/// </summary>
private T? internalValue;
/// <summary>
/// Gets the last set or retrieved value of the column. The
/// value is returned as a generic object.
/// </summary>
public override object ValueAsObject
{
get
{
return BoxedValueCache<T>.GetBoxedValue(this.Value);
}
}
/// <summary>
/// Gets or sets the value in the struct.
/// </summary>
public T? Value
{
get
{
return this.internalValue;
}
set
{
this.internalValue = value;
this.Error = value == null ? JET_wrn.ColumnNull : JET_wrn.Success;
}
}
/// <summary>
/// Gets the byte length of a column value, which is zero if column is null, otherwise
/// it matches the Size for this fixed-size column.
/// </summary>
public override int Length
{
get { return this.Value.HasValue ? this.Size : 0; }
}
/// <summary>
/// Gets a string representation of this object.
/// </summary>
/// <returns>A string representation of this object.</returns>
public override string ToString()
{
return this.Value.ToString();
}
/// <summary>
/// Make sure the retrieved data is exactly the size needed for
/// the structure. An exception is thrown if there is a mismatch.
/// </summary>
/// <param name="count">The size of the retrieved data.</param>
protected void CheckDataCount(int count)
{
if (this.Size != count)
{
throw new EsentInvalidColumnException();
}
}
}
}

View File

@ -1,175 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Conversions.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Globalization;
/// <summary>
/// Provide methods to convert data and flags between
/// Win32 and the .NET Framework.
/// </summary>
public static class Conversions
{
/// <summary>
/// Maps a CompareOption enumeration to the corresponding LCMapString flag.
/// </summary>
private static readonly IDictionary<CompareOptions, uint> CompareOptionsToLcmapFlags;
/// <summary>
/// Maps an LCMapString flag to the corresponding CompareOption enumeration.
/// </summary>
private static readonly IDictionary<uint, CompareOptions> LcmapFlagsToCompareOptions;
/// <summary>
/// Initializes static members of the Conversions class. This sets up the
/// conversion mapping dictionaries.
/// </summary>
static Conversions()
{
// Rather than creating both dictionaries, define one as the inverse of the other.
CompareOptionsToLcmapFlags = new Dictionary<CompareOptions, uint>
{
{ CompareOptions.IgnoreCase, NativeMethods.NORM_IGNORECASE },
{ CompareOptions.IgnoreKanaType, NativeMethods.NORM_IGNOREKANATYPE },
{ CompareOptions.IgnoreNonSpace, NativeMethods.NORM_IGNORENONSPACE },
{ CompareOptions.IgnoreSymbols, NativeMethods.NORM_IGNORESYMBOLS },
{ CompareOptions.IgnoreWidth, NativeMethods.NORM_IGNOREWIDTH },
{ CompareOptions.StringSort, NativeMethods.SORT_STRINGSORT }
};
LcmapFlagsToCompareOptions = InvertDictionary(CompareOptionsToLcmapFlags);
}
/// <summary>
/// Convert a double (OA date time format) to a DateTime. Unlike DateTime.FromOADate
/// this doesn't throw exceptions.
/// </summary>
/// <param name="d">The double value.</param>
/// <returns>A DateTime.</returns>
public static DateTime ConvertDoubleToDateTime(double d)
{
try
{
return LibraryHelpers.FromOADate(d);
}
catch (ArgumentException)
{
// Not all double values are valid OADates. We deal with out-of-range values
// by returning either min or max
return d < 0 ? DateTime.MinValue : DateTime.MaxValue;
}
}
/// <summary>
/// Given flags for LCMapFlags, turn them into compare options. Unknown options
/// are ignored.
/// </summary>
/// <param name="lcmapFlags">LCMapString flags.</param>
/// <returns>CompareOptions describing the (known) flags.</returns>
[CLSCompliant(false)]
public static CompareOptions CompareOptionsFromLCMapFlags(uint lcmapFlags)
{
// This should be a template, but there isn't an elegant way to express than with C# generics
CompareOptions options = CompareOptions.None;
foreach (uint flag in LcmapFlagsToCompareOptions.Keys)
{
if (flag == (lcmapFlags & flag))
{
options |= LcmapFlagsToCompareOptions[flag];
}
}
return options;
}
/// <summary>
/// Give CompareOptions, turn them into flags from LCMapString. Unknown options are ignored.
/// </summary>
/// <param name="compareOptions">The options to convert.</param>
/// <returns>The LCMapString flags that match the compare options. Unsupported options are ignored.</returns>
[CLSCompliant(false)]
public static uint LCMapFlagsFromCompareOptions(CompareOptions compareOptions)
{
// This should be a template, but there isn't an elegant way to express than with C# generics
uint flags = 0;
foreach (CompareOptions option in CompareOptionsToLcmapFlags.Keys)
{
if (option == (compareOptions & option))
{
flags |= CompareOptionsToLcmapFlags[option];
}
}
return flags;
}
/// <summary>
/// Given a Key=>Value dictionary create an inverted dictionary that maps Value=>Key.
/// </summary>
/// <typeparam name="TValue">The new value type (the key of the current dictionary).</typeparam>
/// <typeparam name="TKey">The new key type (the value if the current dictionary).</typeparam>
/// <param name="dict">The dictionary to invert.</param>
/// <returns>An inverted dictionary.</returns>
private static IDictionary<TKey, TValue> InvertDictionary<TValue, TKey>(ICollection<KeyValuePair<TValue, TKey>> dict)
{
var invertedDict = new Dictionary<TKey, TValue>(dict.Count);
foreach (KeyValuePair<TValue, TKey> entry in dict)
{
invertedDict.Add(entry.Value, entry.Key);
}
return invertedDict;
}
/// <summary>
/// This class contains the unmanaged constants used in the conversion.
/// </summary>
internal static class NativeMethods
{
#region Win32 Constants
/// <summary>
/// Ignore case.
/// </summary>
public const uint NORM_IGNORECASE = 0x00000001;
/// <summary>
/// Ignore nonspacing chars.
/// </summary>
public const uint NORM_IGNORENONSPACE = 0x00000002;
/// <summary>
/// Ignore symbols.
/// </summary>
public const uint NORM_IGNORESYMBOLS = 0x00000004;
/// <summary>
/// Ignore kanatype.
/// </summary>
public const uint NORM_IGNOREKANATYPE = 0x00010000;
/// <summary>
/// Ignore width.
/// </summary>
public const uint NORM_IGNOREWIDTH = 0x00020000;
/// <summary>
/// Treat punctuation the same as symbols.
/// </summary>
public const uint SORT_STRINGSORT = 0x00001000;
/// <summary>
/// Produce a normalized wide-character sort key.
/// </summary>
public const uint LCMAP_SORTKEY = 0x00000400;
#endregion Win32 Constants
}
}
}

View File

@ -1,70 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="DateTimeColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A <see cref="Guid"/> column value.
/// </summary>
public class DateTimeColumnValue : ColumnValueOfStruct<DateTime>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(double); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault().ToOADate();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(double), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
double d = BitConverter.ToDouble(value, startIndex);
this.Value = Conversions.ConvertDoubleToDateTime(d);
}
}
}
}

View File

@ -1,69 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="DoubleColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A <see cref="double"/> column value.
/// </summary>
public class DoubleColumnValue : ColumnValueOfStruct<double>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(double); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(double), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToDouble(value, startIndex);
}
}
}
}

View File

@ -1,172 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DurableCommitCallback.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// Callback for JET_param JET_paramDurableCommitCallback.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Windows8
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
#if !MANAGEDESENT_ON_CORECLR
using System.Runtime.CompilerServices;
#endif
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// A class which wraps the callback dealing with durable commits.
/// </summary>
public class DurableCommitCallback : EsentResource
{
/// <summary>
/// API call tracing.
/// </summary>
private static readonly TraceSwitch TraceSwitch = new TraceSwitch("ESENT DurableCommitCallback", "Wrapper around unmanaged ESENT durable commit callback");
/// <summary>
/// Instance associated with this callback.
/// </summary>
private JET_INSTANCE instance;
/// <summary>
/// Hold a reference to the delegate so that it doesn't get garbage-collected.
/// </summary>
private JET_PFNDURABLECOMMITCALLBACK wrappedCallback;
/// <summary>
/// Hold a reference to the delegate so that it doesn't get garbage-collected.
/// </summary>
[SuppressMessage("Exchange.Performance", "EX0023:DeadVariableDetector", Justification = "Need to hold on to a reference to the callback, so that it does not get garbage collected.")]
private NATIVE_JET_PFNDURABLECOMMITCALLBACK wrapperCallback;
/// <summary>
/// Initializes a new instance of the <see cref="DurableCommitCallback"/> class.
/// The constructor.
/// </summary>
/// <param name="instance">
/// The instance with which to associate the callback.
/// </param>
/// <param name="wrappedCallback">
/// The managed code callback to call.
/// </param>
public DurableCommitCallback(
JET_INSTANCE instance,
JET_PFNDURABLECOMMITCALLBACK wrappedCallback)
{
this.instance = instance;
this.wrappedCallback = wrappedCallback;
this.wrapperCallback = this.NativeDurableCommitCallback;
#if !MANAGEDESENT_ON_WSA // RuntimeHelpers works differently in Windows Store Apps.
if (this.wrappedCallback != null)
{
RuntimeHelpers.PrepareMethod(this.wrappedCallback.Method.MethodHandle);
}
RuntimeHelpers.PrepareMethod(typeof(DurableCommitCallback).GetMethod("NativeDurableCommitCallback", BindingFlags.NonPublic | BindingFlags.Instance).MethodHandle);
#endif
InstanceParameters instanceParameters = new InstanceParameters(this.instance);
// This might be null.
instanceParameters.SetDurableCommitCallback(this.wrapperCallback);
this.ResourceWasAllocated();
}
/// <summary>
/// Generate a string representation of the structure.
/// </summary>
/// <returns>The structure as a string.</returns>
public override string ToString()
{
return string.Format(
CultureInfo.InvariantCulture,
"DurableCommitCallback({0})",
this.instance.ToString());
}
/// <summary>
/// Terminate the durable commit session.
/// </summary>
public void End()
{
this.CheckObjectIsNotDisposed();
this.ReleaseResource();
}
/// <summary>
/// Free the durable commit session.
/// We do not try to set the instance parameter to null, since the callback is disposed after JetTerm and
/// the callback cannot be set after JetTerm.
/// </summary>
protected override void ReleaseResource()
{
this.instance = JET_INSTANCE.Nil;
this.wrappedCallback = null;
this.wrapperCallback = null;
this.ResourceWasReleased();
}
/// <summary>
/// The proxy callback function to call the user-defined managed delegate.
/// </summary>
/// <param name="instance">
/// The instance.
/// </param>
/// <param name="commitIdSeen">
/// The commit-id flushed.
/// </param>
/// <param name="grbit">
/// Reserved currently.
/// </param>
/// <returns>
/// An error code.
/// </returns>
private JET_err NativeDurableCommitCallback(
IntPtr instance,
ref NATIVE_COMMIT_ID commitIdSeen,
uint grbit)
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
JET_INSTANCE jetInstance = new JET_INSTANCE()
{
Value = instance
};
if (this.instance != jetInstance)
{
// We assume it's only called on one instance at a time. The only thing
// we really care about is serialization of the byte array.
//
// It would be nice to throw an error, but we're going back to real
// code, which doesn't deal with managed exceptions well.
return JET_err.CallbackFailed;
}
JET_COMMIT_ID commitId = new JET_COMMIT_ID(commitIdSeen);
return this.wrappedCallback(jetInstance, commitId, (DurableCommitCallbackGrbit)grbit);
}
catch (Exception ex)
{
Trace.WriteLineIf(
TraceSwitch.TraceWarning, string.Format(CultureInfo.InvariantCulture, "Caught Exception {0}", ex));
JetApi.ReportUnhandledException(ex, "Unhandled exception during NativeDurableCommitCallback");
// This should never be executed, but the compiler doesn't know it.
return JET_err.CallbackFailed;
}
}
}
}

View File

@ -1,121 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EnumeratedColumn.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Globalization;
/// <summary>
/// The values for a given column as generated by Api.EnumerateColumns.
/// </summary>
public class EnumeratedColumn
{
/// <summary>
/// Gets or sets the column ID of this set of column values.
/// </summary>
public JET_COLUMNID Id { get; set; }
/// <summary>
/// Gets or sets the status of this column id.
/// </summary>
/// <seealso cref="JET_err.Success"/>
/// <seealso cref="JET_err.BadColumnId"/>
/// <seealso cref="JET_err.ColumnNotFound"/>
public JET_err Error { get; set; }
/// <summary>
/// Gets or sets the status of this set of column values.
/// </summary>
/// <seealso cref="JET_wrn.Success"/>
/// <seealso cref="JET_wrn.ColumnDefault"/>
/// <seealso cref="JET_wrn.ColumnNull"/>
/// <seealso cref="JET_wrn.ColumnPresent"/>
/// <seealso cref="JET_wrn.ColumnSkipped"/>
public JET_wrn Warning { get; set; }
/// <summary>
/// Gets or sets the column values enumerated.
/// </summary>
/// <remarks>
/// This will be null if the column is null or the column values were not provided.
/// </remarks>
public Value[] Values { get; set; }
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="EnumeratedColumn"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="EnumeratedColumn"/>.
/// </returns>
public override string ToString()
{
return string.Format(
CultureInfo.InvariantCulture,
"EnumeratedColumn(0x{0:x}: {1} Values[{2}])",
this.Id,
this.Error != JET_err.Success ? this.Error.ToString() : this.Warning.ToString(),
this.Values.Length);
}
/// <summary>
/// A single column value.
/// </summary>
public class Value
{
/// <summary>
/// Gets or sets the ordinal of this column value.
/// </summary>
/// <remarks>
/// The lowest valid ordinal is one.
/// This is the same as the "itagSequence" of the column value.
/// </remarks>
public int Ordinal { get; set; }
/// <summary>
/// Gets or sets the status of this column value.
/// </summary>
/// <seealso cref="JET_wrn.Success"/>
/// <seealso cref="JET_wrn.ColumnDefault"/>
/// <seealso cref="JET_wrn.ColumnNotInRecord"/>
/// <seealso cref="JET_wrn.ColumnNull"/>
/// <seealso cref="JET_wrn.ColumnPresent"/>
/// <seealso cref="JET_wrn.ColumnSkipped"/>
/// <seealso cref="JET_wrn.ColumnTruncated"/>
public JET_wrn Warning { get; set; }
/// <summary>
/// Gets or sets the column value as bytes.
/// </summary>
/// <remarks>
/// This will be null if the column is null or the column values were not provided.
/// This will be truncated if Warning is <see cref="JET_wrn.ColumnTruncated"/>.
/// </remarks>
public byte[] Bytes { get; set; }
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="EnumeratedColumn.Value"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="EnumeratedColumn.Value"/>.
/// </returns>
public override string ToString()
{
const int MaxLength = 16;
return string.Format(
CultureInfo.InvariantCulture,
"EnumeratedColumn.Value({0}: {1} Bytes[{2}] = {3}{4}{5}{6})",
this.Ordinal,
this.Warning,
this.Bytes.Length,
'{',
BitConverter.ToString(this.Bytes, 0, Math.Min(this.Bytes.Length, MaxLength)),
this.Bytes.Length > MaxLength ? "..." : string.Empty,
'}');
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,351 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35122.118
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{18B3E50E-454E-49DB-A92F-E1D7DAD2AF7D}"
ProjectSection(SolutionItems) = preProject
CodeCoverage.testrunconfig = CodeCoverage.testrunconfig
esent.vsmdi = esent.vsmdi
Normal.testrunconfig = Normal.testrunconfig
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentInterop", "EsentInterop.csproj", "{E929E163-52A0-4AAC-917B-6D7FAF70C45E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbUtil", "..\EsentInteropSamples\DbUtil\DbUtil.csproj", "{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "isam", "..\isam\isam.csproj", "{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StockSample", "..\EsentInteropSamples\StockSample\StockSample.csproj", "{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentCollections", "..\EsentCollections\EsentCollections.csproj", "{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorld", "..\EsentCollectionsSamples\HelloWorld\HelloWorld.csproj", "{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RssDictionarySample", "..\EsentCollectionsSamples\RssDictionarySample\RssDictionarySample.csproj", "{134FBC80-2E23-451B-A6B3-72B0AA2234F9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentInteropTests", "..\EsentInteropTests\EsentInteropTests.csproj", "{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentCollectionsTests", "..\EsentCollectionsTests\EsentCollectionsTests.csproj", "{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IsamUnitTests", "..\isamunittests\IsamUnitTests.csproj", "{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbUtilTests", "..\EsentInteropSamples\DbUtilTests\DbUtilTests.csproj", "{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentSample", "..\EsentInteropSamples\EsentSample\EsentSample.csproj", "{44D46916-891F-435F-B914-AE8AC80613FD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicTest", "..\EsentInteropSamples\BasicTest\BasicTest.csproj", "{08819B49-02B8-4F93-A143-F9B0461CEA64}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UWPSample", "..\UWPSample\UWPSample.csproj", "{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|ARM.Build.0 = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|ARM64.Build.0 = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|x64.ActiveCfg = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|x64.Build.0 = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|x86.ActiveCfg = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|x86.Build.0 = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|Any CPU.Build.0 = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|ARM.ActiveCfg = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|ARM.Build.0 = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|ARM64.ActiveCfg = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|ARM64.Build.0 = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|x64.ActiveCfg = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|x64.Build.0 = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|x86.ActiveCfg = Release|x86
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|x86.Build.0 = Release|x86
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|ARM.Build.0 = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|ARM64.Build.0 = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|x64.ActiveCfg = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|x64.Build.0 = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|x86.ActiveCfg = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|x86.Build.0 = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|Any CPU.Build.0 = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|ARM.ActiveCfg = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|ARM.Build.0 = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|ARM64.ActiveCfg = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|ARM64.Build.0 = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|x64.ActiveCfg = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|x64.Build.0 = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|x86.ActiveCfg = Release|x86
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|x86.Build.0 = Release|x86
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|ARM.Build.0 = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|ARM64.Build.0 = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|x64.ActiveCfg = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|x64.Build.0 = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|x86.ActiveCfg = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|x86.Build.0 = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|Any CPU.Build.0 = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|ARM.ActiveCfg = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|ARM.Build.0 = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|ARM64.ActiveCfg = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|ARM64.Build.0 = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|x64.ActiveCfg = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|x64.Build.0 = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|x86.ActiveCfg = Release|x86
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|x86.Build.0 = Release|x86
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|ARM.Build.0 = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|ARM64.Build.0 = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|x64.ActiveCfg = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|x64.Build.0 = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|x86.ActiveCfg = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|x86.Build.0 = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|Any CPU.Build.0 = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|ARM.ActiveCfg = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|ARM.Build.0 = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|ARM64.ActiveCfg = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|ARM64.Build.0 = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|x64.ActiveCfg = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|x64.Build.0 = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|x86.ActiveCfg = Release|x86
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|x86.Build.0 = Release|x86
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|ARM.ActiveCfg = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|ARM.Build.0 = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|ARM64.Build.0 = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|x64.ActiveCfg = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|x64.Build.0 = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|x86.ActiveCfg = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|x86.Build.0 = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|Any CPU.Build.0 = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|ARM.ActiveCfg = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|ARM.Build.0 = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|ARM64.ActiveCfg = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|ARM64.Build.0 = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|x64.ActiveCfg = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|x64.Build.0 = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|x86.ActiveCfg = Release|x86
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|x86.Build.0 = Release|x86
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|ARM.Build.0 = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|ARM64.Build.0 = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|x64.ActiveCfg = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|x64.Build.0 = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|x86.ActiveCfg = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|x86.Build.0 = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|Any CPU.Build.0 = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|ARM.ActiveCfg = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|ARM.Build.0 = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|ARM64.ActiveCfg = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|ARM64.Build.0 = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|x64.ActiveCfg = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|x64.Build.0 = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|x86.ActiveCfg = Release|x86
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|x86.Build.0 = Release|x86
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|ARM.ActiveCfg = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|ARM.Build.0 = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|ARM64.Build.0 = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|x64.ActiveCfg = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|x64.Build.0 = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|x86.ActiveCfg = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|x86.Build.0 = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|Any CPU.Build.0 = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|ARM.ActiveCfg = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|ARM.Build.0 = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|ARM64.ActiveCfg = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|ARM64.Build.0 = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|x64.ActiveCfg = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|x64.Build.0 = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|x86.ActiveCfg = Release|x86
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|x86.Build.0 = Release|x86
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|ARM.Build.0 = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|ARM64.Build.0 = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|x64.ActiveCfg = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|x64.Build.0 = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|x86.ActiveCfg = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|x86.Build.0 = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|Any CPU.Build.0 = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|ARM.ActiveCfg = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|ARM.Build.0 = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|ARM64.ActiveCfg = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|ARM64.Build.0 = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|x64.ActiveCfg = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|x64.Build.0 = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|x86.ActiveCfg = Release|x86
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|x86.Build.0 = Release|x86
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|ARM.Build.0 = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|ARM64.Build.0 = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|x64.ActiveCfg = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|x64.Build.0 = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|x86.ActiveCfg = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|x86.Build.0 = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|Any CPU.Build.0 = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|ARM.ActiveCfg = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|ARM.Build.0 = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|ARM64.ActiveCfg = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|ARM64.Build.0 = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|x64.ActiveCfg = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|x64.Build.0 = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|x86.ActiveCfg = Release|x86
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|x86.Build.0 = Release|x86
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|ARM.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|ARM64.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|x64.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|x64.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|x86.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|x86.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|Any CPU.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|ARM.ActiveCfg = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|ARM.Build.0 = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|ARM64.ActiveCfg = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|ARM64.Build.0 = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|x64.ActiveCfg = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|x64.Build.0 = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|x86.ActiveCfg = Release|x86
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|x86.Build.0 = Release|x86
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|ARM.Build.0 = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|ARM64.Build.0 = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|x64.ActiveCfg = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|x64.Build.0 = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|x86.ActiveCfg = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|x86.Build.0 = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|Any CPU.Build.0 = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|ARM.ActiveCfg = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|ARM.Build.0 = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|ARM64.ActiveCfg = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|ARM64.Build.0 = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|x64.ActiveCfg = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|x64.Build.0 = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|x86.ActiveCfg = Release|x86
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|x86.Build.0 = Release|x86
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|ARM.ActiveCfg = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|ARM.Build.0 = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|ARM64.Build.0 = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|x64.ActiveCfg = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|x64.Build.0 = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|x86.ActiveCfg = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|x86.Build.0 = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|Any CPU.Build.0 = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|ARM.ActiveCfg = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|ARM.Build.0 = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|ARM64.ActiveCfg = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|ARM64.Build.0 = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|x64.ActiveCfg = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|x64.Build.0 = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|x86.ActiveCfg = Release|x86
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|x86.Build.0 = Release|x86
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|ARM.ActiveCfg = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|ARM.Build.0 = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|ARM64.Build.0 = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|x64.ActiveCfg = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|x64.Build.0 = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|x86.ActiveCfg = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|x86.Build.0 = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|Any CPU.Build.0 = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|ARM.ActiveCfg = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|ARM.Build.0 = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|ARM64.ActiveCfg = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|ARM64.Build.0 = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|x64.ActiveCfg = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|x64.Build.0 = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|x86.ActiveCfg = Release|x86
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|x86.Build.0 = Release|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|Any CPU.ActiveCfg = Debug|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM.ActiveCfg = Debug|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM.Build.0 = Debug|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM.Deploy.0 = Debug|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM64.ActiveCfg = Debug|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM64.Build.0 = Debug|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM64.Deploy.0 = Debug|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x64.ActiveCfg = Debug|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x64.Build.0 = Debug|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x64.Deploy.0 = Debug|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x86.ActiveCfg = Debug|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x86.Build.0 = Debug|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x86.Deploy.0 = Debug|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|Any CPU.ActiveCfg = Release|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM.ActiveCfg = Release|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM.Build.0 = Release|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM.Deploy.0 = Release|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM64.ActiveCfg = Release|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM64.Build.0 = Release|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM64.Deploy.0 = Release|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x64.ActiveCfg = Release|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x64.Build.0 = Release|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x64.Deploy.0 = Release|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x86.ActiveCfg = Release|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x86.Build.0 = Release|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6A6764EF-3A8F-46BF-8CC8-C07DE889160A}
EndGlobalSection
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = Esent.vsmdi
EndGlobalSection
EndGlobal

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
<RunConfiguration id="6c3d561f-b13d-4563-9e69-90f00c61747b" name="Normal" storage="normal.testrunconfig" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</TestList>
</TestLists>

View File

@ -1 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Properties><Property><Name>svn:mime-type</Name><Value>application/octet-stream</Value></Property></Properties></ItemProperties>

View File

@ -1,82 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="AssemblyInfo.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EsentInterop")]
[assembly: AssemblyDescription("Managed interop code for esent.dll")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("EsentInterop")]
[assembly: AssemblyCopyright("Copyright (c) Microsoft")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
//
// Version history:
// 1.6.0.0
// 1.7.0.0
// 1.8.0.0 Support new Windows user interface (As of Win8 Beta build).
// 1.8.1.0 2012.11.18. Some minor updates, including some perf updates.
// 1.8.2.0 2012.11.19. Signed.
// 1.8.3.0 2013.03.25. Signed and Strong Named. Renamed 'Metro' to 'Wsa' (Windows Store App)
// 1.8.4.0 2013.12.23. Updated for Windows 8.1.
// 1.9.0.0 2013.12.23. Go back to targetting framework 4.0.
// 1.9.1.0 2014.07.18. PersistentDictionary gets binary blobs; added Isam layer.
// 1.9.2.0 2014.09.11. Isam is placed in the Microsoft.Database namespace.
// 1.9.3.0 2015.08.11. Dependence added from Collections to Isam dll for configsets.
// 1.9.3.2 2015.09.02. Some bug fixes; go back to Framework 4.0
// 1.9.3.3 2016.03.01. Some bug and perf fixes.
// 1.9.4 2016.06.28. Some bug fixes.
// 1.9.4.1 2017.08.30. Adding JetGetIndexInfo that returns JET_INDEXCREATE.
[assembly: AssemblyVersion("1.9.4.1")]
[assembly: AssemblyFileVersion("1.9.4.1")]
#if STRONG_NAMED
[assembly: InternalsVisibleTo("EsentInteropWsaTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("Esent.Isam, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("InteropApiTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("IsamUnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("Pixie, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("PixieTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
// This assembly is generated by Rhino.Mocks
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2,PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
#else
[assembly: InternalsVisibleTo("InteropApiTests")]
[assembly: InternalsVisibleTo("IsamUnitTests")]
[assembly: InternalsVisibleTo("EsentInteropTestsImmersive")]
[assembly: InternalsVisibleTo("EsentInteropWsaTests")]
[assembly: InternalsVisibleTo("Esent.Isam")]
[assembly: InternalsVisibleTo("Pixie")]
[assembly: InternalsVisibleTo("PixieTests")]
// This assembly is generated by Rhino.Mocks
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
#endif

View File

@ -1,37 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="CallbackDataConverter.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// Methods to convert data objects used in callbacks.
/// </summary>
internal static class CallbackDataConverter
{
/// <summary>
/// Get the managed data object from the unmanaged data.
/// </summary>
/// <param name="nativeData">The native data.</param>
/// <param name="snp">The SNP (used to determine the type of object).</param>
/// <param name="snt">The SNT (used to determine the type of object).</param>
/// <returns>The managed data object.</returns>
public static object GetManagedData(IntPtr nativeData, JET_SNP snp, JET_SNT snt)
{
if (IntPtr.Zero != nativeData && JET_SNT.Progress == snt)
{
NATIVE_SNPROG native = (NATIVE_SNPROG)Marshal.PtrToStructure(nativeData, typeof(NATIVE_SNPROG));
JET_SNPROG managed = new JET_SNPROG();
managed.SetFromNative(native);
return managed;
}
return null;
}
}
}

View File

@ -1,263 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentImplementationStubs.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// Class stubs to allow compiling on CoreClr.
// </summary>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Implementation
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text;
/// <summary>
/// A fake class to allow compilation on platforms that lack this functionality.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
public class Trace
{
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="condition">
/// The condition.
/// </param>
/// <param name="message">
/// The message.
/// </param>
[ConditionalAttribute("TRACE")]
public static void WriteLineIf(bool condition, string message)
{
}
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="condition">
/// The condition.
/// </param>
/// <param name="message">
/// The message.
/// </param>
[ConditionalAttribute("TRACE")]
public static void WriteLineIf(bool condition, object message)
{
}
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// A fake class to allow compilation on platforms that lack this class.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
internal static class RuntimeHelpers
{
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
public static void PrepareConstrainedRegions()
{
}
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="method">
/// The method.
/// </param>
public static void PrepareMethod(RuntimeMethodHandle method)
{
}
}
/// <summary>
/// Ascii encoding is not available on Core Clr. But UTF-8 is.
/// This class will reject any character that results in an
/// extended value.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
internal class SlowAsciiEncoding : UTF8Encoding
{
/// <summary>
/// The standard encoding object.
/// </summary>
private static SlowAsciiEncoding slowAsciiEncoding = new SlowAsciiEncoding();
/// <summary>
/// Gets an Encoding object.
/// </summary>
public static Encoding Encoding
{
get
{
return slowAsciiEncoding;
}
}
#if !MANAGEDESENT_ON_WSA
/// <summary>
/// Converts a string to the byte representation.
/// </summary>
/// <param name="chars">
/// The chars.
/// </param>
/// <param name="charCount">
/// The char count.
/// </param>
/// <param name="bytes">
/// The bytes.
/// </param>
/// <param name="byteCount">
/// The byte count.
/// </param>
/// <returns>
/// A count of bytes stored.
/// </returns>
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
IntPtr toFree;
char* charsToTranslate = this.SanitizeString(chars, charCount, out toFree);
int toReturn = base.GetBytes(charsToTranslate, charCount, bytes, byteCount);
LibraryHelpers.MarshalFreeHGlobal(toFree);
return toReturn;
}
#endif
/// <summary>
/// Converts a string to the byte representation.
/// </summary>
/// <param name="inputString">
/// The input string.
/// </param>
/// <returns>
/// The byte representation of the string.
/// </returns>
public override byte[] GetBytes(string inputString)
{
string stringToTranslate = this.SanitizeString(inputString);
return base.GetBytes(stringToTranslate);
}
/// <summary>
/// Converts a string to the byte representation.
/// </summary>
/// <param name="inputString">
/// The input string.
/// </param>
/// <param name="charIndex">
/// The char index.
/// </param>
/// <param name="charCount">
/// The char count.
/// </param>
/// <param name="bytes">
/// The bytes.
/// </param>
/// <param name="byteIndex">
/// The byte index.
/// </param>
/// <returns>
/// The byte representation of the string.
/// </returns>
public override int GetBytes(string inputString, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
string stringToTranslate = this.SanitizeString(inputString);
return base.GetBytes(stringToTranslate, charIndex, charCount, bytes, byteIndex);
}
/// <summary>
/// Scans the string looking for unmappable characters in the ASCII set, and replaces
/// them with '?'.
/// </summary>
/// <param name="inputString">A unicode string with unknown characters.</param>
/// <returns>A string that has all legal ASCII characters.</returns>
private string SanitizeString(string inputString)
{
bool needToDuplicate = false;
string returnString = inputString;
foreach (char ch in inputString)
{
if (ch > 127)
{
needToDuplicate = true;
break;
}
}
if (needToDuplicate)
{
StringBuilder sb = new StringBuilder(inputString.Length);
foreach (char ch in inputString)
{
sb.Append(ch > 127 ? '?' : ch);
}
returnString = sb.ToString();
}
return returnString;
}
#if !MANAGEDESENT_ON_WSA
/// <summary>
/// Scans the string looking for unmappable characters in the ASCII set, and replaces
/// them with '?'.
/// </summary>
/// <param name="inputString">A unicode string with unknown characters.</param>
/// <param name="charCount">The length of the string to sanitize.</param>
/// <param name="allocedMemory">On output, a value that needs to be freed. Only used
/// if there are any untranslaable characters.</param>
/// <returns>A string that has all legal ASCII characters.</returns>
private unsafe char* SanitizeString(char* inputString, int charCount, out IntPtr allocedMemory)
{
allocedMemory = IntPtr.Zero;
bool needToDuplicate = false;
char* returnString = inputString;
for (int i = 0; i < charCount; ++i)
{
if (inputString[i] > 127)
{
needToDuplicate = true;
break;
}
}
if (needToDuplicate)
{
allocedMemory = LibraryHelpers.MarshalAllocHGlobal(charCount);
returnString = (char*)allocedMemory;
char* dest = returnString;
for (int i = 0; i < charCount; ++i)
{
dest[i] = inputString[i] > 127 ? '?' : inputString[i];
}
}
return returnString;
}
#endif
}
}

View File

@ -1,157 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentJetApi.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// JetApi code that is specific to ESENT.
// </summary>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Implementation
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Threading;
/// <summary>
/// JetApi code that is specific to ESENT.
/// </summary>
internal sealed partial class JetApi
{
/// <summary>
/// Reports the exception to a central authority.
/// </summary>
/// <param name="exception">An unhandled exception.</param>
/// <param name="description">A string description of the scenario.</param>
internal static void ReportUnhandledException(
Exception exception,
string description)
{
}
/// <summary>
/// Calculates the capabilities of the current Esent version.
/// </summary>
private void DetermineCapabilities()
{
const int Server2003BuildNumber = 2700;
const int VistaBuildNumber = 6000;
const int Windows7BuildNumber = 7000; // includes beta as well as RTM (RTM is 7600)
const int Windows8BuildNumber = 8000; // includes beta as well as RTM (RTM is 9200)
const int Windows81BuildNumber = 9300; // includes beta as well as RTM (RTM is 9600)
const int Windows10BuildNumber = 9900; // includes beta as well as RTM (RTM is 10240)
// Create new capabilities, set as all false. This will allow
// us to call into Esent.
this.Capabilities = new JetCapabilities { ColumnsKeyMost = 12 };
var version = this.versionOverride;
if (version == 0)
{
version = this.GetVersionFromEsent();
}
var buildNumber = (int)((version & 0xFFFFFF) >> 8);
Trace.WriteLineIf(
TraceSwitch.TraceVerbose,
string.Format(CultureInfo.InvariantCulture, "Version = {0}, BuildNumber = {1}", version, buildNumber));
if (buildNumber >= Server2003BuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Server 2003 features");
this.Capabilities.SupportsServer2003Features = true;
}
if (buildNumber >= VistaBuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Vista features");
this.Capabilities.SupportsVistaFeatures = true;
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Unicode paths");
this.Capabilities.SupportsUnicodePaths = true;
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports large keys");
this.Capabilities.SupportsLargeKeys = true;
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports 16-column keys");
this.Capabilities.ColumnsKeyMost = 16;
}
if (buildNumber >= Windows7BuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Windows 7 features");
this.Capabilities.SupportsWindows7Features = true;
}
if (buildNumber >= Windows8BuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Windows 8 features");
this.Capabilities.SupportsWindows8Features = true;
}
if (buildNumber >= Windows81BuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Windows 8.1 features");
this.Capabilities.SupportsWindows81Features = true;
}
if (buildNumber >= Windows10BuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Windows 10 features");
this.Capabilities.SupportsWindows10Features = true;
}
}
/// <summary>
/// Create an instance and get the current version of Esent.
/// </summary>
/// <returns>The current version of Esent.</returns>
private uint GetVersionFromEsent()
{
#if MANAGEDESENT_ON_WSA
// JetGetVersion isn't available in new Windows user interface, so we'll pretend it's always Win8:
return 8250 << 8;
#else
// Create a unique name so that multiple threads can call this simultaneously.
// This can happen if there are multiple AppDomains.
string instanceName = string.Format(CultureInfo.InvariantCulture, "GettingEsentVersion{0}", LibraryHelpers.GetCurrentManagedThreadId());
JET_INSTANCE instance = JET_INSTANCE.Nil;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
this.JetCreateInstance(out instance, instanceName);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.Recovery, new IntPtr(0), "off");
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.NoInformationEvent, new IntPtr(1), null);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.MaxTemporaryTables, new IntPtr(0), null);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.MaxCursors, new IntPtr(16), null);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.MaxOpenTables, new IntPtr(16), null);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.MaxVerPages, new IntPtr(4), null);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.MaxSessions, new IntPtr(1), null);
this.JetInit(ref instance);
JET_SESID sesid;
this.JetBeginSession(instance, out sesid, string.Empty, string.Empty);
try
{
uint version;
this.JetGetVersion(sesid, out version);
return version;
}
finally
{
this.JetEndSession(sesid, EndSessionGrbit.None);
}
}
finally
{
if (JET_INSTANCE.Nil != instance)
{
this.JetTerm(instance);
}
}
#endif
}
}
}

View File

@ -1,22 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentNativeMethods.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// NativeMethods code that is specific to ESENT.
// </summary>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Implementation
{
/// <summary>
/// Configuration for functions in esent.dll.
/// </summary>
internal static partial class NativeMethods
{
/// <summary>
/// The name of the DLL that the methods should be loaded from.
/// </summary>
private const string EsentDll = "esent.dll";
}
}

View File

@ -1,325 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentStubAttributes.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// Attribute stubs to allow compiling on CoreClr.
// </summary>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics.CodeAnalysis;
#if !MANAGEDESENT_ON_WSA
This file should only be compiled with MANAGEDESENT_ON_WSA
#endif
/// <summary>
/// A fake enumeration to allow compilation on platforms that lack this enumeration.
/// </summary>
public enum SecurityAction
{
/// <summary>
/// A fake enumeration to allow compilation on platforms that lack this enumeration.
/// </summary>
LinkDemand
}
/// <summary>
/// A fake attribute to allow compilation on platforms that lack this attribute.
/// </summary>
//// The real one inherits from System.Security.Permissions.CodeAccessSecurityAttribute.
[SerializableAttribute]
[ComVisibleAttribute(true)]
[AttributeUsageAttribute(
AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor
| AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
internal sealed class SecurityPermissionAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="SecurityPermissionAttribute"/> class.
/// </summary>
/// <param name="action">
/// The action.
/// </param>
public SecurityPermissionAttribute(
SecurityAction action)
{
}
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// A fake attribute to allow compilation on platforms that lack this attribute.
/// </summary>
[ComVisibleAttribute(true)]
[AttributeUsageAttribute(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal sealed class BestFitMappingAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="BestFitMappingAttribute"/> class.
/// </summary>
/// <param name="bestFitMapping">
/// The best fit mapping.
/// </param>
public BestFitMappingAttribute(
bool bestFitMapping)
{
}
/// <summary>
/// Gets or sets a value indicating whether ThrowOnUnmappableChar.
/// </summary>
public bool ThrowOnUnmappableChar
{
get;
set;
}
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// A fake attribute to allow compilation on platforms that lack this attribute.
/// </summary>
[ComVisibleAttribute(true)]
[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = true,
Inherited = false)]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal sealed class SuppressUnmanagedCodeSecurityAttribute : Attribute
{
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// A fake attribute to allow compilation on platforms that lack this attribute.
/// </summary>
[AttributeUsageAttribute(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ComVisibleAttribute(true)]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal sealed class ComVisibleAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ComVisibleAttribute"/> class.
/// </summary>
/// <param name="comVisible">
/// The com visible.
/// </param>
public ComVisibleAttribute(bool comVisible)
{
}
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// Indicates that a class can be serialized. This class cannot be inherited.
/// </summary>
/// <filterpriority>1</filterpriority>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false), ComVisible(true)]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal sealed class SerializableAttribute : Attribute
{
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// Indicates that a field of a serializable class should not be serialized. This class cannot be inherited.
/// </summary>
/// <filterpriority>1</filterpriority>
[ComVisible(true), AttributeUsage(AttributeTargets.Field, Inherited = false)]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal sealed class NonSerializedAttribute : Attribute
{
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
}
namespace System.Runtime.ConstrainedExecution
{
}
namespace System.Security.Cryptography
{
}
namespace System.Security.Permissions
{
}
namespace Microsoft.Win32.SafeHandles
{
}
namespace System.Runtime.ConstrainedExecution
{
using System;
using Microsoft.Isam.Esent.Interop;
/// <summary>
/// The consistency model. A stub.
/// </summary>
internal enum Consistency
{
/// <summary>
/// Might corrupt the process.
/// </summary>
MayCorruptProcess,
/// <summary>
/// Might corrupt the application domain.
/// </summary>
MayCorruptAppDomain,
/// <summary>
/// Might corrupt the instance.
/// </summary>
MayCorruptInstance,
/// <summary>
/// Will not corrupt the state.
/// </summary>
WillNotCorruptState,
}
/// <summary>
/// The Crticial Execution Region description. A stub.
/// </summary>
internal enum Cer
{
/// <summary>
/// No options.
/// </summary>
None,
/// <summary>
/// This might fail.
/// </summary>
MayFail,
/// <summary>
/// A successful CER.
/// </summary>
Success,
}
/// <summary>
/// The description of the reliability contract. A stub.
/// </summary>
internal sealed class ReliabilityContractAttribute : Attribute
{
/// <summary>
/// The consistency guarantee. A stub.
/// </summary>
private Consistency consistency;
/// <summary>
/// The critical execution region. A stub.
/// </summary>
private Cer cer;
/// <summary>
/// Initializes a new instance of the ReliabilityContractAttribute class. A stub.
/// </summary>
/// <param name="consistencyGuarantee">The guarantee of the consistency.</param>
/// <param name="cer">The critical execution region description.</param>
public ReliabilityContractAttribute(Consistency consistencyGuarantee, Cer cer)
{
this.consistency = consistencyGuarantee;
this.cer = cer;
}
/// <summary>
/// Gets the consistency guarantee. A stub.
/// </summary>
public Consistency ConsistencyGuarantee
{
get
{
return this.consistency;
}
}
/// <summary>
/// Gets the critical execution region. A stub.
/// </summary>
public Cer Cer
{
get
{
return this.cer;
}
}
}
}

View File

@ -1,273 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentStubs.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// Class stubs to allow compiling on CoreClr.
// </summary>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// Some useful functionality that was omitted from Core CLR classes.
/// </summary>
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
public static class ExtensionsToCoreClr
{
/// <summary>Converts the value of this instance to the equivalent OLE Automation date.</summary>
/// <param name="dateTime">A DateTime structure.</param>
/// <returns>A double-precision floating-point number that contains an OLE Automation date equivalent to the value of this instance.</returns>
/// <exception cref="T:System.OverflowException">The value of this instance cannot be represented as an OLE Automation Date. </exception>
/// <filterpriority>2</filterpriority>
public static double ToOADate(this DateTime dateTime)
{
return LibraryHelpers.TicksToOADate(dateTime.Ticks);
}
}
/// <summary>
/// JetApi code that is specific to ESENT.
/// </summary>
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
public class SerializationInfo
{
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
/// <summary>
/// Deserializes an integer.
/// </summary>
/// <param name="propName">The name of the field to retrieve.</param>
/// <returns>An integer.</returns>
public int GetInt32(string propName)
{
return 0;
}
}
/// <summary>
/// A fake class to allow compilation on platforms that lack this class.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal static class RuntimeHelpers
{
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
public static void PrepareConstrainedRegions()
{
}
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="method">
/// The method.
/// </param>
public static void PrepareMethod(RuntimeMethodHandle method)
{
}
}
/// <summary>
/// A fake class to allow compilation on platforms that lack this class.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
internal class TraceSwitch
{
/// <summary>
/// Initializes a new instance of the <see cref="TraceSwitch"/> class.
/// </summary>
/// <param name="displayName">
/// The display name.
/// </param>
/// <param name="description">
/// The description.
/// </param>
public TraceSwitch(string displayName, string description)
{
}
/// <summary>
/// Gets a value indicating whether TraceVerbose.
/// </summary>
public bool TraceVerbose { get; private set; }
/// <summary>
/// Gets a value indicating whether TraceWarning.
/// </summary>
public bool TraceWarning { get; private set; }
/// <summary>
/// Gets a value indicating whether TraceError.
/// </summary>
public bool TraceError { get; private set; }
/// <summary>
/// Gets a value indicating whether TraceInfo.
/// </summary>
public bool TraceInfo { get; private set; }
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// A fake class to allow compilation on platforms that lack this class.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
internal class Trace
{
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="condition">
/// The condition.
/// </param>
/// <param name="message">
/// The message.
/// </param>
[ConditionalAttribute("TRACE")]
public static void WriteLineIf(bool condition, string message)
{
}
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="message">
/// The message.
/// </param>
[ConditionalAttribute("TRACE")]
public static void TraceError(string message)
{
}
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="message">
/// The message.
/// </param>
/// <param name="args">
/// The arguments.
/// </param>
[ConditionalAttribute("TRACE")]
public static void TraceWarning(string message, params object[] args)
{
}
}
}
#if MANAGEDESENT_ON_WSA
namespace System.ComponentModel
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Security;
/// <summary>
/// An exception from a Win32 call.
/// </summary>
//// The original derives from System.Runtime.InteropServices.ExternalException.
internal class Win32Exception : Exception
{
/// <summary>
/// The error code from a Win32 call.
/// </summary>
private readonly int nativeErrorCode;
/// <summary>
/// Initializes a new instance of the Win32Exception class.
/// </summary>
[SecuritySafeCritical]
public Win32Exception() : this(Marshal.GetLastWin32Error())
{
}
/// <summary>
/// Initializes a new instance of the Win32Exception class.
/// </summary>
/// <param name="error">A win32 error code.</param>
[SecuritySafeCritical]
public Win32Exception(int error) : this(error, Win32Exception.GetErrorMessage(error))
{
}
/// <summary>
/// Initializes a new instance of the Win32Exception class.
/// </summary>
/// <param name="error">A win32 error code.</param>
/// <param name="message">The string message.</param>
public Win32Exception(int error, string message)
: base(message)
{
this.nativeErrorCode = error;
}
/// <summary>
/// Initializes a new instance of the Win32Exception class.
/// </summary>
/// <param name="message">The string message.</param>
[SecuritySafeCritical]
public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message)
{
}
/// <summary>
/// Initializes a new instance of the Win32Exception class.
/// </summary>
/// <param name="message">The string message.</param>
/// <param name="innerException">The nested exception.</param>
[SecuritySafeCritical, SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke", Justification = "Retuning error codes.")]
public Win32Exception(string message, Exception innerException) : base(message, innerException)
{
this.nativeErrorCode = Marshal.GetLastWin32Error();
}
/// <summary>
/// Returns a string value of the Win32 error code.
/// </summary>
/// <param name="error">The Win32 error code.</param>
/// <returns>A string representation.</returns>
[SecuritySafeCritical]
private static string GetErrorMessage(int error)
{
string result = string.Empty;
result = "Win32 error (0x" + Convert.ToString(error, 16) + ")";
return result;
}
}
}
#endif // MANAGEDESENT_ON_WSA

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,76 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentErrorException.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Runtime.Serialization;
/// <summary>
/// Base class for ESENT error exceptions.
/// </summary>
[Serializable]
public class EsentErrorException : EsentException
{
/// <summary>
/// The error code that was encountered.
/// </summary>
private JET_err errorCode;
/// <summary>
/// Initializes a new instance of the EsentErrorException class.
/// </summary>
/// <param name="message">The description of the error.</param>
/// <param name="err">The error code of the exception.</param>
internal EsentErrorException(string message, JET_err err) : base(message)
{
this.errorCode = err;
}
/// <summary>
/// Initializes a new instance of the EsentErrorException class. This constructor
/// is used to deserialize a serialized exception.
/// </summary>
/// <param name="info">The data needed to deserialize the object.</param>
/// <param name="context">The deserialization context.</param>
protected EsentErrorException(SerializationInfo info, StreamingContext context) :
base(info, context)
{
this.errorCode = (JET_err)info.GetInt32("errorCode");
}
/// <summary>
/// Gets the underlying Esent error for this exception.
/// </summary>
public JET_err Error
{
get
{
return this.errorCode;
}
}
#if !MANAGEDESENT_ON_CORECLR // Serialization does not work in Core CLR.
/// <summary>When overridden in a derived class, sets the <see cref="T:System.Runtime.Serialization.SerializationInfo" /> with information about the exception.</summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> that holds the serialized object data about the exception being thrown. </param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext" /> that contains contextual information about the source or destination. </param>
/// <exception cref="T:System.ArgumentNullException">The <paramref name="info" /> parameter is a null reference (Nothing in Visual Basic). </exception>
/// <filterpriority>2</filterpriority>
/// <PermissionSet>
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Read="*AllFiles*" PathDiscovery="*AllFiles*" />
/// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="SerializationFormatter" />
/// </PermissionSet>
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
if (info != null)
{
info.AddValue("errorCode", this.errorCode, typeof(int));
}
}
#endif
}
}

View File

@ -1,51 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentException.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent
{
using System;
using System.Runtime.Serialization;
#if !MANAGEDESENT_SUPPORTS_SERIALIZATION && MANAGEDESENT_ON_WSA
using Microsoft.Isam.Esent.Interop;
using SerializableAttribute = Microsoft.Isam.Esent.Interop.SerializableAttribute;
#endif
/// <summary>
/// Base class for ESENT exceptions.
/// </summary>
[Serializable]
public abstract class EsentException : Exception
{
/// <summary>
/// Initializes a new instance of the EsentException class.
/// </summary>
protected EsentException()
{
}
/// <summary>
/// Initializes a new instance of the EsentException class with a specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
protected EsentException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the EsentException class. This constructor
/// is used to deserialize a serialized exception.
/// </summary>
/// <param name="info">The data needed to deserialize the object.</param>
/// <param name="context">The deserialization context.</param>
protected EsentException(SerializationInfo info, StreamingContext context)
#if MANAGEDESENT_SUPPORTS_SERIALIZATION || !MANAGEDESENT_ON_WSA
: base(info, context)
#endif
{
}
}
}

View File

@ -1,109 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E929E163-52A0-4AAC-917B-6D7FAF70C45E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Esent.Interop</RootNamespace>
<AssemblyName>Esent.Interop</AssemblyName>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<DefineConstants></DefineConstants>
<FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<PublicKeyFile>..\scripts\internal\35MSSharedLib1024.snk</PublicKeyFile>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
<!-- The .snk file won't be published to codeplex. -->
<PropertyGroup Condition="Exists('$(PublicKeyFile)')">
<DefineConstants>$(DefineConstants);STRONG_NAMED</DefineConstants>
<DelaySign>true</DelaySign>
<AssemblyOriginatorKeyFile>$(PublicKeyFile)</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>$(DefineConstants);DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>$(DefineConstants);DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Compile Include="*.cs" />
<Compile Include="Esent\CallbackDataConverter.cs" />
<Compile Include="Esent\EsentJetApi.cs" />
<Compile Include="Esent\EsentNativeMethods.cs" />
<Compile Include="Esent\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,50 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentInvalidColumnException.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Runtime.Serialization;
/// <summary>
/// Exception thrown when a column conversion fails.
/// </summary>
[Serializable]
public class EsentInvalidColumnException : EsentException
{
/// <summary>
/// Initializes a new instance of the EsentInvalidColumnException class.
/// </summary>
public EsentInvalidColumnException()
{
}
#if MANAGEDESENT_ON_CORECLR
#else
/// <summary>
/// Initializes a new instance of the EsentInvalidColumnException class. This constructor
/// is used to deserialize a serialized exception.
/// </summary>
/// <param name="info">The data needed to deserialize the object.</param>
/// <param name="context">The deserialization context.</param>
protected EsentInvalidColumnException(SerializationInfo info, StreamingContext context) :
base(info, context)
{
}
#endif
/// <summary>
/// Gets a text message describing the exception.
/// </summary>
public override string Message
{
get
{
return "Column is not valid for this operation";
}
}
}
}

View File

@ -1,127 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentResource.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// This is the base class for all esent resource objects.
/// Subclasses of this class can allocate and release unmanaged
/// resources.
/// </summary>
public abstract class EsentResource : IDisposable
{
/// <summary>
/// True if a resource has been allocated.
/// </summary>
private bool hasResource;
/// <summary>
/// True if this object has been disposed.
/// </summary>
private bool isDisposed;
/// <summary>
/// Finalizes an instance of the EsentResource class.
/// </summary>
~EsentResource()
{
this.Dispose(false);
}
/// <summary>
/// Gets a value indicating whether the underlying resource
/// is currently allocated.
/// </summary>
protected bool HasResource
{
get
{
return this.hasResource;
}
}
/// <summary>
/// Dispose of this object, releasing the underlying
/// Esent resource.
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Called by Dispose and the finalizer.
/// </summary>
/// <param name="isDisposing">
/// True if called from Dispose.
/// </param>
protected virtual void Dispose(bool isDisposing)
{
if (isDisposing)
{
if (this.hasResource)
{
this.ReleaseResource();
Debug.Assert(!this.hasResource, "Resource was not freed");
}
this.isDisposed = true;
}
else
{
if (this.hasResource)
{
// We should not get to this point. The problem is that if
// we use finalizers to free esent resources they may end
// up being freed in the wrong order (e.g. JetEndSession is
// called before JetCloseTable). Freeing esent resources
// in the wrong order will generate EsentExceptions.
Trace.TraceWarning("Non-finalized ESENT resource {0}", this);
}
}
}
/// <summary>
/// Throw an exception if this object has been disposed.
/// </summary>
protected void CheckObjectIsNotDisposed()
{
if (this.isDisposed)
{
throw new ObjectDisposedException("EsentResource");
}
}
/// <summary>
/// Called by a subclass when a resource is allocated.
/// </summary>
protected void ResourceWasAllocated()
{
this.CheckObjectIsNotDisposed();
Debug.Assert(!this.hasResource, "Resource is already allocated");
this.hasResource = true;
}
/// <summary>
/// Called by a subclass when a resource is freed.
/// </summary>
protected void ResourceWasReleased()
{
Debug.Assert(this.hasResource, "Resource is not allocated");
this.CheckObjectIsNotDisposed();
this.hasResource = false;
}
/// <summary>
/// Implemented by the subclass to release a resource.
/// </summary>
protected abstract void ReleaseResource();
}
}

View File

@ -1,113 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentStopwatch.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using Microsoft.Isam.Esent.Interop.Vista;
/// <summary>
/// Provides a set of methods and properties that you can use to measure
/// ESENT work statistics for a thread. If the current version of ESENT
/// doesn't support <see cref="VistaApi.JetGetThreadStats"/> then all
/// ESENT statistics will be 0.
/// </summary>
public class EsentStopwatch
{
/// <summary>
/// Used to measure how long statistics are collected for.
/// </summary>
private Stopwatch stopwatch;
/// <summary>
/// The stats at the start of our collection.
/// </summary>
private JET_THREADSTATS statsAtStart;
/// <summary>
/// Gets a value indicating whether the EsentStopwatch timer is running.
/// </summary>
public bool IsRunning { get; private set; }
/// <summary>
/// Gets the total ESENT work stats measured by the current instance.
/// </summary>
public JET_THREADSTATS ThreadStats { get; private set; }
/// <summary>
/// Gets the total elapsed time measured by the current instance.
/// </summary>
public TimeSpan Elapsed { get; private set; }
/// <summary>
/// Initializes a new EsentStopwatch instance and starts
/// measuring elapsed time.
/// </summary>
/// <returns>A new, running EsentStopwatch.</returns>
public static EsentStopwatch StartNew()
{
var stopwatch = new EsentStopwatch();
stopwatch.Start();
return stopwatch;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="Stopwatch"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="Stopwatch"/>.
/// </returns>
public override string ToString()
{
return this.IsRunning ? "EsentStopwatch (running)" : this.Elapsed.ToString();
}
/// <summary>
/// Starts measuring ESENT work.
/// </summary>
public void Start()
{
this.Reset();
this.stopwatch = Stopwatch.StartNew();
this.IsRunning = true;
if (EsentVersion.SupportsVistaFeatures)
{
VistaApi.JetGetThreadStats(out this.statsAtStart);
}
}
/// <summary>
/// Stops measuring ESENT work.
/// </summary>
public void Stop()
{
if (this.IsRunning)
{
this.IsRunning = false;
this.stopwatch.Stop();
this.Elapsed = this.stopwatch.Elapsed;
if (EsentVersion.SupportsVistaFeatures)
{
JET_THREADSTATS statsAtEnd;
VistaApi.JetGetThreadStats(out statsAtEnd);
this.ThreadStats = statsAtEnd - this.statsAtStart;
}
}
}
/// <summary>
/// Stops time interval measurement and resets the thread statistics.
/// </summary>
public void Reset()
{
this.stopwatch = null;
this.ThreadStats = new JET_THREADSTATS();
this.Elapsed = TimeSpan.Zero;
this.IsRunning = false;
}
}
}

View File

@ -1,134 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentVersion.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// Gives information about the version of esent being used.
/// </summary>
public static class EsentVersion
{
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows Server 2003 version of
/// esent.
/// </summary>
public static bool SupportsServer2003Features
{
get
{
return Capabilities.SupportsServer2003Features;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows Vista version of
/// esent.
/// </summary>
public static bool SupportsVistaFeatures
{
get
{
return Capabilities.SupportsVistaFeatures;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows 7 version of
/// esent.
/// </summary>
public static bool SupportsWindows7Features
{
get
{
return Capabilities.SupportsWindows7Features;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows 8 version of
/// esent.
/// </summary>
public static bool SupportsWindows8Features
{
get
{
return Capabilities.SupportsWindows8Features;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows 8.1 version of
/// esent.
/// </summary>
public static bool SupportsWindows81Features
{
get
{
return Capabilities.SupportsWindows81Features;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows 10 version of
/// esent.
/// </summary>
public static bool SupportsWindows10Features
{
get
{
return Capabilities.SupportsWindows10Features;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// can use non-ASCII paths to access databases.
/// </summary>
public static bool SupportsUnicodePaths
{
get
{
return Capabilities.SupportsUnicodePaths;
}
}
/// <summary>
/// Gets a value indicating whether large (> 255 byte) keys are supported.
/// The key size for an index can be specified in the <see cref="JET_INDEXCREATE"/>
/// object.
/// </summary>
public static bool SupportsLargeKeys
{
get
{
return Capabilities.SupportsLargeKeys;
}
}
/// <summary>
/// Gets a description of the current Esent capabilities.
/// </summary>
/// <remarks>
/// We allow this to be set separately so that capabilities can
/// be downgraded for testing.
/// </remarks>
private static JetCapabilities Capabilities
{
get
{
return Api.Impl.Capabilities;
}
}
}
}

View File

@ -1,69 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="FloatColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A <see cref="float"/> column value.
/// </summary>
public class FloatColumnValue : ColumnValueOfStruct<float>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(float); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(float), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToSingle(value, startIndex);
}
}
}
}

View File

@ -1,94 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="GCHandleCollection.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Implementation
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
/// <summary>
/// A collection of GCHandles for pinned objects. The handles
/// are freed when this object is disposed.
/// </summary>
[StructLayout(LayoutKind.Auto)]
internal struct GCHandleCollection : IDisposable
{
/// <summary>
/// The handles of the objects being pinned.
/// </summary>
private GCHandle[] handles;
/// <summary>
/// Handle count.
/// </summary>
private int count;
/// <summary>
/// Disposes of the object.
/// </summary>
public void Dispose()
{
if (null != this.handles)
{
for (int i = 0; i < this.count; i++)
{
this.handles[i].Free();
}
this.handles = null;
}
}
/// <summary>
/// Add an object to the handle collection. This automatically
/// pins the object.
/// </summary>
/// <param name="value">The object to pin.</param>
/// <returns>
/// The address of the pinned object. This is valid until the
/// GCHandleCollection is disposed.
/// </returns>
public IntPtr Add(object value)
{
if (null == value)
{
return IntPtr.Zero;
}
if (null == this.handles)
{
this.handles = new GCHandle[4]; // same as List<T>
}
else if (this.count == this.handles.Length)
{
Array.Resize(ref this.handles, this.count * 2);
}
Debug.Assert(this.count < this.handles.Length, "Index out of bound");
GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
this.handles[this.count++] = handle;
IntPtr pinned = handle.AddrOfPinnedObject();
Debug.Assert(IntPtr.Zero != pinned, "Pinned object has null address");
return pinned;
}
/// <summary>
/// Set handle array capacity.
/// </summary>
/// <param name="capacity">Estimated handle count</param>
public void SetCapacity(int capacity)
{
if (null == this.handles)
{
this.handles = new GCHandle[capacity];
}
}
}
}

View File

@ -1,64 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="GenericEnumerable.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// IEnumerable class that takes a delegate to create the enumerator it returns.
/// </summary>
/// <typeparam name="T">The type returned by the enumerator.</typeparam>
internal class GenericEnumerable<T> : IEnumerable<T>
{
/// <summary>
/// The delegate used to create the enumerator.
/// </summary>
private readonly CreateEnumerator enumeratorCreator;
/// <summary>
/// Initializes a new instance of the <see cref="GenericEnumerable{T}"/> class.
/// </summary>
/// <param name="enumeratorCreator">
/// The enumerator creator.
/// </param>
public GenericEnumerable(CreateEnumerator enumeratorCreator)
{
this.enumeratorCreator = enumeratorCreator;
}
/// <summary>
/// IEnumerator creating delegate.
/// </summary>
/// <returns>A new enumerator.</returns>
public delegate IEnumerator<T> CreateEnumerator();
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/>
/// that can be used to iterate through the collection.
/// </returns>
public IEnumerator<T> GetEnumerator()
{
return this.enumeratorCreator();
}
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.IEnumerator"/>
/// object that can be used to iterate through the collection.
/// </returns>
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}

View File

@ -1,48 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="GetLockHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// Helper methods for JetMakeKey.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK
namespace Microsoft.Isam.Esent.Interop
{
using System.Diagnostics;
/// <summary>
/// Helper methods for the ESENT API. These wrap JetMakeKey.
/// </summary>
public static partial class Api
{
/// <summary>
/// Explicitly reserve the ability to update a row, write lock, or to explicitly prevent a row from
/// being updated by any other session, read lock. Normally, row write locks are acquired implicitly as a
/// result of updating rows. Read locks are usually not required because of record versioning. However,
/// in some cases a transaction may desire to explicitly lock a row to enforce serialization, or to ensure
/// that a subsequent operation will succeed.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to use. A lock will be acquired on the current record.</param>
/// <param name="grbit">Lock options, use this to specify which type of lock to obtain.</param>
/// <returns>
/// True if the lock was obtained, false otherwise. An exception is thrown if an unexpected
/// error is encountered.
/// </returns>
public static bool TryGetLock(JET_SESID sesid, JET_TABLEID tableid, GetLockGrbit grbit)
{
var err = (JET_err)Impl.JetGetLock(sesid, tableid, grbit);
if (JET_err.WriteConflict == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
}
}
#endif // !MANAGEDESENT_ON_WSA

View File

@ -1,82 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="GuidColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A <see cref="Guid"/> column value.
/// </summary>
public class GuidColumnValue : ColumnValueOfStruct<Guid>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return 16; /* sizeof(Guid) */ }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
Guid data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, this.Size, this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
unsafe
{
// There isn't a convenient Guid constructor for this case, so
// we copy the data manually.
Guid guid;
void* guidBuffer = &guid;
byte* buffer = (byte*)guidBuffer;
for (int i = 0; i < this.Size; ++i)
{
buffer[i] = value[startIndex + i];
}
this.Value = guid;
}
}
}
}
}

View File

@ -1,26 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IContentEquatable.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Interface for objects that can have their contents compared against
/// each other. This should be used for equality comparisons on mutable
/// reference objects where overriding Equals() and GetHashCode() isn't a
/// good idea.
/// </summary>
/// <typeparam name="T">The type of objects to compare.</typeparam>
public interface IContentEquatable<T>
{
/// <summary>
/// Returns a value indicating whether this instance is equal
/// to another instance.
/// </summary>
/// <param name="other">An instance to compare with this instance.</param>
/// <returns>True if the two instances are equal.</returns>
bool ContentEquals(T other);
}
}

View File

@ -1,22 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IDeepCloneable.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Interface for objects that can be cloned. This creates a deep copy of
/// the object. It is used for cloning meta-data objects.
/// </summary>
/// <typeparam name="T">The type of object.</typeparam>
public interface IDeepCloneable<T>
{
/// <summary>
/// Returns a deep copy of the object.
/// </summary>
/// <returns>A deep copy of the object.</returns>
T DeepClone();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="INullableJetStruct.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Interface for Jet structures that are nullable (can have null values).
/// </summary>
public interface INullableJetStruct
{
/// <summary>
/// Gets a value indicating whether the structure has a null value.
/// </summary>
bool HasValue { get; }
}
}

View File

@ -1,189 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IndexInfo.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Text;
/// <summary>
/// Information about one esent index. This is not an interop
/// class, but is used by the meta-data helper methods.
/// </summary>
[Serializable]
public class IndexInfo
{
/// <summary>
/// The name of the index.
/// </summary>
private readonly string name;
/// <summary>
/// The culture info of the index.
/// </summary>
private readonly CultureInfo cultureInfo;
/// <summary>
/// Index comparison options.
/// </summary>
private readonly CompareOptions compareOptions;
/// <summary>
/// Index segments.
/// </summary>
private readonly ReadOnlyCollection<IndexSegment> indexSegments;
/// <summary>
/// Index options.
/// </summary>
private readonly CreateIndexGrbit grbit;
/// <summary>
/// Number of unique keys in the index.
/// </summary>
private readonly int keys;
/// <summary>
/// Number of entries in the index.
/// </summary>
private readonly int entries;
/// <summary>
/// Number of pages in the index.
/// </summary>
private readonly int pages;
/// <summary>
/// Initializes a new instance of the IndexInfo class.
/// </summary>
/// <param name="name">Name of the index.</param>
/// <param name="cultureInfo">CultureInfo for string sorting.</param>
/// <param name="compareOptions">String comparison options.</param>
/// <param name="indexSegments">Array of index segment descriptions.</param>
/// <param name="grbit">Index options.</param>
/// <param name="keys">Number of unique keys in the index.</param>
/// <param name="entries">Number of entries in the index.</param>
/// <param name="pages">Number of pages in the index.</param>
internal IndexInfo(
string name,
CultureInfo cultureInfo,
CompareOptions compareOptions,
IndexSegment[] indexSegments,
CreateIndexGrbit grbit,
int keys,
int entries,
int pages)
{
this.name = name;
this.cultureInfo = cultureInfo;
this.compareOptions = compareOptions;
this.indexSegments = new ReadOnlyCollection<IndexSegment>(indexSegments);
this.grbit = grbit;
this.keys = keys;
this.entries = entries;
this.pages = pages;
}
/// <summary>
/// Gets the name of the index.
/// </summary>
public string Name
{
[DebuggerStepThrough]
get { return this.name; }
}
/// <summary>
/// Gets the CultureInfo the index is sorted by.
/// </summary>
public CultureInfo CultureInfo
{
[DebuggerStepThrough]
get { return this.cultureInfo; }
}
/// <summary>
/// Gets the CompareOptions for the index.
/// </summary>
public CompareOptions CompareOptions
{
[DebuggerStepThrough]
get { return this.compareOptions; }
}
/// <summary>
/// Gets the segments of the index.
/// </summary>
public IList<IndexSegment> IndexSegments
{
[DebuggerStepThrough]
get { return this.indexSegments; }
}
/// <summary>
/// Gets the index options.
/// </summary>
public CreateIndexGrbit Grbit
{
[DebuggerStepThrough]
get { return this.grbit; }
}
/// <summary>
/// Gets the number of unique keys in the index.
/// This value is not current and is only is updated by Api.JetComputeStats.
/// </summary>
public int Keys
{
[DebuggerStepThrough]
get { return this.keys; }
}
/// <summary>
/// Gets the number of entries in the index.
/// This value is not current and is only is updated by Api.JetComputeStats.
/// </summary>
public int Entries
{
[DebuggerStepThrough]
get { return this.entries; }
}
/// <summary>
/// Gets the number of pages in the index.
/// This value is not current and is only is updated by Api.JetComputeStats.
/// </summary>
public int Pages
{
[DebuggerStepThrough]
get { return this.pages; }
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="IndexInfo"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="IndexInfo"/>.
/// </returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(this.Name);
sb.Append(" (");
foreach (var segment in this.IndexSegments)
{
sb.Append(segment.ToString());
}
sb.Append(")");
return sb.ToString();
}
}
}

View File

@ -1,153 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IndexInfoEnumerator.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Diagnostics;
using System.Globalization;
using System.Text;
using Microsoft.Isam.Esent.Interop.Windows8;
/// <summary>
/// Base class for enumerators that return IndexInfo objects. Subclasses differ
/// by how they open the table.
/// </summary>
internal abstract class IndexInfoEnumerator : TableEnumerator<IndexInfo>
{
/// <summary>
/// Initializes a new instance of the <see cref="IndexInfoEnumerator"/> class.
/// </summary>
/// <param name="sesid">
/// The session to use.
/// </param>
protected IndexInfoEnumerator(JET_SESID sesid) : base(sesid)
{
}
/// <summary>
/// Gets or sets the indexlist used to retrieve data.
/// </summary>
protected JET_INDEXLIST Indexlist { get; set; }
/// <summary>
/// Gets the entry the cursor is currently positioned on.
/// </summary>
/// <returns>The entry the cursor is currently positioned on.</returns>
protected override IndexInfo GetCurrent()
{
return this.GetIndexInfoFromIndexlist(this.Sesid, this.Indexlist);
}
/// <summary>
/// Retrieves information about indexes on a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="indexname">The name of the index.</param>
/// <param name="result">Filled in with information about indexes on the table.</param>
/// <param name="infoLevel">The type of information to retrieve.</param>
protected abstract void GetIndexInfo(
JET_SESID sesid,
string indexname,
out string result,
JET_IdxInfo infoLevel);
/// <summary>
/// Create an array of IndexSegment objects from the data in the current JET_INDEXLIST entry.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="indexlist">The indexlist to take the data from.</param>
/// <returns>An array of IndexSegment objects containing the information for the current index.</returns>
private static IndexSegment[] GetIndexSegmentsFromIndexlist(JET_SESID sesid, JET_INDEXLIST indexlist)
{
var numSegments = (int)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidcColumn);
Debug.Assert(numSegments > 0, "Index has zero index segments");
// If we use the wide API (Vista+), then the temp table will be in UTF-16.
Encoding encodingOfTextColumns = EsentVersion.SupportsVistaFeatures ? Encoding.Unicode : LibraryHelpers.EncodingASCII;
var segments = new IndexSegment[numSegments];
for (int i = 0; i < numSegments; ++i)
{
string columnName = Api.RetrieveColumnAsString(
sesid,
indexlist.tableid,
indexlist.columnidcolumnname,
encodingOfTextColumns,
RetrieveColumnGrbit.None);
columnName = StringCache.TryToIntern(columnName);
var coltyp = (JET_coltyp)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidcoltyp);
var grbit =
(IndexKeyGrbit)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidgrbitColumn);
bool isAscending = IndexKeyGrbit.Ascending == grbit;
var cp = (JET_CP)Api.RetrieveColumnAsInt16(sesid, indexlist.tableid, indexlist.columnidCp);
bool isASCII = JET_CP.ASCII == cp;
segments[i] = new IndexSegment(columnName, coltyp, isAscending, isASCII);
if (i < numSegments - 1)
{
Api.JetMove(sesid, indexlist.tableid, JET_Move.Next, MoveGrbit.None);
}
}
return segments;
}
/// <summary>
/// Create an IndexInfo object from the data in the current JET_INDEXLIST entry.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="indexlist">The indexlist to take the data from.</param>
/// <returns>An IndexInfo object containing the information from that record.</returns>
private IndexInfo GetIndexInfoFromIndexlist(JET_SESID sesid, JET_INDEXLIST indexlist)
{
// If we use the wide API (Vista+), then the temp table will be in UTF-16.
Encoding encodingOfTextColumns = EsentVersion.SupportsVistaFeatures ? Encoding.Unicode : LibraryHelpers.EncodingASCII;
string name = Api.RetrieveColumnAsString(
sesid, indexlist.tableid, indexlist.columnidindexname, encodingOfTextColumns, RetrieveColumnGrbit.None);
name = StringCache.TryToIntern(name);
CultureInfo cultureInfo = null;
if (EsentVersion.SupportsWindows8Features)
{
string localeName;
this.GetIndexInfo(sesid, name, out localeName, Windows8IdxInfo.LocaleName);
cultureInfo = new CultureInfo(localeName);
}
else
{
#if !MANAGEDESENT_ON_CORECLR
// This probably won't work on platforms that don't support LCIDs. Newer environments have dropped
// LCIDs in favour of locale names. But currently JET_INDEXLIST doesn't expose columnidLocale.
int lcid = (int)Api.RetrieveColumnAsInt16(sesid, indexlist.tableid, indexlist.columnidLangid);
cultureInfo = LibraryHelpers.CreateCultureInfoByLcid(lcid);
#endif // !MANAGEDESENT_ON_CORECLR
}
uint lcmapFlags = (uint)Api.RetrieveColumnAsUInt32(sesid, indexlist.tableid, indexlist.columnidLCMapFlags);
CompareOptions compareOptions = Conversions.CompareOptionsFromLCMapFlags(lcmapFlags);
uint grbit = (uint)Api.RetrieveColumnAsUInt32(sesid, indexlist.tableid, indexlist.columnidgrbitIndex);
int keys = (int)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidcKey);
int entries = (int)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidcEntry);
int pages = (int)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidcPage);
IndexSegment[] segments = GetIndexSegmentsFromIndexlist(sesid, indexlist);
return new IndexInfo(
name,
cultureInfo,
compareOptions,
segments,
(CreateIndexGrbit)grbit,
keys,
entries,
pages);
}
}
}

View File

@ -1,152 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IndexSegment.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Globalization;
/// <summary>
/// Describes one segment of an index.
/// </summary>
[Serializable]
public class IndexSegment : IEquatable<IndexSegment>
{
/// <summary>
/// The name of the column.
/// </summary>
private readonly string columnName;
/// <summary>
/// The type of the column.
/// </summary>
private readonly JET_coltyp coltyp;
/// <summary>
/// True if the column is sorted in ascending order.
/// </summary>
private readonly bool isAscending;
/// <summary>
/// True if the column is an ASCII column.
/// </summary>
private readonly bool isASCII;
/// <summary>
/// Initializes a new instance of the IndexSegment class.
/// </summary>
/// <param name="name">The name of the indexed column.</param>
/// <param name="coltyp">The type of the column.</param>
/// <param name="isAscending">True if the column is ascending.</param>
/// <param name="isASCII">True if the column is over an ASCII column.</param>
internal IndexSegment(
string name,
JET_coltyp coltyp,
bool isAscending,
bool isASCII)
{
this.columnName = name;
this.coltyp = coltyp;
this.isAscending = isAscending;
this.isASCII = isASCII;
}
/// <summary>
/// Gets name of the column being indexed.
/// </summary>
public string ColumnName
{
[DebuggerStepThrough]
get { return this.columnName; }
}
/// <summary>
/// Gets the type of the column being indexed.
/// </summary>
public JET_coltyp Coltyp
{
[DebuggerStepThrough]
get { return this.coltyp; }
}
/// <summary>
/// Gets a value indicating whether the index segment is ascending.
/// </summary>
public bool IsAscending
{
[DebuggerStepThrough]
get { return this.isAscending; }
}
/// <summary>
/// Gets a value indicating whether the index segment is over an ASCII text
/// column. This value is only meaningful for text column segments.
/// </summary>
public bool IsASCII
{
[DebuggerStepThrough]
get { return this.isASCII; }
}
/// <summary>
/// Returns a value indicating whether this instance is equal
/// to another instance.
/// </summary>
/// <param name="obj">An object to compare with this instance.</param>
/// <returns>True if the two instances are equal.</returns>
public override bool Equals(object obj)
{
if (obj == null || this.GetType() != obj.GetType())
{
return false;
}
return this.Equals((IndexSegment)obj);
}
/// <summary>
/// Generate a string representation of the instance.
/// </summary>
/// <returns>The structure as a string.</returns>
public override string ToString()
{
return string.Format(
CultureInfo.InvariantCulture, "{0}{1}({2})", this.isAscending ? "+" : "-", this.columnName, this.coltyp);
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <returns>The hash code for this instance.</returns>
public override int GetHashCode()
{
return this.columnName.GetHashCode()
^ (int)this.coltyp * 31
^ (this.isAscending ? 0x10000 : 0x20000)
^ (this.isASCII ? 0x40000 : 0x80000);
}
/// <summary>
/// Returns a value indicating whether this instance is equal
/// to another instance.
/// </summary>
/// <param name="other">An instance to compare with this instance.</param>
/// <returns>True if the two instances are equal.</returns>
public bool Equals(IndexSegment other)
{
if (null == other)
{
return false;
}
return this.columnName.Equals(other.columnName, StringComparison.OrdinalIgnoreCase)
&& this.coltyp == other.coltyp
&& this.isAscending == other.isAscending
&& this.isASCII == other.isASCII;
}
}
}

View File

@ -1,337 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Instance.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using Microsoft.Isam.Esent.Interop.Vista;
using Microsoft.Win32.SafeHandles;
/// <summary>
/// A class that encapsulates a <see cref="JET_INSTANCE"/> in a disposable object. The
/// instance must be closed last and closing the instance releases all other
/// resources for the instance.
/// </summary>
public class Instance : SafeHandleZeroOrMinusOneIsInvalid
{
/// <summary>
/// Parameters for the instance.
/// </summary>
private readonly InstanceParameters parameters;
/// <summary>
/// The name of the instance.
/// </summary>
private readonly string name;
/// <summary>
/// The display name of the instance.
/// </summary>
private readonly string displayName;
/// <summary>
/// The TermGrbit to be used at JetTerm time.
/// </summary>
private TermGrbit termGrbit;
/// <summary>
/// Initializes a new instance of the Instance class. The underlying
/// JET_INSTANCE is allocated, but not initialized.
/// </summary>
/// <param name="name">
/// The name of the instance. This string must be unique within a
/// given process hosting the database engine.
/// </param>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public Instance(string name) : this(name, name, TermGrbit.None)
{
}
/// <summary>
/// Initializes a new instance of the Instance class. The underlying
/// JET_INSTANCE is allocated, but not initialized.
/// </summary>
/// <param name="name">
/// The name of the instance. This string must be unique within a
/// given process hosting the database engine.
/// </param>
/// <param name="displayName">
/// A display name for the instance. This will be used in eventlog
/// entries.
/// </param>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public Instance(string name, string displayName) : this(name, displayName, TermGrbit.None)
{
}
/// <summary>
/// Initializes a new instance of the Instance class. The underlying
/// JET_INSTANCE is allocated, but not initialized.
/// </summary>
/// <param name="name">
/// The name of the instance. This string must be unique within a
/// given process hosting the database engine.
/// </param>
/// <param name="displayName">
/// A display name for the instance. This will be used in eventlog
/// entries.
/// </param>
/// <param name="termGrbit">
/// The TermGrbit to be used at JetTerm time.
/// </param>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public Instance(string name, string displayName, TermGrbit termGrbit) : base(true)
{
this.name = name;
this.displayName = displayName;
this.termGrbit = termGrbit;
JET_INSTANCE instance;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
this.SetHandle(JET_INSTANCE.Nil.Value);
}
finally
{
// This is the code that we want in a constrained execution region.
// We need to avoid the situation where JetCreateInstance2 is called
// but the handle isn't set, so the instance is never terminated.
// This would happen, for example, if there was a ThreadAbortException
// between the call to JetCreateInstance2 and the call to SetHandle.
//
// If an Esent exception is generated we do not want to call SetHandle
// because the instance isn't valid. On the other hand if a different
// exception (out of memory or thread abort) is generated we still need
// to set the handle to avoid losing track of the instance. The call to
// JetCreateInstance2 is in the CER to make sure that the only exceptions
// which can be generated are from ESENT failures.
Api.JetCreateInstance2(out instance, this.name, this.displayName, CreateInstanceGrbit.None);
this.SetHandle(instance.Value);
}
this.parameters = new InstanceParameters(instance);
}
/// <summary>
/// Gets the JET_INSTANCE that this instance contains.
/// </summary>
public JET_INSTANCE JetInstance
{
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
get
{
this.CheckObjectIsNotDisposed();
return this.CreateInstanceFromHandle();
}
}
/// <summary>
/// Gets the InstanceParameters for this instance.
/// </summary>
public InstanceParameters Parameters
{
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
get
{
this.CheckObjectIsNotDisposed();
return this.parameters;
}
}
/// <summary>
/// Gets or sets the TermGrbit for this instance.
/// </summary>
public TermGrbit TermGrbit
{
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
get
{
this.CheckObjectIsNotDisposed();
return this.termGrbit;
}
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
set
{
this.CheckObjectIsNotDisposed();
this.termGrbit = value;
}
}
/// <summary>
/// Provide implicit conversion of an Instance object to a JET_INSTANCE
/// structure. This is done so that an Instance can be used anywhere a
/// JET_INSTANCE is required.
/// </summary>
/// <param name="instance">The instance to convert.</param>
/// <returns>The JET_INSTANCE wrapped by the instance.</returns>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public static implicit operator JET_INSTANCE(Instance instance)
{
return instance.JetInstance;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="Instance"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="Instance"/>.
/// </returns>
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "{0} ({1})", this.displayName, this.name);
}
/// <summary>
/// Initialize the JET_INSTANCE.
/// </summary>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public void Init()
{
this.Init(InitGrbit.None);
}
/// <summary>
/// Initialize the JET_INSTANCE.
/// </summary>
/// <param name="grbit">
/// Initialization options.
/// </param>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public void Init(InitGrbit grbit)
{
this.CheckObjectIsNotDisposed();
JET_INSTANCE instance = this.JetInstance;
// Use a constrained region so that the handle is
// always set after JetInit2 is called.
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// Remember that a failure in JetInit can zero the handle
// and that JetTerm should not be called in that case.
Api.JetInit2(ref instance, grbit);
}
finally
{
this.SetHandle(instance.Value);
}
}
/// <summary>
/// Initialize the JET_INSTANCE. This API requires at least the
/// Vista version of ESENT.
/// </summary>
/// <param name="recoveryOptions">
/// Additional recovery parameters for remapping databases during
/// recovery, position where to stop recovery at, or recovery status.
/// </param>
/// <param name="grbit">
/// Initialization options.
/// </param>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public void Init(JET_RSTINFO recoveryOptions, InitGrbit grbit)
{
this.CheckObjectIsNotDisposed();
JET_INSTANCE instance = this.JetInstance;
// Use a constrained region so that the handle is
// always set after JetInit3 is called.
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// Remember that a failure in JetInit can zero the handle
// and that JetTerm should not be called in that case.
VistaApi.JetInit3(ref instance, recoveryOptions, grbit);
}
finally
{
this.SetHandle(instance.Value);
}
}
/// <summary>
/// Terminate the JET_INSTANCE.
/// </summary>
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1409:RemoveUnnecessaryCode",
Justification = "CER code belongs in the finally block, so the try clause is empty")]
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public void Term()
{
// Use a constrained region so that the handle is
// always set as invalid after JetTerm is called.
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// This try block deliberately left blank.
}
finally
{
// This is the code that we want in a constrained execution region.
// We need to avoid the situation where JetTerm is called
// but the handle isn't invalidated, so the instance is terminated again.
// This would happen, for example, if there was a ThreadAbortException
// between the call to JetTerm and the call to SetHandle.
//
// If an Esent exception is generated we do not want to invalidate the handle
// because the instance isn't necessarily terminated. On the other hand if a
// different exception (out of memory or thread abort) is generated we still need
// to invalidate the handle.
try
{
Api.JetTerm2(this.JetInstance, this.termGrbit);
}
catch (EsentDirtyShutdownException)
{
this.SetHandleAsInvalid();
throw;
}
this.SetHandleAsInvalid();
}
}
/// <summary>
/// Release the handle for this instance.
/// </summary>
/// <returns>True if the handle could be released.</returns>
protected override bool ReleaseHandle()
{
// The object is already marked as invalid so don't check
var instance = this.CreateInstanceFromHandle();
return (int)JET_err.Success == Api.Impl.JetTerm2(instance, this.termGrbit);
}
/// <summary>
/// Create a JET_INSTANCE from the internal handle value.
/// </summary>
/// <returns>A JET_INSTANCE containing the internal handle.</returns>
private JET_INSTANCE CreateInstanceFromHandle()
{
return new JET_INSTANCE { Value = this.handle };
}
/// <summary>
/// Check to see if this instance is invalid or closed.
/// </summary>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
private void CheckObjectIsNotDisposed()
{
if (this.IsInvalid || this.IsClosed)
{
throw new ObjectDisposedException("Instance");
}
}
}
}

View File

@ -1,762 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="InstanceParameters.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Globalization;
using System.IO;
using Microsoft.Isam.Esent.Interop.Server2003;
using Microsoft.Isam.Esent.Interop.Vista;
using Microsoft.Isam.Esent.Interop.Windows7;
/// <summary>
/// This class provides properties to set and get system parameters
/// on an ESENT instance.
/// </summary>
public partial class InstanceParameters
{
/// <summary>
/// The instance to set parameters on.
/// </summary>
private readonly JET_INSTANCE instance;
/// <summary>
/// The session to set parameters with.
/// </summary>
private readonly JET_SESID sesid;
/// <summary>
/// Initializes a new instance of the InstanceParameters class.
/// </summary>
/// <param name="instance">
/// The instance to set parameters on. If this is JET_INSTANCE.Nil,
/// then the settings affect the default settings of future instances.
/// </param>
public InstanceParameters(JET_INSTANCE instance)
{
this.instance = instance;
this.sesid = JET_SESID.Nil;
}
/// <summary>
/// Gets or sets the relative or absolute file system path of the
/// folder that will contain the checkpoint file for the instance.
/// </summary>
public string SystemDirectory
{
get
{
return Util.AddTrailingDirectorySeparator(this.GetStringParameter(JET_param.SystemPath));
}
set
{
this.SetStringParameter(JET_param.SystemPath, Util.AddTrailingDirectorySeparator(value));
}
}
/// <summary>
/// Gets or sets the relative or absolute file system path of
/// the folder that will contain the temporary database for the instance.
/// </summary>
public string TempDirectory
{
get
{
// Older versions of Esent (e.g. Windows XP) will return the
// full path of the temporary database. Extract the directory name.
string path = this.GetStringParameter(JET_param.TempPath);
string dir = Path.GetDirectoryName(path);
return Util.AddTrailingDirectorySeparator(dir);
}
set
{
this.SetStringParameter(JET_param.TempPath, Util.AddTrailingDirectorySeparator(value));
}
}
/// <summary>
/// Gets or sets the relative or absolute file system path of the
/// folder that will contain the transaction logs for the instance.
/// </summary>
public string LogFileDirectory
{
get
{
return Util.AddTrailingDirectorySeparator(this.GetStringParameter(JET_param.LogFilePath));
}
set
{
this.SetStringParameter(JET_param.LogFilePath, Util.AddTrailingDirectorySeparator(value));
}
}
/// <summary>
/// Gets or sets the relative or absolute file system path of the
/// a folder where crash recovery or a restore operation can find
/// the databases referenced in the transaction log in the
/// specified folder.
/// </summary>
/// <remarks>
/// This parameter is ignored on Windows XP.
/// </remarks>
public string AlternateDatabaseRecoveryDirectory
{
get
{
if (EsentVersion.SupportsServer2003Features)
{
return
Util.AddTrailingDirectorySeparator(
this.GetStringParameter(Server2003Param.AlternateDatabaseRecoveryPath));
}
return null;
}
set
{
if (EsentVersion.SupportsServer2003Features)
{
this.SetStringParameter(
Server2003Param.AlternateDatabaseRecoveryPath, Util.AddTrailingDirectorySeparator(value));
}
}
}
/// <summary>
/// Gets or sets the three letter prefix used for many of the files used by
/// the database engine. For example, the checkpoint file is called EDB.CHK by
/// default because EDB is the default base name.
/// </summary>
public string BaseName
{
get
{
return this.GetStringParameter(JET_param.BaseName);
}
set
{
this.SetStringParameter(JET_param.BaseName, value);
}
}
/// <summary>
/// Gets or sets an application specific string that will be added to
/// any event log messages that are emitted by the database engine. This allows
/// easy correlation of event log messages with the source application. By default
/// the host application executable name will be used.
/// </summary>
public string EventSource
{
get
{
return this.GetStringParameter(JET_param.EventSource);
}
set
{
this.SetStringParameter(JET_param.EventSource, value);
}
}
/// <summary>
/// Gets or sets the number of sessions resources reserved for this instance.
/// A session resource directly corresponds to a JET_SESID.
/// </summary>
public int MaxSessions
{
get
{
return this.GetIntegerParameter(JET_param.MaxSessions);
}
set
{
this.SetIntegerParameter(JET_param.MaxSessions, value);
}
}
/// <summary>
/// Gets or sets the number of B+ Tree resources reserved for this instance.
/// </summary>
public int MaxOpenTables
{
get
{
return this.GetIntegerParameter(JET_param.MaxOpenTables);
}
set
{
this.SetIntegerParameter(JET_param.MaxOpenTables, value);
}
}
/// <summary>
/// Gets or sets the number of cursor resources reserved for this instance.
/// A cursor resource directly corresponds to a JET_TABLEID.
/// </summary>
public int MaxCursors
{
get
{
return this.GetIntegerParameter(JET_param.MaxCursors);
}
set
{
this.SetIntegerParameter(JET_param.MaxCursors, value);
}
}
/// <summary>
/// Gets or sets the maximum number of version store pages reserved
/// for this instance.
/// </summary>
public int MaxVerPages
{
get
{
return this.GetIntegerParameter(JET_param.MaxVerPages);
}
set
{
this.SetIntegerParameter(JET_param.MaxVerPages, value);
}
}
/// <summary>
/// Gets or sets the preferred number of version store pages reserved
/// for this instance. If the size of the version store exceeds this
/// threshold then any information that is only used for optional
/// background tasks, such as reclaiming deleted space in the database,
/// is instead sacrificed to preserve room for transactional information.
/// </summary>
public int PreferredVerPages
{
get
{
return this.GetIntegerParameter(JET_param.PreferredVerPages);
}
set
{
this.SetIntegerParameter(JET_param.PreferredVerPages, value);
}
}
/// <summary>
/// Gets or sets the the number of background cleanup work items that
/// can be queued to the database engine thread pool at any one time.
/// </summary>
public int VersionStoreTaskQueueMax
{
get
{
return this.GetIntegerParameter(JET_param.VersionStoreTaskQueueMax);
}
set
{
this.SetIntegerParameter(JET_param.VersionStoreTaskQueueMax, value);
}
}
/// <summary>
/// Gets or sets the number of temporary table resources for use
/// by an instance. This setting will affect how many temporary tables can be used at
/// the same time. If this system parameter is set to zero then no temporary database
/// will be created and any activity that requires use of the temporary database will
/// fail. This setting can be useful to avoid the I/O required to create the temporary
/// database if it is known that it will not be used.
/// </summary>
/// <remarks>
/// The use of a temporary table also requires a cursor resource.
/// </remarks>
public int MaxTemporaryTables
{
get
{
return this.GetIntegerParameter(JET_param.MaxTemporaryTables);
}
set
{
this.SetIntegerParameter(JET_param.MaxTemporaryTables, value);
}
}
/// <summary>
/// Gets or sets the size of the transaction log files. This parameter
/// should be set in units of 1024 bytes (e.g. a setting of 2048 will
/// give 2MB logfiles).
/// </summary>
public int LogFileSize
{
get
{
return this.GetIntegerParameter(JET_param.LogFileSize);
}
set
{
this.SetIntegerParameter(JET_param.LogFileSize, value);
}
}
/// <summary>
/// Gets or sets the amount of memory used to cache log records
/// before they are written to the transaction log file. The unit for this
/// parameter is the sector size of the volume that holds the transaction log files.
/// The sector size is almost always 512 bytes, so it is safe to assume that size
/// for the unit. This parameter has an impact on performance. When the database
/// engine is under heavy update load, this buffer can become full very rapidly.
/// A larger cache size for the transaction log file is critical for good update
/// performance under such a high load condition. The default is known to be too small
/// for this case.
/// Do not set this parameter to a number of buffers that is larger (in bytes) than
/// half the size of a transaction log file.
/// </summary>
public int LogBuffers
{
get
{
return this.GetIntegerParameter(JET_param.LogBuffers);
}
set
{
this.SetIntegerParameter(JET_param.LogBuffers, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether circular logging is on.
/// When circular logging is off, all transaction log files that are generated
/// are retained on disk until they are no longer needed because a full backup of the
/// database has been performed. When circular logging is on, only transaction log files
/// that are younger than the current checkpoint are retained on disk. The benefit of
/// this mode is that backups are not required to retire old transaction log files.
/// </summary>
public bool CircularLog
{
get
{
return this.GetBoolParameter(JET_param.CircularLog);
}
set
{
this.SetBoolParameter(JET_param.CircularLog, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether JetInit fails when the database
/// engine is configured to start using transaction log files on disk
/// that are of a different size than what is configured. Normally,
/// <see cref="Api.JetInit"/> will successfully recover the databases
/// but will fail with <see cref="JET_err.LogFileSizeMismatchDatabasesConsistent"/>
/// to indicate that the log file size is misconfigured. However, when
/// this parameter is set to true then the database engine will silently
/// delete all the old log files, start a new set of transaction log files
/// using the configured log file size. This parameter is useful when the
/// application wishes to transparently change its transaction log file
/// size yet still work transparently in upgrade and restore scenarios.
/// </summary>
public bool CleanupMismatchedLogFiles
{
get
{
return this.GetBoolParameter(JET_param.CleanupMismatchedLogFiles);
}
set
{
this.SetBoolParameter(JET_param.CleanupMismatchedLogFiles, value);
}
}
/// <summary>
/// Gets or sets the initial size of the temporary database. The size is in
/// database pages. A size of zero indicates that the default size of an ordinary
/// database should be used. It is often desirable for small applications to configure
/// the temporary database to be as small as possible. Setting this parameter to
/// <see cref="SystemParameters.PageTempDBSmallest"/> will achieve the smallest
/// temporary database possible.
/// </summary>
public int PageTempDBMin
{
get
{
return this.GetIntegerParameter(JET_param.PageTempDBMin);
}
set
{
this.SetIntegerParameter(JET_param.PageTempDBMin, value);
}
}
/// <summary>
/// Gets or sets the threshold in bytes for about how many transaction log
/// files will need to be replayed after a crash. If circular logging is enabled using
/// CircularLog then this parameter will also control the approximate amount
/// of transaction log files that will be retained on disk.
/// </summary>
public int CheckpointDepthMax
{
get
{
return this.GetIntegerParameter(JET_param.CheckpointDepthMax);
}
set
{
this.SetIntegerParameter(JET_param.CheckpointDepthMax, value);
}
}
/// <summary>
/// Gets or sets the number of pages that are added to a database file each
/// time it needs to grow to accommodate more data.
/// </summary>
public int DbExtensionSize
{
get
{
return this.GetIntegerParameter(JET_param.DbExtensionSize);
}
set
{
this.SetIntegerParameter(JET_param.DbExtensionSize, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether crash recovery is on.
/// </summary>
public bool Recovery
{
get
{
return 0 == string.Compare(this.GetStringParameter(JET_param.Recovery), "on", StringComparison.OrdinalIgnoreCase);
}
set
{
if (value)
{
this.SetStringParameter(JET_param.Recovery, "on");
}
else
{
this.SetStringParameter(JET_param.Recovery, "off");
}
}
}
/// <summary>
/// Gets or sets a value indicating whether online defragmentation is enabled.
/// </summary>
public bool EnableOnlineDefrag
{
get
{
return this.GetBoolParameter(JET_param.EnableOnlineDefrag);
}
set
{
this.SetBoolParameter(JET_param.EnableOnlineDefrag, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether <see cref="Api.JetAttachDatabase"/> will check for
/// indexes that were build using an older version of the NLS library in the
/// operating system.
/// </summary>
public bool EnableIndexChecking
{
get
{
return this.GetBoolParameter(JET_param.EnableIndexChecking);
}
set
{
this.SetBoolParameter(JET_param.EnableIndexChecking, value);
}
}
/// <summary>
/// Gets or sets the name of the event log the database engine uses for its event log
/// messages. By default, all event log messages will go to the Application event log. If the registry
/// key name for another event log is configured then the event log messages will go there instead.
/// </summary>
public string EventSourceKey
{
get
{
return this.GetStringParameter(JET_param.EventSourceKey);
}
set
{
this.SetStringParameter(JET_param.EventSourceKey, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether informational event
/// log messages that would ordinarily be generated by the
/// database engine will be suppressed.
/// </summary>
public bool NoInformationEvent
{
get
{
return this.GetBoolParameter(JET_param.NoInformationEvent);
}
set
{
this.SetBoolParameter(JET_param.NoInformationEvent, value);
}
}
/// <summary>
/// Gets or sets the detail level of eventlog messages that are emitted
/// to the eventlog by the database engine. Higher numbers will result
/// in more detailed eventlog messages.
/// </summary>
public EventLoggingLevels EventLoggingLevel
{
get
{
return (EventLoggingLevels)this.GetIntegerParameter(JET_param.EventLoggingLevel);
}
set
{
this.SetIntegerParameter(JET_param.EventLoggingLevel, (int)value);
}
}
/// <summary>
/// Gets or sets a value indicating whether only one database is allowed to
/// be opened using JetOpenDatabase by a given session at one time.
/// The temporary database is excluded from this restriction.
/// </summary>
public bool OneDatabasePerSession
{
get
{
return this.GetBoolParameter(JET_param.OneDatabasePerSession);
}
set
{
this.SetBoolParameter(JET_param.OneDatabasePerSession, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether ESENT will silently create folders
/// that are missing in its filesystem paths.
/// </summary>
public bool CreatePathIfNotExist
{
get
{
return this.GetBoolParameter(JET_param.CreatePathIfNotExist);
}
set
{
this.SetBoolParameter(JET_param.CreatePathIfNotExist, value);
}
}
/// <summary>
/// Gets or sets a value giving the number of B+ Tree resources cached by
/// the instance after the tables they represent have been closed by
/// the application. Large values for this parameter will cause the
/// database engine to use more memory but will increase the speed
/// with which a large number of tables can be opened randomly by
/// the application. This is useful for applications that have a
/// schema with a very large number of tables.
/// <para>
/// Supported on Windows Vista and up. Ignored on Windows XP and
/// Windows Server 2003.
/// </para>
/// </summary>
public int CachedClosedTables
{
get
{
if (EsentVersion.SupportsVistaFeatures)
{
return this.GetIntegerParameter(VistaParam.CachedClosedTables);
}
return 0;
}
set
{
if (EsentVersion.SupportsVistaFeatures)
{
this.SetIntegerParameter(VistaParam.CachedClosedTables, value);
}
}
}
/// <summary>
/// Gets or sets a the number of logs that esent will defer database
/// flushes for. This can be used to increase database recoverability if
/// failures cause logfiles to be lost.
/// <para>
/// Supported on Windows 7 and up. Ignored on Windows XP,
/// Windows Server 2003, Windows Vista and Windows Server 2008.
/// </para>
/// </summary>
public int WaypointLatency
{
get
{
if (EsentVersion.SupportsWindows7Features)
{
return this.GetIntegerParameter(Windows7Param.WaypointLatency);
}
// older versions have no waypoint
return 0;
}
set
{
if (EsentVersion.SupportsWindows7Features)
{
this.SetIntegerParameter(Windows7Param.WaypointLatency, value);
}
}
}
/// <summary>
/// Gets or sets a value indicating whether <see cref="Api.JetAttachDatabase"/> will
/// delete indexes that were build using an older version of the NLS library in the
/// operating system.
/// </summary>
public bool EnableIndexCleanup
{
get
{
return this.GetBoolParameter(JET_param.EnableIndexCleanup);
}
set
{
this.SetBoolParameter(JET_param.EnableIndexCleanup, value);
}
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="InstanceParameters"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="InstanceParameters"/>.
/// </returns>
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "InstanceParameters (0x{0:x})", this.instance.Value);
}
/// <summary>
/// Set a system parameter which is a string.
/// </summary>
/// <param name="param">The parameter to set.</param>
/// <param name="value">The value to set.</param>
private void SetStringParameter(JET_param param, string value)
{
Api.JetSetSystemParameter(this.instance, this.sesid, param, 0, value);
}
/// <summary>
/// Get a system parameter which is a string.
/// </summary>
/// <param name="param">The parameter to get.</param>
/// <returns>The value of the parameter.</returns>
private string GetStringParameter(JET_param param)
{
int ignored = 0;
string value;
Api.JetGetSystemParameter(this.instance, this.sesid, param, ref ignored, out value, 1024);
return value;
}
/// <summary>
/// Set a system parameter which is an integer.
/// </summary>
/// <param name="param">The parameter to set.</param>
/// <param name="value">The value to set.</param>
private void SetIntegerParameter(JET_param param, int value)
{
Api.JetSetSystemParameter(this.instance, this.sesid, param, value, null);
}
/// <summary>
/// Get a system parameter which is an integer.
/// </summary>
/// <param name="param">The parameter to get.</param>
/// <returns>The value of the parameter.</returns>
private int GetIntegerParameter(JET_param param)
{
int value = 0;
string ignored;
Api.JetGetSystemParameter(this.instance, this.sesid, param, ref value, out ignored, 0);
return value;
}
/// <summary>
/// Set a system parameter which is a boolean.
/// </summary>
/// <param name="param">The parameter to set.</param>
/// <param name="value">The value to set.</param>
private void SetBoolParameter(JET_param param, bool value)
{
if (value)
{
Api.JetSetSystemParameter(this.instance, this.sesid, param, 1, null);
}
else
{
Api.JetSetSystemParameter(this.instance, this.sesid, param, 0, null);
}
}
/// <summary>
/// Get a system parameter which is a boolean.
/// </summary>
/// <param name="param">The parameter to get.</param>
/// <returns>The value of the parameter.</returns>
private bool GetBoolParameter(JET_param param)
{
int value = 0;
string ignored;
Api.JetGetSystemParameter(this.instance, this.sesid, param, ref value, out ignored, 0);
return value != 0;
}
}
}

View File

@ -1,69 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Int16ColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// An <see cref="short"/> column value.
/// </summary>
public class Int16ColumnValue : ColumnValueOfStruct<short>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(short); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(short), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToInt16(value, startIndex);
}
}
}
}

View File

@ -1,69 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Int32ColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// An <see cref="int"/> column value.
/// </summary>
public class Int32ColumnValue : ColumnValueOfStruct<int>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(int); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(int), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToInt32(value, startIndex);
}
}
}
}

View File

@ -1,69 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Int64ColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// An <see cref="long"/> column value.
/// </summary>
public class Int64ColumnValue : ColumnValueOfStruct<long>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(long); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(long), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToInt64(value, startIndex);
}
}
}
}

View File

@ -1,192 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="InternalApi.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// Internal-only methods of the Api.
/// </summary>
public static partial class Api
{
/// <summary>
/// The JetSetColumn function modifies a single column value in a modified record to be inserted or to
/// update the current record. It can overwrite an existing value, add a new value to a sequence of
/// values in a multi-valued column, remove a value from a sequence of values in a multi-valued column,
/// or update all or part of a long value (a column of type <see cref="JET_coltyp.LongText"/>
/// or <see cref="JET_coltyp.LongBinary"/>).
/// </summary>
/// <remarks>
/// This is an internal-only version of the API that takes a data buffer and an offset into the buffer.
/// </remarks>
/// <param name="sesid">The session which is performing the update.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="dataSize">The size of data to set.</param>
/// <param name="dataOffset">The offset in the data buffer to set data from.</param>
/// <param name="grbit">SetColumn options.</param>
/// <param name="setinfo">Used to specify itag or long-value offset.</param>
/// <returns>A warning value.</returns>
public static JET_wrn JetSetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, int dataSize, int dataOffset, SetColumnGrbit grbit, JET_SETINFO setinfo)
{
if (dataOffset < 0
|| (null != data && 0 != dataSize && dataOffset >= data.Length)
|| (null == data && dataOffset != 0))
{
throw new ArgumentOutOfRangeException(
"dataOffset",
dataOffset,
"must be inside the data buffer");
}
if (null != data && dataSize > checked(data.Length - dataOffset) && (SetColumnGrbit.SizeLV != (grbit & SetColumnGrbit.SizeLV)))
{
throw new ArgumentOutOfRangeException(
"dataSize",
dataSize,
"cannot be greater than the length of the data (unless the SizeLV option is used)");
}
unsafe
{
fixed (byte* pointer = data)
{
return Api.JetSetColumn(sesid, tableid, columnid, new IntPtr(pointer + dataOffset), dataSize, grbit, setinfo);
}
}
}
/// <summary>
/// Retrieves a single column value from the current record. The record is that
/// record associated with the index entry at the current position of the cursor.
/// Alternatively, this function can retrieve a column from a record being created
/// in the cursor copy buffer. This function can also retrieve column data from an
/// index entry that references the current record. In addition to retrieving the
/// actual column value, JetRetrieveColumn can also be used to retrieve the size
/// of a column, before retrieving the column data itself so that application
/// buffers can be sized appropriately.
/// </summary>
/// <remarks>
/// This is an internal method that takes a buffer offset as well as size.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to retrieve the column from.</param>
/// <param name="columnid">The columnid to retrieve.</param>
/// <param name="data">The data buffer to be retrieved into.</param>
/// <param name="dataSize">The size of the data buffer.</param>
/// <param name="dataOffset">Offset into the data buffer to read data into.</param>
/// <param name="actualDataSize">Returns the actual size of the data buffer.</param>
/// <param name="grbit">Retrieve column options.</param>
/// <param name="retinfo">
/// If pretinfo is give as NULL then the function behaves as though an itagSequence
/// of 1 and an ibLongValue of 0 (zero) were given. This causes column retrieval to
/// retrieve the first value of a multi-valued column, and to retrieve long data at
/// offset 0 (zero).
/// </param>
/// <returns>An ESENT warning code.</returns>
public static JET_wrn JetRetrieveColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, int dataSize, int dataOffset, out int actualDataSize, RetrieveColumnGrbit grbit, JET_RETINFO retinfo)
{
if (dataOffset < 0
|| (null != data && 0 != dataSize && dataOffset >= data.Length)
|| (null == data && dataOffset != 0))
{
throw new ArgumentOutOfRangeException(
"dataOffset",
dataOffset,
"must be inside the data buffer");
}
if ((null == data && dataSize > 0) || (null != data && dataSize > data.Length))
{
throw new ArgumentOutOfRangeException(
"dataSize",
dataSize,
"cannot be greater than the length of the data");
}
unsafe
{
fixed (byte* pointer = data)
{
return Api.JetRetrieveColumn(
sesid, tableid, columnid, new IntPtr(pointer + dataOffset), dataSize, out actualDataSize, grbit, retinfo);
}
}
}
/// <summary>
/// Retrieves a single column value from the current record. The record is that
/// record associated with the index entry at the current position of the cursor.
/// Alternatively, this function can retrieve a column from a record being created
/// in the cursor copy buffer. This function can also retrieve column data from an
/// index entry that references the current record. In addition to retrieving the
/// actual column value, JetRetrieveColumn can also be used to retrieve the size
/// of a column, before retrieving the column data itself so that application
/// buffers can be sized appropriately.
/// </summary>
/// <remarks>
/// This is an internal-use version that takes an IntPtr.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to retrieve the column from.</param>
/// <param name="columnid">The columnid to retrieve.</param>
/// <param name="data">The data buffer to be retrieved into.</param>
/// <param name="dataSize">The size of the data buffer.</param>
/// <param name="actualDataSize">Returns the actual size of the data buffer.</param>
/// <param name="grbit">Retrieve column options.</param>
/// <param name="retinfo">
/// If pretinfo is give as NULL then the function behaves as though an itagSequence
/// of 1 and an ibLongValue of 0 (zero) were given. This causes column retrieval to
/// retrieve the first value of a multi-valued column, and to retrieve long data at
/// offset 0 (zero).
/// </param>
/// <returns>An ESENT warning code.</returns>
internal static JET_wrn JetRetrieveColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, IntPtr data, int dataSize, out int actualDataSize, RetrieveColumnGrbit grbit, JET_RETINFO retinfo)
{
return Api.Check(Impl.JetRetrieveColumn(sesid, tableid, columnid, data, dataSize, out actualDataSize, grbit, retinfo));
}
/// <summary>
/// Constructs search keys that may then be used by JetSeek and JetSetIndexRange.
/// </summary>
/// <remarks>
/// This is an internal (unsafe) version that takes an IntPtr.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="dataSize">Size of the data.</param>
/// <param name="grbit">Key options.</param>
internal static void JetMakeKey(JET_SESID sesid, JET_TABLEID tableid, IntPtr data, int dataSize, MakeKeyGrbit grbit)
{
Api.Check(Impl.JetMakeKey(sesid, tableid, data, dataSize, grbit));
}
/// <summary>
/// The JetSetColumn function modifies a single column value in a modified record to be inserted or to
/// update the current record. It can overwrite an existing value, add a new value to a sequence of
/// values in a multi-valued column, remove a value from a sequence of values in a multi-valued column,
/// or update all or part of a long value, a column of type JET_coltyp.LongText or JET_coltyp.LongBinary.
/// </summary>
/// <remarks>
/// This method takes an IntPtr and is intended for internal use only.
/// </remarks>
/// <param name="sesid">The session which is performing the update.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="dataSize">The size of data to set.</param>
/// <param name="grbit">SetColumn options.</param>
/// <param name="setinfo">Used to specify itag or long-value offset.</param>
/// <returns>A warning value.</returns>
internal static JET_wrn JetSetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, IntPtr data, int dataSize, SetColumnGrbit grbit, JET_SETINFO setinfo)
{
return Api.Check(Impl.JetSetColumn(sesid, tableid, columnid, data, dataSize, grbit, setinfo));
}
}
}

View File

@ -1,56 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IntersectIndexesEnumerator.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Enumerator that can intersect indexes and return the intersected bookmarks.
/// </summary>
internal sealed class IntersectIndexesEnumerator : TableEnumerator<byte[]>
{
/// <summary>
/// The ranges to intersect.
/// </summary>
private readonly JET_INDEXRANGE[] ranges;
/// <summary>
/// The recordlist containing the result of the intersection.
/// </summary>
private JET_RECORDLIST recordlist;
/// <summary>
/// Initializes a new instance of the <see cref="IntersectIndexesEnumerator"/> class.
/// </summary>
/// <param name="sesid">
/// The session to use.
/// </param>
/// <param name="ranges">
/// The ranges to intersect.
/// </param>
public IntersectIndexesEnumerator(JET_SESID sesid, JET_INDEXRANGE[] ranges) : base(sesid)
{
this.ranges = ranges;
}
/// <summary>
/// Open the table to be enumerated. This should set <see cref="TableEnumerator{T}.TableidToEnumerate"/>.
/// </summary>
protected override void OpenTable()
{
Api.JetIntersectIndexes(this.Sesid, this.ranges, this.ranges.Length, out this.recordlist, IntersectIndexesGrbit.None);
this.TableidToEnumerate = this.recordlist.tableid;
}
/// <summary>
/// Gets the entry the cursor is currently positioned on.
/// </summary>
/// <returns>The entry the cursor is currently positioned on.</returns>
protected override byte[] GetCurrent()
{
return Api.RetrieveColumn(this.Sesid, this.TableidToEnumerate, this.recordlist.columnidBookmark);
}
}
}

View File

@ -1,44 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="JET_eventlogginglevel.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Options for EventLoggingLevel.
/// </summary>
public enum EventLoggingLevels
{
/// <summary>
/// Disable all events.
/// </summary>
Disable = 0,
/// <summary>
/// Default level. Windows 7 and later.
/// </summary>
Min = 1,
/// <summary>
/// Low verbosity and lower. Windows 7 and later.
/// </summary>
Low = 25,
/// <summary>
/// Medium verbosity and lower. Windows 7 and later.
/// </summary>
Medium = 50,
/// <summary>
/// High verbosity and lower. Windows 7 and later.
/// </summary>
High = 75,
/// <summary>
/// All events.
/// </summary>
Max = 100,
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,175 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="JetCallbackWrapper.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
/// <summary>
/// A multi-purpose callback function used by the database engine to inform
/// the application of an event involving online defragmentation and cursor
/// state notifications.
/// </summary>
/// <param name="sesid">The session for which the callback is being made.</param>
/// <param name="dbid">The database for which the callback is being made.</param>
/// <param name="tableid">The cursor for which the callback is being made.</param>
/// <param name="cbtyp">The operation for which the callback is being made.</param>
/// <param name="arg1">First callback-specific argument.</param>
/// <param name="arg2">Second callback-specific argument.</param>
/// <param name="context">Callback context.</param>
/// <param name="unused">This parameter is not used.</param>
/// <returns>An ESENT error code.</returns>
internal delegate JET_err NATIVE_CALLBACK(
IntPtr sesid,
uint dbid,
IntPtr tableid,
uint cbtyp,
IntPtr arg1,
IntPtr arg2,
IntPtr context,
IntPtr unused);
/// <summary>
/// Wraps a NATIVE_CALLBACK callback around a JET_CALLBACK. This is
/// used to catch exceptions and provide argument conversion.
/// </summary>
internal sealed class JetCallbackWrapper
{
/// <summary>
/// API call tracing.
/// </summary>
private static readonly TraceSwitch TraceSwitch = new TraceSwitch("ESENT JetCallbackWrapper", "Wrapper around unmanaged ESENT callback");
/// <summary>
/// The wrapped status callback.
/// </summary>
private readonly WeakReference wrappedCallback;
/// <summary>
/// The native version of the callback. This will actually be a closure
/// because we are calling a non-static method. Keep track of it here
/// to make sure that it isn't garbage collected.
/// </summary>
private readonly NATIVE_CALLBACK nativeCallback;
#if !MANAGEDESENT_ON_WSA
/// <summary>
/// Initializes static members of the <see cref="JetCallbackWrapper"/> class.
/// </summary>
static JetCallbackWrapper()
{
// We don't want a JIT failure when trying to execute the callback
// because that would throw an exception through ESENT, corrupting it.
// It is fine for the wrapped callback to fail because CallbackImpl
// will catch the exception and deal with it.
RuntimeHelpers.PrepareMethod(typeof(StatusCallbackWrapper).GetMethod(
"CallbackImpl",
BindingFlags.NonPublic | BindingFlags.Instance).MethodHandle);
}
#endif // !MANAGEDESENT_ON_WSA
/// <summary>
/// Initializes a new instance of the JetCallbackWrapper class.
/// </summary>
/// <param name="callback">
/// The managed callback to use.
/// </param>
public JetCallbackWrapper(JET_CALLBACK callback)
{
this.wrappedCallback = new WeakReference(callback);
this.nativeCallback = this.CallbackImpl;
Debug.Assert(this.wrappedCallback.IsAlive, "Callback isn't alive");
}
/// <summary>
/// Gets a value indicating whether the wrapped callback has been garbage
/// collected.
/// </summary>
public bool IsAlive
{
get
{
return this.wrappedCallback.IsAlive;
}
}
/// <summary>
/// Gets a NATIVE_CALLBACK callback that wraps the managed callback.
/// </summary>
public NATIVE_CALLBACK NativeCallback
{
get
{
return this.nativeCallback;
}
}
/// <summary>
/// Determine if the callback is wrapping the specified JET_CALLBACK.
/// </summary>
/// <param name="callback">The callback.</param>
/// <returns>True if this wrapper is wrapping the callback.</returns>
public bool IsWrapping(JET_CALLBACK callback)
{
return callback.Equals(this.wrappedCallback.Target);
}
/// <summary>
/// Callback function for native code. We don't want to throw an exception through
/// unmanaged ESENT because that will corrupt ESENT's internal state. Instead we
/// catch all exceptions and return an error instead. We use a CER to make catching
/// the exceptions as reliable as possible.
/// </summary>
/// <param name="nativeSesid">The session for which the callback is being made.</param>
/// <param name="nativeDbid">The database for which the callback is being made.</param>
/// <param name="nativeTableid">The cursor for which the callback is being made.</param>
/// <param name="nativeCbtyp">The operation for which the callback is being made.</param>
/// <param name="arg1">First callback-specific argument.</param>
/// <param name="arg2">Second callback-specific argument.</param>
/// <param name="nativeContext">Callback context.</param>
/// <param name="unused">This parameter is not used.</param>
/// <returns>An ESENT error code.</returns>
private JET_err CallbackImpl(
IntPtr nativeSesid,
uint nativeDbid,
IntPtr nativeTableid,
uint nativeCbtyp,
IntPtr arg1,
IntPtr arg2,
IntPtr nativeContext,
IntPtr unused)
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
var sesid = new JET_SESID { Value = nativeSesid };
var dbid = new JET_DBID { Value = nativeDbid };
var tableid = new JET_TABLEID { Value = nativeTableid };
JET_cbtyp cbtyp = (JET_cbtyp)nativeCbtyp;
Debug.Assert(this.wrappedCallback.IsAlive, "Wrapped callback has been garbage collected");
// This will throw an exception if the wrapped callback has been collected. The exception
// will be handled below.
JET_CALLBACK callback = (JET_CALLBACK)this.wrappedCallback.Target;
return callback(sesid, dbid, tableid, cbtyp, null, null, nativeContext, IntPtr.Zero);
}
catch (Exception ex)
{
// Thread aborts aren't handled here. ESENT callbacks can execute on client threads or
// internal ESENT threads so it isn't clear what should be done on an abort.
Trace.WriteLineIf(
TraceSwitch.TraceWarning,
string.Format(CultureInfo.InvariantCulture, "Caught Exception {0}", ex));
return JET_err.CallbackFailed;
}
}
}
}

View File

@ -1,67 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="JetCapabilities.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Implementation
{
/// <summary>
/// Describes the functionality exposed by an object which implements IJetApi.
/// </summary>
internal sealed class JetCapabilities
{
/// <summary>
/// Gets or sets a value indicating whether Windows Server 2003 features
/// (in the Interop.Server2003 namespace) are supported.
/// </summary>
public bool SupportsServer2003Features { get; set; }
/// <summary>
/// Gets or sets a value indicating whether Vista features (in the
/// Interop.Vista namespace) are supported.
/// </summary>
public bool SupportsVistaFeatures { get; set; }
/// <summary>
/// Gets or sets a value indicating whether Win7 features (in the
/// Interop.Windows7 namespace) are supported.
/// </summary>
public bool SupportsWindows7Features { get; set; }
/// <summary>
/// Gets or sets a value indicating whether Win8 features (in the
/// Interop.Windows8 namespace) are supported.
/// </summary>
public bool SupportsWindows8Features { get; set; }
/// <summary>
/// Gets or sets a value indicating whether Win8.1 features (in the
/// Interop.Windows81 namespace) are supported.
/// </summary>
public bool SupportsWindows81Features { get; set; }
/// <summary>
/// Gets or sets a value indicating whether Win10 features (in the
/// Interop.Windows10 namespace) are supported.
/// </summary>
public bool SupportsWindows10Features { get; set; }
/// <summary>
/// Gets or sets a value indicating whether unicode file paths are supported.
/// </summary>
public bool SupportsUnicodePaths { get; set; }
/// <summary>
/// Gets or sets a value indicating whether large (> 255 byte) keys are supported.
/// The key size for an index can be specified in the <see cref="JET_INDEXCREATE"/>
/// object.
/// </summary>
public bool SupportsLargeKeys { get; set; }
/// <summary>
/// Gets or sets the maximum number of components in a sort or index key.
/// </summary>
public int ColumnsKeyMost { get; set; }
}
}

View File

@ -1,191 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="jet_indexcreate3.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using Microsoft.Isam.Esent.Interop.Vista;
/// <summary>
/// The native version of the JET_INDEXCREATE3 structure.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules",
"SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.NamingRules",
"SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
internal unsafe struct NATIVE_INDEXCREATE3
{
/// <summary>
/// Size of the structure.
/// </summary>
public uint cbStruct;
/// <summary>
/// Name of the index.
/// </summary>
public IntPtr szIndexName;
/// <summary>
/// Index key description.
/// </summary>
public IntPtr szKey;
/// <summary>
/// Size of index key description.
/// </summary>
public uint cbKey;
/// <summary>
/// Index options.
/// </summary>
public uint grbit;
/// <summary>
/// Index density.
/// </summary>
public uint ulDensity;
/// <summary>
/// Pointer to unicode sort options.
/// </summary>
public NATIVE_UNICODEINDEX2* pidxUnicode;
/// <summary>
/// Maximum size of column data to index. This can also be
/// a pointer to a JET_TUPLELIMITS structure.
/// </summary>
public IntPtr cbVarSegMac;
/// <summary>
/// Pointer to array of conditional columns.
/// </summary>
public IntPtr rgconditionalcolumn;
/// <summary>
/// Count of conditional columns.
/// </summary>
public uint cConditionalColumn;
/// <summary>
/// Returned error from index creation.
/// </summary>
public int err;
/// <summary>
/// Maximum size of the key.
/// </summary>
public uint cbKeyMost;
/// <summary>
/// A <see cref="NATIVE_SPACEHINTS"/> pointer.
/// </summary>
public IntPtr pSpaceHints;
}
/// <summary>
/// Contains the information needed to create an index over data in an ESE database.
/// </summary>
public sealed partial class JET_INDEXCREATE : IContentEquatable<JET_INDEXCREATE>, IDeepCloneable<JET_INDEXCREATE>
{
/// <summary>
/// Gets the native (interop) version of this object, except for
/// <see cref="szIndexName"/> and <see cref="szKey"/>.
/// </summary>
/// <remarks>The cbKey holds the length of the key in bytes, and does not need to be adjusted.</remarks>
/// <returns>The native (interop) version of this object.</returns>
internal NATIVE_INDEXCREATE3 GetNativeIndexcreate3()
{
this.CheckMembersAreValid();
var native = new NATIVE_INDEXCREATE3();
native.cbStruct = checked((uint)Marshal.SizeOf(typeof(NATIVE_INDEXCREATE3)));
// szIndexName and szKey are converted at pinvoke time.
//
// native.szIndexName = this.szIndexName;
// native.szKey = this.szKey;
native.cbKey = checked((uint)this.cbKey * sizeof(char));
native.grbit = unchecked((uint)this.grbit);
native.ulDensity = checked((uint)this.ulDensity);
native.cbVarSegMac = new IntPtr(this.cbVarSegMac);
native.cConditionalColumn = checked((uint)this.cConditionalColumn);
if (0 != this.cbKeyMost)
{
native.cbKeyMost = checked((uint)this.cbKeyMost);
native.grbit |= unchecked((uint)VistaGrbits.IndexKeyMost);
}
return native;
}
/// <summary>
/// Sets only the output fields of the object from a <see cref="NATIVE_INDEXCREATE3"/> struct,
/// specifically <see cref="err"/>.
/// </summary>
/// <param name="value">
/// The native indexcreate to set the values from.
/// </param>
internal void SetFromNativeIndexCreate(ref NATIVE_INDEXCREATE3 value)
{
this.err = (JET_err)value.err;
}
/// <summary>
/// Sets all of the fields (not just output fields) of the object from a <see cref="NATIVE_INDEXCREATE3"/> struct,
/// specifically <see cref="err"/>.
/// </summary>
/// <param name="value">
/// The native indexcreate to set the values from.
/// </param>
internal void SetAllFromNativeIndexCreate(ref NATIVE_INDEXCREATE3 value)
{
this.szIndexName = Marshal.PtrToStringUni(value.szIndexName);
this.cbKey = unchecked((int)value.cbKey / sizeof(char));
this.szKey = Marshal.PtrToStringUni(value.szKey, this.cbKey);
if (this.cbKey != this.szKey.Length)
{
throw new ArgumentException(string.Format("cbKey {0} != szKey.Length {1}", this.cbKey, this.szKey.Length));
}
this.grbit = unchecked((CreateIndexGrbit)value.grbit);
this.ulDensity = unchecked((int)value.ulDensity);
unsafe
{
this.pidxUnicode = new JET_UNICODEINDEX(ref *value.pidxUnicode);
}
this.cbVarSegMac = (int)value.cbVarSegMac;
this.cConditionalColumn = unchecked((int)value.cConditionalColumn);
this.rgconditionalcolumn = new JET_CONDITIONALCOLUMN[this.cConditionalColumn];
int sizeofConditionalColumn = Marshal.SizeOf(typeof(NATIVE_CONDITIONALCOLUMN));
for (int i = 0; i < this.cConditionalColumn; ++i)
{
IntPtr addressOfElement = value.rgconditionalcolumn + i * sizeofConditionalColumn;
NATIVE_CONDITIONALCOLUMN nativeConditionalColumn =
(NATIVE_CONDITIONALCOLUMN)Marshal.PtrToStructure(addressOfElement, typeof(NATIVE_CONDITIONALCOLUMN));
this.rgconditionalcolumn[i] = new JET_CONDITIONALCOLUMN(ref nativeConditionalColumn);
}
this.err = (JET_err)value.err;
this.cbKeyMost = unchecked((int)value.cbKeyMost);
var nativeSpaceHints = (NATIVE_SPACEHINTS)Marshal.PtrToStructure(value.pSpaceHints, typeof(NATIVE_SPACEHINTS));
this.pSpaceHints = new JET_SPACEHINTS();
this.pSpaceHints.SetFromNativeSpaceHints(nativeSpaceHints);
}
}
}

View File

@ -1,97 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="jet_opentemporarytable2.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Vista
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
/// <summary>
/// The native version of the JET_OPENTEMPORARYTABLE2 structure.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules",
"SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.NamingRules",
"SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
internal unsafe struct NATIVE_OPENTEMPORARYTABLE2
{
/// <summary>
/// Size of the structure.
/// </summary>
public uint cbStruct;
/// <summary>
/// Columns to create.
/// </summary>
public NATIVE_COLUMNDEF* prgcolumndef;
/// <summary>
/// Number of entries in prgcolumndef.
/// </summary>
public uint ccolumn;
/// <summary>
/// Optional pointer to unicode index information.
/// </summary>
public NATIVE_UNICODEINDEX2* pidxunicode;
/// <summary>
/// Table options.
/// </summary>
public uint grbit;
/// <summary>
/// Pointer to array of returned columnids. This
/// should have at least ccolumn entries.
/// </summary>
public uint* rgcolumnid;
/// <summary>
/// Maximum key size.
/// </summary>
public uint cbKeyMost;
/// <summary>
/// Maximum amount of data used to construct a key.
/// </summary>
public uint cbVarSegMac;
/// <summary>
/// Returns the tableid of the new table.
/// </summary>
public IntPtr tableid;
}
/// <summary>
/// A collection of parameters for the JetOpenTemporaryTable method.
/// </summary>
public partial class JET_OPENTEMPORARYTABLE
{
/// <summary>
/// Returns the unmanaged opentemporarytable that represents this managed class.
/// </summary>
/// <returns>
/// A native (interop) version of the JET_OPENTEMPORARYTABLE.
/// </returns>
internal NATIVE_OPENTEMPORARYTABLE2 GetNativeOpenTemporaryTable2()
{
this.CheckDataSize();
var openTemporaryTable = new NATIVE_OPENTEMPORARYTABLE2();
openTemporaryTable.cbStruct = checked((uint)Marshal.SizeOf(typeof(NATIVE_OPENTEMPORARYTABLE2)));
openTemporaryTable.ccolumn = checked((uint)this.ccolumn);
openTemporaryTable.grbit = (uint)this.grbit;
openTemporaryTable.cbKeyMost = checked((uint)this.cbKeyMost);
openTemporaryTable.cbVarSegMac = checked((uint)this.cbVarSegMac);
return openTemporaryTable;
}
}
}

View File

@ -1,159 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="jet_tablecreate4.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// The native version of the <see cref="JET_TABLECREATE"/> structure. This includes callbacks,
/// space hints, and uses NATIVE_INDEXCREATE4.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules",
"SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.NamingRules",
"SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
internal unsafe struct NATIVE_TABLECREATE4
{
/// <summary>
/// Size of the structure.
/// </summary>
public uint cbStruct;
/// <summary>
/// Name of the table to create.
/// </summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string szTableName;
/// <summary>
/// Name of the table from which to inherit base DDL.
/// </summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string szTemplateTableName;
/// <summary>
/// Initial pages to allocate for table.
/// </summary>
public uint ulPages;
/// <summary>
/// Table density.
/// </summary>
public uint ulDensity;
/// <summary>
/// Array of column creation info.
/// </summary>
public NATIVE_COLUMNCREATE* rgcolumncreate;
/// <summary>
/// Number of columns to create.
/// </summary>
public uint cColumns;
/// <summary>
/// Array of indices to create, pointer to <see cref="NATIVE_INDEXCREATE3"/>.
/// </summary>
public IntPtr rgindexcreate;
/// <summary>
/// Number of indices to create.
/// </summary>
public uint cIndexes;
/// <summary>
/// Callback function to use for the table.
/// </summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string szCallback;
/// <summary>
/// Type of the callback function.
/// </summary>
public JET_cbtyp cbtyp;
/// <summary>
/// Table options.
/// </summary>
public uint grbit;
/// <summary>
/// Space allocation, maintenance, and usage hints for default sequential index.
/// </summary>
public NATIVE_SPACEHINTS* pSeqSpacehints;
/// <summary>
/// Space allocation, maintenance, and usage hints for Separated LV tree.
/// </summary>
public NATIVE_SPACEHINTS* pLVSpacehints;
/// <summary>
/// Heuristic size to separate a intrinsic LV from the primary record.
/// </summary>
public uint cbSeparateLV;
/// <summary>
/// Returned tableid.
/// </summary>
public IntPtr tableid;
/// <summary>
/// Count of objects created (columns+table+indexes+callbacks).
/// </summary>
public uint cCreated;
}
/// <summary>
/// Contains the information needed to create a table in an ESE database.
/// </summary>
public partial class JET_TABLECREATE : IContentEquatable<JET_TABLECREATE>, IDeepCloneable<JET_TABLECREATE>
{
/// <summary>
/// Gets the native (interop) version of this object. The following members are
/// NOT converted: <see cref="rgcolumncreate"/>, <see cref="rgindexcreate"/>,
/// <see cref="pSeqSpacehints"/>, and <see cref="pLVSpacehints"/>.
/// </summary>
/// <returns>The native (interop) version of this object.</returns>
internal NATIVE_TABLECREATE4 GetNativeTableCreate4()
{
this.CheckMembersAreValid();
var native = new NATIVE_TABLECREATE4();
native.cbStruct = checked((uint)Marshal.SizeOf(typeof(NATIVE_TABLECREATE4)));
native.szTableName = this.szTableName;
native.szTemplateTableName = this.szTemplateTableName;
native.ulPages = checked((uint)this.ulPages);
native.ulDensity = checked((uint)this.ulDensity);
// native.rgcolumncreate is done at pinvoke time.
native.cColumns = checked((uint)this.cColumns);
// native.rgindexcreate is done at pinvoke time.
native.cIndexes = checked((uint)this.cIndexes);
native.szCallback = this.szCallback;
native.cbtyp = this.cbtyp;
native.grbit = checked((uint)this.grbit);
// native.pSeqSpacehints is done at pinvoke time.
// native.pLVSpacehints is done at pinvoke time.
native.cbSeparateLV = checked((uint)this.cbSeparateLV);
native.tableid = this.tableid.Value;
native.cCreated = checked((uint)this.cCreated);
return native;
}
}
}

View File

@ -1,26 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="LegacyFileNames.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Vista
{
/// <summary>
/// Options for LegacyFileNames.
/// </summary>
public enum LegacyFileNames
{
/// <summary>
/// When this option is present then the database engine will use the following naming conventions for its files:
/// o Transaction Log files will use .LOG for their file extension.
/// o Checkpoint files will use .CHK for their file extension.
/// </summary>
ESE98FileNames = 0x00000001,
/// <summary>
/// Preserve the 8.3 naming syntax for as long as possible. (this should not be changed, w/o ensuring there are no log files).
/// </summary>
EightDotThreeSoftCompat = 0x00000002,
}
}

View File

@ -1,273 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="LibraryHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading;
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// Contains several helper functions that are useful in the test binary.
/// In particular, it contains functionality that is not available in
/// reduced-functionality environments (such as CoreClr).
/// </summary>
internal static class LibraryHelpers
{
/// <summary>Provides a platform-specific character used to separate directory levels in a path string that reflects a hierarchical file system organization.</summary>
/// <filterpriority>1</filterpriority>
public static readonly char DirectorySeparatorChar = '\\';
/// <summary>Provides a platform-specific alternate character used to separate directory levels in a path string that reflects a hierarchical file system organization.</summary>
/// <filterpriority>1</filterpriority>
public static readonly char AltDirectorySeparatorChar = '/';
/// <summary>
/// Gets an ASCII encoder.
/// </summary>
public static Encoding EncodingASCII
{
get
{
#if MANAGEDESENT_ON_CORECLR
return SlowAsciiEncoding.Encoding;
#else
return Encoding.ASCII;
#endif
}
}
/// <summary>
/// Gets a new ASCII encoder. It's preferred to use EncodingASCII, but some applications (e.g. tests)
/// may want a different Encoding object.
/// </summary>
public static Encoding NewEncodingASCII
{
get
{
#if MANAGEDESENT_ON_CORECLR
return new SlowAsciiEncoding();
#else
return new ASCIIEncoding();
#endif
}
}
// This should be dead code when running on Core CLR; This is only called by
// GetIndexInfoFromIndexlist() when called on a pre-Win8 system, and Core CLR
// is only on Win8 anyway.
#if !MANAGEDESENT_ON_CORECLR
/// <summary>
/// Creates a CultureInfo object when given the LCID.
/// </summary>
/// <param name="lcid">
/// The lcid passed in.
/// </param>
/// <returns>
/// A CultureInfo object.
/// </returns>
public static CultureInfo CreateCultureInfoByLcid(int lcid)
{
return new CultureInfo(lcid);
}
#endif // !MANAGEDESENT_ON_CORECLR
/// <summary>
/// Allocates memory on the native heap.
/// </summary>
/// <returns>A pointer to native memory.</returns>
/// <param name="size">The size of the memory desired.</param>
public static IntPtr MarshalAllocHGlobal(int size)
{
#if MANAGEDESENT_ON_CORECLR && !MANAGEDESENT_ON_WSA
return Win32.NativeMethods.LocalAlloc(0, new UIntPtr((uint)size));
#else
return Marshal.AllocHGlobal(size);
#endif
}
/// <summary>
/// Frees memory that was allocated on the native heap.
/// </summary>
/// <param name="buffer">A pointer to native memory.</param>
public static void MarshalFreeHGlobal(IntPtr buffer)
{
#if MANAGEDESENT_ON_CORECLR && !MANAGEDESENT_ON_WSA
Win32.NativeMethods.LocalFree(buffer);
#else
Marshal.FreeHGlobal(buffer);
#endif
}
/// <summary>Copies the contents of a managed <see cref="T:System.String" /> into unmanaged memory.</summary>
/// <returns>The address, in unmanaged memory, to where the <paramref name="managedString" /> was copied, or 0 if <paramref name="managedString" /> is null.</returns>
/// <param name="managedString">A managed string to be copied.</param>
/// <exception cref="T:System.OutOfMemoryException">The method could not allocate enough native heap memory.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="managedString" /> parameter exceeds the maximum length allowed by the operating system.</exception>
public static IntPtr MarshalStringToHGlobalUni(string managedString)
{
#if MANAGEDESENT_ON_CORECLR && !MANAGEDESENT_ON_WSA
return MyStringToHGlobalUni(managedString);
#else
return Marshal.StringToHGlobalUni(managedString);
#endif
}
/// <summary>
/// Retrieves the managed ID of the current thread.
/// </summary>
/// <returns>The ID of the current thread.</returns>
public static int GetCurrentManagedThreadId()
{
#if MANAGEDESENT_ON_CORECLR
return Environment.CurrentManagedThreadId;
#else
return Thread.CurrentThread.ManagedThreadId;
#endif
}
/// <summary>
/// Cancels an <see cref="M:System.Threading.Thread.Abort(System.Object)"/> requested for the current thread.
/// </summary>
/// <exception cref="T:System.Threading.ThreadStateException">Abort was not invoked on the current thread. </exception><exception cref="T:System.Security.SecurityException">The caller does not have the required security permission for the current thread. </exception><filterpriority>2</filterpriority><PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="ControlThread"/></PermissionSet>
public static void ThreadResetAbort()
{
#if MANAGEDESENT_ON_CORECLR
// Do nothing.
#else
Thread.ResetAbort();
#endif
}
// FUTURE-2013/12/16-martinc. It appears that all of this hacking for running on Core CLR may no longer be necessary.
// We initially ported to an early version of Core CLR that had a lot of functionality missing. By the time
// Windows Store Apps came out in Windows 8, many of these functions were added back.
#if MANAGEDESENT_ON_CORECLR && !MANAGEDESENT_ON_WSA
// System.Runtime.InteropServices.Marshal
/// <summary>Copies the contents of a managed <see cref="T:System.String" /> into unmanaged memory.</summary>
/// <returns>The address, in unmanaged memory, to where the <paramref name="managedString" /> was copied, or 0 if <paramref name="managedString" /> is null.</returns>
/// <param name="managedString">A managed string to be copied.</param>
/// <exception cref="T:System.OutOfMemoryException">The method could not allocate enough native heap memory.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="managedString" /> parameter exceeds the maximum length allowed by the operating system.</exception>
[SecurityCritical]
private static unsafe IntPtr MyStringToHGlobalUni(string managedString)
{
if (managedString == null)
{
return IntPtr.Zero;
}
int charCountWithNull = managedString.Length + 1;
int byteCount = charCountWithNull * sizeof(char);
if (byteCount < managedString.Length)
{
throw new ArgumentOutOfRangeException("managedString");
}
UIntPtr sizetdwBytes = new UIntPtr((uint)byteCount);
IntPtr rawBuffer = Win32.NativeMethods.LocalAlloc(0, sizetdwBytes);
if (rawBuffer == IntPtr.Zero)
{
throw new OutOfMemoryException();
}
fixed (char* sourcePointer = managedString)
{
byte* destPointer = (byte*)rawBuffer;
var unicodeEncoding = new System.Text.UnicodeEncoding();
int bytesWritten = unicodeEncoding.GetBytes(sourcePointer, charCountWithNull, destPointer, byteCount);
}
return rawBuffer;
}
#endif // MANAGEDESENT_ON_CORECLR && !MANAGEDESENT_ON_WSA
/// <summary>Returns a <see cref="T:System.DateTime" /> equivalent to the specified OLE Automation Date.</summary>
/// <returns>A <see cref="T:System.DateTime" /> that represents the same date and time as <paramref name="d" />.</returns>
/// <param name="d">An OLE Automation Date value. </param>
/// <exception cref="T:System.ArgumentException">The date is not a valid OLE Automation Date value. </exception>
/// <filterpriority>1</filterpriority>
public static DateTime FromOADate(double d)
{
#if MANAGEDESENT_ON_CORECLR
return new DateTime(DoubleDateToTicks(d), DateTimeKind.Unspecified);
#else
return DateTime.FromOADate(d);
#endif
}
#if MANAGEDESENT_ON_CORECLR
/// <summary>
/// Copied from the reflected implementation.
/// </summary>
/// <param name="value">The date, as a 64bit integer.</param>
/// <returns>The date, as a double representation.</returns>
internal static double TicksToOADate(long value)
{
if (value == 0L)
{
return 0.0;
}
if (value < 864000000000L)
{
value += 599264352000000000L;
}
if (value < 31241376000000000L)
{
throw new OverflowException();
}
long num = (value - 599264352000000000L) / 10000L;
if (num < 0L)
{
long num2 = num % 86400000L;
if (num2 != 0L)
{
num -= (86400000L + num2) * 2L;
}
}
return (double)num / 86400000.0;
}
/// <summary>
/// Copied from the reflected implementation.
/// </summary>
/// <param name="value">The date, as a double representation.</param>
/// <returns>The date, as a 64bit integer.</returns>
internal static long DoubleDateToTicks(double value)
{
if (value >= 2958466.0 || value <= -657435.0)
{
throw new ArgumentException("value does not represent a valid date", "value");
}
long num = (long)((value * 86400000.0) + ((value >= 0.0) ? 0.5 : -0.5));
if (num < 0L)
{
num -= (num % 86400000L) * 2L;
}
num += 59926435200000L;
if (num < 0L || num >= 315537897600000L)
{
throw new ArgumentException("value does not represent a valid date", "value");
}
return num * 10000L;
}
#endif
}
}

View File

@ -1,321 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="MakeKeyHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Text;
/// <summary>
/// Helper methods for the ESENT API. These do data conversion for
/// JetMakeKey.
/// </summary>
public static partial class Api
{
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, byte[] data, MakeKeyGrbit grbit)
{
if (null == data)
{
Api.JetMakeKey(sesid, tableid, null, 0, grbit);
}
else if (0 == data.Length)
{
Api.JetMakeKey(sesid, tableid, data, data.Length, grbit | MakeKeyGrbit.KeyDataZeroLength);
}
else
{
Api.JetMakeKey(sesid, tableid, data, data.Length, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="encoding">The encoding used to convert the string.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, string data, Encoding encoding, MakeKeyGrbit grbit)
{
CheckEncodingIsValid(encoding);
if (null == data)
{
Api.JetMakeKey(sesid, tableid, null, 0, grbit);
}
else if (0 == data.Length)
{
Api.JetMakeKey(sesid, tableid, null, 0, grbit | MakeKeyGrbit.KeyDataZeroLength);
}
else if (Encoding.Unicode == encoding)
{
// Optimization for Unicode strings
unsafe
{
fixed (char* buffer = data)
{
Api.JetMakeKey(sesid, tableid, new IntPtr(buffer), checked(data.Length * sizeof(char)), grbit);
}
}
}
else
{
#if MANAGEDESENT_ON_WSA
// Encoding.GetBytes(char*, int, byte*, int) overload is missing in new Windows UI.
// So we can't use the ColumnCache. We'll just use a different GetBytes() overload.
byte[] buffer = encoding.GetBytes(data);
Api.JetMakeKey(sesid, tableid, buffer, buffer.Length, grbit);
#else
// Convert the string using a cached column buffer. The column buffer is far larger
// than the maximum key size, so any data truncation here won't matter.
byte[] buffer = null;
try
{
buffer = Caches.ColumnCache.Allocate();
int dataSize;
unsafe
{
fixed (char* chars = data)
fixed (byte* bytes = buffer)
{
dataSize = encoding.GetBytes(chars, data.Length, bytes, buffer.Length);
}
}
JetMakeKey(sesid, tableid, buffer, dataSize, grbit);
}
finally
{
if (buffer != null)
{
Caches.ColumnCache.Free(ref buffer);
}
}
#endif
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, bool data, MakeKeyGrbit grbit)
{
byte b = data ? (byte)0xff : (byte)0x0;
Api.MakeKey(sesid, tableid, b, grbit);
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, byte data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(byte);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, short data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(short);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, int data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(int);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, long data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(long);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, Guid data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = 16 /* sizeof(Guid) */;
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, DateTime data, MakeKeyGrbit grbit)
{
Api.MakeKey(sesid, tableid, data.ToOADate(), grbit);
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, float data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(float);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, double data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(double);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
[CLSCompliant(false)]
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, ushort data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(ushort);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
[CLSCompliant(false)]
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, uint data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(uint);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
[CLSCompliant(false)]
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, ulong data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(ulong);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
}
}

View File

@ -1,151 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="MemoryCache.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Threading;
/// <summary>
/// Cache allocated chunks of memory that are needed for very short periods
/// of time. The memory is not zeroed on allocation.
/// </summary>
internal sealed class MemoryCache
{
/// <summary>
/// A zero-length array that should be used whenever we want to return one.
/// </summary>
private static readonly byte[] ZeroLengthArray = new byte[0];
/// <summary>
/// Default size for newly allocated buffers.
/// </summary>
private readonly int bufferSize;
/// <summary>
/// Currently cached buffers.
/// </summary>
private readonly byte[][] cachedBuffers;
/// <summary>
/// Initializes a new instance of the <see cref="MemoryCache"/> class.
/// </summary>
/// <param name="bufferSize">
/// The size of the buffers to cache.
/// </param>
/// <param name="maxCachedBuffers">
/// The maximum number of buffers to cache.
/// </param>
public MemoryCache(int bufferSize, int maxCachedBuffers)
{
this.bufferSize = bufferSize;
this.cachedBuffers = new byte[maxCachedBuffers][];
}
/// <summary>
/// Gets the size of the buffers that this cache returns.
/// </summary>
public int BufferSize
{
get
{
return this.bufferSize;
}
}
/// <summary>
/// Creates a new array containing a copy of 'length' bytes of data.
/// </summary>
/// <param name="data">The data to copy.</param>
/// <param name="length">The length of data to copy.</param>
/// <returns>An array containing the first length bytes of data.</returns>
public static byte[] Duplicate(byte[] data, int length)
{
Debug.Assert(data.Length >= length, "length parameter is too long");
if (0 == length)
{
return ZeroLengthArray;
}
var output = new byte[length];
Buffer.BlockCopy(data, 0, output, 0, length);
return output;
}
/// <summary>
/// Allocates a chunk of memory. If memory is cached it is returned. If no memory
/// is cached then it is allocated. Check the size of the returned buffer to determine
/// how much memory was allocated.
/// </summary>
/// <returns>A new memory buffer.</returns>
public byte[] Allocate()
{
int offset = this.GetStartingOffset();
for (int i = 0; i < this.cachedBuffers.Length; ++i)
{
int index = (i + offset) % this.cachedBuffers.Length;
byte[] buffer = Interlocked.Exchange(ref this.cachedBuffers[index], null);
if (null != buffer)
{
return buffer;
}
}
return new byte[this.bufferSize];
}
/// <summary>
/// Frees an unused buffer. This may be added to the cache.
/// </summary>
/// <param name="data">The memory to free.</param>
public void Free(ref byte[] data)
{
if (null == data)
{
throw new ArgumentNullException("data");
}
if (data.Length != this.bufferSize)
{
throw new ArgumentOutOfRangeException("data", data.Length, "buffer is not correct size for this MemoryCache");
}
int offset = this.GetStartingOffset();
// The buffers are garbage collected so we don't need to make Free()
// completely safe. In a multi-threaded situation we may see a null
// slot and then overwrite a buffer which was just freed into the slot.
// That will cause us to lose a buffer which could have been placed
// in a different slot, but in return we can do the Free() without
// expensive interlocked operations.
for (int i = 0; i < this.cachedBuffers.Length; ++i)
{
int index = (i + offset) % this.cachedBuffers.Length;
if (null == this.cachedBuffers[index])
{
this.cachedBuffers[index] = data;
break;
}
}
data = null;
}
/// <summary>
/// Get the offset in the cached buffers array to start allocating or freeing
/// buffers to. This is done so that all threads don't start operating on
/// slot zero, which would increase contention.
/// </summary>
/// <returns>The starting offset for Allocate/Free operations.</returns>
private int GetStartingOffset()
{
// Using the current CPU number would be ideal, but there doesn't seem to
// be a cheap way to get that information in managed code.
return LibraryHelpers.GetCurrentManagedThreadId() % this.cachedBuffers.Length;
}
}
}

View File

@ -1,294 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="MetaDataHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// Helper methods for the ESENT API. These methods deal with database
/// meta-data.
/// </summary>
public static partial class Api
{
#region Simpler API. Overloads that omit unused/obsolete parameters.
/// <summary>
/// Initialize a new ESENT session.
/// </summary>
/// <param name="instance">The initialized instance to create the session in.</param>
/// <param name="sesid">Returns the created session.</param>
public static void BeginSession(JET_INSTANCE instance, out JET_SESID sesid)
{
Api.JetBeginSession(instance, out sesid, null, null);
}
/// <summary>
/// Creates and attaches a database file.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="database">The path to the database file to create.</param>
/// <param name="dbid">Returns the dbid of the new database.</param>
/// <param name="grbit">Database creation options.</param>
public static void CreateDatabase(JET_SESID sesid, string database, out JET_DBID dbid, CreateDatabaseGrbit grbit)
{
Api.JetCreateDatabase(sesid, database, null, out dbid, grbit);
}
/// <summary>
/// Opens a database previously attached with <see cref="JetAttachDatabase"/>,
/// for use with a database session. This function can be called multiple times
/// for the same database.
/// </summary>
/// <param name="sesid">The session that is opening the database.</param>
/// <param name="database">The database to open.</param>
/// <param name="dbid">Returns the dbid of the attached database.</param>
/// <param name="grbit">Open database options.</param>
/// <returns>An ESENT warning code.</returns>
public static JET_wrn OpenDatabase(
JET_SESID sesid,
string database,
out JET_DBID dbid,
OpenDatabaseGrbit grbit)
{
return Api.JetOpenDatabase(sesid, database, null, out dbid, grbit);
}
/// <summary>
/// Opens a cursor on a previously created table.
/// </summary>
/// <param name="sesid">The database session to use.</param>
/// <param name="dbid">The database to open the table in.</param>
/// <param name="tablename">The name of the table to open.</param>
/// <param name="grbit">Table open options.</param>
/// <param name="tableid">Returns the opened table.</param>
/// <returns>An ESENT warning.</returns>
public static JET_wrn OpenTable(
JET_SESID sesid,
JET_DBID dbid,
string tablename,
OpenTableGrbit grbit,
out JET_TABLEID tableid)
{
return Api.JetOpenTable(sesid, dbid, tablename, null, 0, grbit, out tableid);
}
#endregion
/// <summary>
/// Try to open a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database to look for the table in.</param>
/// <param name="tablename">The name of the table.</param>
/// <param name="grbit">Table open options.</param>
/// <param name="tableid">Returns the opened tableid.</param>
/// <returns>True if the table was opened, false if the table doesn't exist.</returns>
public static bool TryOpenTable(
JET_SESID sesid,
JET_DBID dbid,
string tablename,
OpenTableGrbit grbit,
out JET_TABLEID tableid)
{
var err = (JET_err)Impl.JetOpenTable(sesid, dbid, tablename, null, 0, grbit, out tableid);
if (JET_err.ObjectNotFound == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
/// <summary>
/// Creates a dictionary which maps column names to their column IDs.
/// </summary>
/// <param name="sesid">The sesid to use.</param>
/// <param name="tableid">The table to retrieve the information for.</param>
/// <returns>A dictionary mapping column names to column IDs.</returns>
public static IDictionary<string, JET_COLUMNID> GetColumnDictionary(JET_SESID sesid, JET_TABLEID tableid)
{
JET_COLUMNLIST columnlist;
JetGetTableColumnInfo(sesid, tableid, string.Empty, out columnlist);
// As of Sep 2015, JetGetColumnInfoW is only called for Win8+. Even though Unicode should have
// worked in Win7, it wasn't reliable until Win8.
Encoding encodingOfTextColumns = EsentVersion.SupportsWindows8Features ? Encoding.Unicode : LibraryHelpers.EncodingASCII;
try
{
// esent treats column names as case-insensitive, so we want the dictionary to be case insensitive as well
var dict = new Dictionary<string, JET_COLUMNID>(
columnlist.cRecord, StringComparer.OrdinalIgnoreCase);
if (columnlist.cRecord > 0)
{
if (Api.TryMoveFirst(sesid, columnlist.tableid))
{
do
{
string name = RetrieveColumnAsString(
sesid,
columnlist.tableid,
columnlist.columnidcolumnname,
encodingOfTextColumns,
RetrieveColumnGrbit.None);
name = StringCache.TryToIntern(name);
var columnidValue =
(uint)RetrieveColumnAsUInt32(sesid, columnlist.tableid, columnlist.columnidcolumnid);
var columnid = new JET_COLUMNID { Value = columnidValue };
dict.Add(name, columnid);
}
while (TryMoveNext(sesid, columnlist.tableid));
}
}
return dict;
}
finally
{
// Close the temporary table used to return the results
JetCloseTable(sesid, columnlist.tableid);
}
}
/// <summary>
/// Get the columnid of the specified column.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table containing the column.</param>
/// <param name="columnName">The name of the column.</param>
/// <returns>The id of the column.</returns>
public static JET_COLUMNID GetTableColumnid(JET_SESID sesid, JET_TABLEID tableid, string columnName)
{
JET_COLUMNDEF columndef;
JetGetTableColumnInfo(sesid, tableid, columnName, out columndef);
return columndef.columnid;
}
/// <summary>
/// Iterates over all the columns in the table, returning information about each one.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to retrieve column information for.</param>
/// <returns>An iterator over ColumnInfo for each column in the table.</returns>
public static IEnumerable<ColumnInfo> GetTableColumns(JET_SESID sesid, JET_TABLEID tableid)
{
return new GenericEnumerable<ColumnInfo>(() => new TableidColumnInfoEnumerator(sesid, tableid));
}
/// <summary>
/// Iterates over all the columns in the table, returning information about each one.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database containing the table.</param>
/// <param name="tablename">The name of the table.</param>
/// <returns>An iterator over ColumnInfo for each column in the table.</returns>
public static IEnumerable<ColumnInfo> GetTableColumns(JET_SESID sesid, JET_DBID dbid, string tablename)
{
if (null == tablename)
{
throw new ArgumentNullException("tablename");
}
return new GenericEnumerable<ColumnInfo>(() => new TableColumnInfoEnumerator(sesid, dbid, tablename));
}
/// <summary>
/// Iterates over all the indexes in the table, returning information about each one.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to retrieve index information for.</param>
/// <returns>An iterator over an IndexInfo for each index in the table.</returns>
public static IEnumerable<IndexInfo> GetTableIndexes(JET_SESID sesid, JET_TABLEID tableid)
{
return new GenericEnumerable<IndexInfo>(() => new TableidIndexInfoEnumerator(sesid, tableid));
}
/// <summary>
/// Iterates over all the indexs in the table, returning information about each one.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database containing the table.</param>
/// <param name="tablename">The name of the table.</param>
/// <returns>An iterator over an IndexInfo for each index in the table.</returns>
public static IEnumerable<IndexInfo> GetTableIndexes(JET_SESID sesid, JET_DBID dbid, string tablename)
{
if (null == tablename)
{
throw new ArgumentNullException("tablename");
}
return new GenericEnumerable<IndexInfo>(() => new TableIndexInfoEnumerator(sesid, dbid, tablename));
}
/// <summary>
/// Returns the names of the tables in the database.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database containing the table.</param>
/// <returns>An iterator over the names of the tables in the database.</returns>
public static IEnumerable<string> GetTableNames(JET_SESID sesid, JET_DBID dbid)
{
return new GenericEnumerable<string>(() => new TableNameEnumerator(sesid, dbid));
}
/// <summary>
/// Retrieves information about indexes on a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to retrieve index information about.</param>
/// <param name="indexname">The name of the index.</param>
/// <param name="result">Filled in with information about indexes on the table.</param>
/// <param name="infoLevel">The type of information to retrieve.</param>
/// <returns>true if there was no error, false if the index wasn't found. Throws for other Jet errors.</returns>
public static bool TryJetGetTableIndexInfo(
JET_SESID sesid,
JET_TABLEID tableid,
string indexname,
out JET_INDEXID result,
JET_IdxInfo infoLevel)
{
int err = Impl.JetGetTableIndexInfo(sesid, tableid, indexname, out result, infoLevel);
if ((JET_err)err == JET_err.IndexNotFound)
{
return false;
}
Api.Check(err);
return true;
}
/// <summary>
/// Determines the name of the current index of a given cursor.
/// </summary>
/// <remarks>
/// This name is also used to later re-select that index as the current index using
/// <see cref="JetSetCurrentIndex"/>. It can also be used to discover the properties of that index using
/// JetGetTableIndexInfo.
///
/// The returned name of the index will be null if the current index is the clustered index and no primary
/// index was explicitly defined.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to get the index name for.</param>
/// <returns>Returns the name of the index.</returns>
public static string JetGetCurrentIndex(JET_SESID sesid, JET_TABLEID tableid)
{
string indexName;
Api.JetGetCurrentIndex(sesid, tableid, out indexName, SystemParameters.NameMost);
return string.IsNullOrEmpty(indexName) ? null : indexName;
}
}
}

View File

@ -1,244 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="MoveHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
/// <summary>
/// Helper methods for the ESENT API. These aren't interop versions
/// of the API, but encapsulate very common uses of the functions.
/// </summary>
public static partial class Api
{
/// <summary>
/// Position the cursor before the first record in the table. A
/// subsequent move next will position the cursor on the first
/// record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to position.</param>
public static void MoveBeforeFirst(JET_SESID sesid, JET_TABLEID tableid)
{
Api.TryMoveFirst(sesid, tableid);
Api.TryMovePrevious(sesid, tableid);
}
/// <summary>
/// Position the cursor after the last record in the table. A
/// subsequent move previous will position the cursor on the
/// last record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to position.</param>
public static void MoveAfterLast(JET_SESID sesid, JET_TABLEID tableid)
{
Api.TryMoveLast(sesid, tableid);
Api.TryMoveNext(sesid, tableid);
}
/// <summary>
/// Try to navigate through an index. If the navigation succeeds this
/// method returns true. If there is no record to navigate to this
/// method returns false; an exception will be thrown for other errors.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <param name="move">The direction to move in.</param>
/// <param name="grbit">Move options.</param>
/// <returns>True if the move was successful.</returns>
public static bool TryMove(JET_SESID sesid, JET_TABLEID tableid, JET_Move move, MoveGrbit grbit)
{
var err = (JET_err)Impl.JetMove(sesid, tableid, (int)move, grbit);
if (JET_err.NoCurrentRecord == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
/// <summary>
/// Try to move to the first record in the table. If the table is empty this
/// returns false, if a different error is encountered an exception is thrown.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <returns>True if the move was successful.</returns>
public static bool TryMoveFirst(JET_SESID sesid, JET_TABLEID tableid)
{
return TryMove(sesid, tableid, JET_Move.First, MoveGrbit.None);
}
/// <summary>
/// Try to move to the last record in the table. If the table is empty this
/// returns false, if a different error is encountered an exception is thrown.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <returns>True if the move was successful.</returns>
public static bool TryMoveLast(JET_SESID sesid, JET_TABLEID tableid)
{
return TryMove(sesid, tableid, JET_Move.Last, MoveGrbit.None);
}
/// <summary>
/// Try to move to the next record in the table. If there is not a next record
/// this returns false, if a different error is encountered an exception is thrown.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <returns>True if the move was successful.</returns>
public static bool TryMoveNext(JET_SESID sesid, JET_TABLEID tableid)
{
return TryMove(sesid, tableid, JET_Move.Next, MoveGrbit.None);
}
/// <summary>
/// Try to move to the previous record in the table. If there is not a previous record
/// this returns false, if a different error is encountered an exception is thrown.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <returns>True if the move was successful.</returns>
public static bool TryMovePrevious(JET_SESID sesid, JET_TABLEID tableid)
{
return TryMove(sesid, tableid, JET_Move.Previous, MoveGrbit.None);
}
/// <summary>
/// Efficiently positions a cursor to an index entry that matches the search
/// criteria specified by the search key in that cursor and the specified
/// inequality. A search key must have been previously constructed using JetMakeKey.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <param name="grbit">Seek option.</param>
/// <returns>True if a record matching the criteria was found.</returns>
public static bool TrySeek(JET_SESID sesid, JET_TABLEID tableid, SeekGrbit grbit)
{
var err = (JET_err)Impl.JetSeek(sesid, tableid, grbit);
if (JET_err.RecordNotFound == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
/// <summary>
/// Temporarily limits the set of index entries that the cursor can walk using
/// JetMove to those starting from the current index entry and ending at the index
/// entry that matches the search criteria specified by the search key in that cursor
/// and the specified bound criteria. A search key must have been previously constructed
/// using JetMakeKey. Returns true if the index range is non-empty, false otherwise.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <param name="grbit">Seek option.</param>
/// <returns>True if the seek was successful.</returns>
public static bool TrySetIndexRange(JET_SESID sesid, JET_TABLEID tableid, SetIndexRangeGrbit grbit)
{
var err = (JET_err)Impl.JetSetIndexRange(sesid, tableid, grbit);
if (JET_err.NoCurrentRecord == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
/// <summary>
/// Removes an index range created with <see cref="JetSetIndexRange"/> or
/// <see cref="TrySetIndexRange"/>. If no index range is present this
/// method does nothing.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to remove the index range on.</param>
public static void ResetIndexRange(JET_SESID sesid, JET_TABLEID tableid)
{
var err = (JET_err)Impl.JetSetIndexRange(sesid, tableid, SetIndexRangeGrbit.RangeRemove);
if (JET_err.InvalidOperation == err)
{
// this error is expected if there isn't currently an index range
return;
}
Api.Check((int)err);
return;
}
/// <summary>
/// Intersect a group of index ranges and return the bookmarks of the records which are found
/// in all the index ranges.
/// Also see <see cref="JetIntersectIndexes"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableids">
/// The tableids to use. Each tableid must be from a different index on the same table and
/// have an active index range. Use <see cref="JetSetIndexRange"/>
/// to create an index range.
/// </param>
/// <returns>
/// The bookmarks of the records which are found in all the index ranges. The bookmarks
/// are returned in primary key order.
/// </returns>
public static IEnumerable<byte[]> IntersectIndexes(JET_SESID sesid, params JET_TABLEID[] tableids)
{
if (null == tableids)
{
throw new ArgumentNullException("tableids");
}
var ranges = new JET_INDEXRANGE[tableids.Length];
for (int i = 0; i < tableids.Length; ++i)
{
ranges[i] = new JET_INDEXRANGE { tableid = tableids[i] };
}
return new GenericEnumerable<byte[]>(() => new IntersectIndexesEnumerator(sesid, ranges));
}
/// <summary>
/// Positions a cursor to an index entry for the record that is associated with
/// the specified bookmark. The bookmark can be used with any index defined over
/// a table. The bookmark for a record can be retrieved using <see cref="JetGetBookmark"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <param name="bookmark">The bookmark used to position the cursor.</param>
/// <param name="bookmarkSize">The size of the bookmark.</param>
/// <returns>True if a record matching the bookmark was found.</returns>
public static bool TryGotoBookmark(JET_SESID sesid, JET_TABLEID tableid, byte[] bookmark, int bookmarkSize)
{
var err = (JET_err)Impl.JetGotoBookmark(sesid, tableid, bookmark, bookmarkSize);
// Return false if the record no longer exists.
if (JET_err.RecordDeleted == err)
{
return false;
}
// Return false if there is no entry for this record on the current (secondary) index.
if (JET_err.NoCurrentRecord == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,53 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ObjectInfoFlags.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// Flags for ESENT objects (tables). Used in <see cref="JET_OBJECTINFO"/>.
/// </summary>
[Flags]
public enum ObjectInfoFlags
{
/// <summary>
/// Default options.
/// </summary>
None = 0,
/// <summary>
/// Object is for internal use only.
/// </summary>
System = -2147483648, // 0x80000000
// It's possible to use bit shift to avoid triggering fxcop CA2217.
// System = (long)0x1L << 31, // 0x80000000;
// (http://social.msdn.microsoft.com/Forums/en-US/vstscode/thread/a44aa5c1-c62a-46b7-8009-dc46ba21ba93)
// But we don't want to change the type of the enum to a long.
/// <summary>
/// Table's DDL is fixed.
/// </summary>
TableFixedDDL = 0x40000000,
/// <summary>
/// Table's DDL is inheritable.
/// </summary>
TableTemplate = 0x20000000,
/// <summary>
/// Table's DDL is inherited from a template table.
/// </summary>
TableDerived = 0x10000000,
/// <summary>
/// Fixed or variable columns in derived tables (so that fixed or variable
/// columns can be added to the template in the future).
/// Used in conjunction with <see cref="TableTemplate"/>.
/// </summary>
TableNoFixedVarColumnsInDerivedTables = 0x04000000,
}
}

View File

@ -1,52 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ObsoleteApi.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// API members that are marked as obsolete.
/// </summary>
public static partial class Api
{
/// <summary>
/// Retrieves information about indexes on a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database to use.</param>
/// <param name="tablename">The name of the table to retrieve index information about.</param>
/// <param name="ignored">This parameter is ignored.</param>
/// <param name="indexlist">Filled in with information about indexes on the table.</param>
[Obsolete("Use the overload that takes a JET_IdxInfo parameter, passing in JET_IdxInfo.List")]
public static void JetGetIndexInfo(
JET_SESID sesid,
JET_DBID dbid,
string tablename,
string ignored,
out JET_INDEXLIST indexlist)
{
Api.JetGetIndexInfo(sesid, dbid, tablename, ignored, out indexlist, JET_IdxInfo.List);
}
/// <summary>
/// Retrieves information about indexes on a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to retrieve index information about.</param>
/// <param name="indexname">This parameter is ignored.</param>
/// <param name="indexlist">Filled in with information about indexes on the table.</param>
[Obsolete("Use the overload that takes a JET_IdxInfo parameter, passing in JET_IdxInfo.List")]
public static void JetGetTableIndexInfo(
JET_SESID sesid,
JET_TABLEID tableid,
string indexname,
out JET_INDEXLIST indexlist)
{
Api.JetGetTableIndexInfo(sesid, tableid, indexname, out indexlist, JET_IdxInfo.List);
}
}
}

View File

@ -1,44 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="OnlineMaintenanceHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// Helper methods for the ESENT API. These methods deal with database
/// meta-data.
/// </summary>
public static partial class Api
{
/// <summary>
/// Starts and stops database defragmentation tasks that improves data
/// organization within a database.
/// </summary>
/// <param name="sesid">The session to use for the call.</param>
/// <param name="dbid">The database to be defragmented.</param>
/// <param name="tableName">
/// Under some options defragmentation is performed for the entire database described by the given
/// database ID, and other options (such as <see cref="Windows7.Windows7Grbits.DefragmentBTree"/>) require
/// the name of the table to defragment.
/// </param>
/// <param name="grbit">Defragmentation options.</param>
/// <returns>A warning code.</returns>
/// <seealso cref="Api.JetDefragment"/>
public static JET_wrn Defragment(
JET_SESID sesid,
JET_DBID dbid,
string tableName,
DefragGrbit grbit)
{
return Api.Check(Impl.Defragment(sesid, dbid, tableName, grbit));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Server2003Api.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Server2003
{
/// <summary>
/// APIs that have been added to the Windows Server 2003 version of ESENT.
/// </summary>
public static class Server2003Api
{
#if !MANAGEDESENT_ON_WSA
/// <summary>
/// Notifies the engine that it can resume normal IO operations after a
/// freeze period ended with a failed snapshot.
/// </summary>
/// <param name="snapid">Identifier of the snapshot session.</param>
/// <param name="grbit">Options for this call.</param>
public static void JetOSSnapshotAbort(JET_OSSNAPID snapid, SnapshotAbortGrbit grbit)
{
Api.Check(Api.Impl.JetOSSnapshotAbort(snapid, grbit));
}
#endif // !MANAGEDESENT_ON_WSA
/// <summary>
/// The JetUpdate function performs an update operation including inserting a new row into
/// a table or updating an existing row. Deleting a table row is performed by calling
/// <see cref="Api.JetDelete"/>.
/// </summary>
/// <param name="sesid">The session which started the update.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="bookmark">Returns the bookmark of the updated record. This can be null.</param>
/// <param name="bookmarkSize">The size of the bookmark buffer.</param>
/// <param name="actualBookmarkSize">Returns the actual size of the bookmark.</param>
/// <param name="grbit">Update options.</param>
/// <remarks>
/// JetUpdate is the final step in performing an insert or an update. The update is begun by
/// calling <see cref="Api.JetPrepareUpdate"/> and then by calling
/// <see cref="Api.JetSetColumn(JET_SESID,JET_TABLEID,JET_COLUMNID,byte[],int,SetColumnGrbit,JET_SETINFO)"/>
/// one or more times to set the record state. Finally, <see cref="JetUpdate2"/>
/// is called to complete the update operation. Indexes are updated only by JetUpdate or and not during JetSetColumn.
/// </remarks>
public static void JetUpdate2(JET_SESID sesid, JET_TABLEID tableid, byte[] bookmark, int bookmarkSize, out int actualBookmarkSize, UpdateGrbit grbit)
{
Api.Check(Api.Impl.JetUpdate2(sesid, tableid, bookmark, bookmarkSize, out actualBookmarkSize, grbit));
}
}
}

View File

@ -1,108 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Server2003Grbits.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Server2003
{
using System;
#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK
/// <summary>
/// Options for <see cref="Server2003Api.JetOSSnapshotAbort"/>.
/// </summary>
[Flags]
public enum SnapshotAbortGrbit
{
/// <summary>
/// Default options.
/// </summary>
None = 0,
}
#endif // !MANAGEDESENT_ON_WSA
/// <summary>
/// Options for <see cref="Server2003Api.JetUpdate2"/>.
/// </summary>
[Flags]
public enum UpdateGrbit
{
/// <summary>
/// Default options.
/// </summary>
None = 0,
#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK
/// <summary>
/// This flag causes the update to return an error if the update would
/// not have been possible in the Windows 2000 version of ESE, which
/// enforced a smaller maximum number of multi-valued column instances
/// in each record than later versions of ESE. This is important only
/// for applications that wish to replicate data between applications
/// hosted on Windows 2000 and applications hosted on Windows
/// 2003, or later versions of ESE. It should not be necessary for most
/// applications.
/// </summary>
[Obsolete("Only needed for legacy replication applications.")]
CheckESE97Compatibility = 0x1,
#endif // !MANAGEDESENT_ON_WSA
}
/// <summary>
/// Grbits that have been added to the Windows Server 2003 version of ESENT.
/// </summary>
public static class Server2003Grbits
{
/// <summary>
/// Delete all indexes with unicode columns.
/// </summary>
public const AttachDatabaseGrbit DeleteUnicodeIndexes = (AttachDatabaseGrbit)0x400;
/// <summary>
/// When the escrow-update column reaches a value of zero (after all
/// versions are resolve), the record will be deleted. A common use for
/// a column that can be finalized is to use it as a reference count
/// field, and when the field reaches zero the record gets deleted. A
/// Delete-on-zero column must be an escrow update / <see cref="ColumndefGrbit.ColumnEscrowUpdate"/>
/// column. ColumnDeleteOnZero cannot be used with ColumnFinalize.
/// ColumnDeleteOnZero cannot be used with user defined default columns.
/// </summary>
public const ColumndefGrbit ColumnDeleteOnZero = (ColumndefGrbit)0x20000;
/// <summary>
/// This option requests that the temporary table only be created if the
/// temporary table manager can use the implementation optimized for
/// intermediate query results. If any characteristic of the temporary
/// table would prevent the use of this optimization then the operation
/// will fail with JET_errCannotMaterializeForwardOnlySort. A side effect
/// of this option is to allow the temporary table to contain records
/// with duplicate index keys. See <see cref="TempTableGrbit.Unique"/>
/// for more information.
/// </summary>
public const TempTableGrbit ForwardOnly = (TempTableGrbit)0x40;
/// <summary>
/// If a given column is not present in the record and it has a user
/// defined default value then no column value will be returned.
/// This option will prevent the callback that computes the user defined
/// default value for the column from being called when enumerating
/// the values for that column.
/// </summary>
/// <remarks>
/// This option is only available for Windows Server 2003 SP1 and later
/// operating systems.
/// </remarks>
public const EnumerateColumnsGrbit EnumerateIgnoreUserDefinedDefault = (EnumerateColumnsGrbit)0x00100000;
/// <summary>
/// All transactions previously committed by any session that have not
/// yet been flushed to the transaction log file will be flushed immediately.
/// This API will wait until the transactions have been flushed before
/// returning to the caller. This option may be used even if the session
/// is not currently in a transaction. This option cannot be used in
/// combination with any other option.
/// </summary>
public const CommitTransactionGrbit WaitAllLevel0Commit = (CommitTransactionGrbit)0x8;
}
}

View File

@ -1,24 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Server2003Param.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Server2003
{
/// <summary>
/// System parameters that have been added to the Windows Server 2003 version of ESENT.
/// </summary>
public static class Server2003Param
{
/// <summary>
/// The full path to each database is persisted in the transaction logs
/// at run time. Ordinarily, these databases must remain at the original
/// location for transaction replay to function correctly. This
/// parameter can be used to force crash recovery or a restore operation
/// to look for the databases referenced in the transaction log in the
/// specified folder.
/// </summary>
public const JET_param AlternateDatabaseRecoveryPath = (JET_param)113;
}
}

View File

@ -1,89 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Session.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Globalization;
/// <summary>
/// A class that encapsulates a JET_SESID in a disposable object.
/// </summary>
public class Session : EsentResource
{
/// <summary>
/// The underlying JET_SESID.
/// </summary>
private JET_SESID sesid;
/// <summary>
/// Initializes a new instance of the Session class. A new
/// JET_SESSION is allocated from the given instance.
/// </summary>
/// <param name="instance">The instance to start the session in.</param>
public Session(JET_INSTANCE instance)
{
Api.JetBeginSession(instance, out this.sesid, null, null);
this.ResourceWasAllocated();
}
/// <summary>
/// Gets the JET_SESID that this session contains.
/// </summary>
public JET_SESID JetSesid
{
get
{
this.CheckObjectIsNotDisposed();
return this.sesid;
}
}
/// <summary>
/// Implicit conversion operator from a Session to a JET_SESID. This
/// allows a Session to be used with APIs which expect a JET_SESID.
/// </summary>
/// <param name="session">The session to convert.</param>
/// <returns>The JET_SESID of the session.</returns>
public static implicit operator JET_SESID(Session session)
{
return session.JetSesid;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="Session"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="Session"/>.
/// </returns>
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "Session (0x{0:x})", this.sesid.Value);
}
/// <summary>
/// Terminate the session.
/// </summary>
public void End()
{
this.CheckObjectIsNotDisposed();
this.ReleaseResource();
}
/// <summary>
/// Free the underlying JET_SESID.
/// </summary>
protected override void ReleaseResource()
{
if (!this.sesid.IsInvalid)
{
Api.JetEndSession(this.JetSesid, EndSessionGrbit.None);
}
this.sesid = JET_SESID.Nil;
this.ResourceWasReleased();
}
}
}

View File

@ -1,544 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="SetColumnHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
#if MANAGEDESENT_SUPPORTS_SERIALIZATION
using System.Runtime.Serialization.Formatters.Binary;
#endif
using System.Text;
using Microsoft.Isam.Esent.Interop.Vista;
using Microsoft.Isam.Esent.Interop.Windows10;
/// <summary>
/// Helper methods for the ESENT API. These do data conversion for
/// setting columns.
/// </summary>
public static partial class Api
{
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="encoding">The encoding used to convert the string.</param>
public static void SetColumn(
JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, string data, Encoding encoding)
{
SetColumn(sesid, tableid, columnid, data, encoding, SetColumnGrbit.None);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="encoding">The encoding used to convert the string.</param>
/// <param name="grbit">SetColumn options.</param>
public static void SetColumn(
JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, string data, Encoding encoding, SetColumnGrbit grbit)
{
CheckEncodingIsValid(encoding);
if (null == data)
{
JetSetColumn(sesid, tableid, columnid, null, 0, grbit, null);
}
else if (0 == data.Length)
{
JetSetColumn(sesid, tableid, columnid, null, 0, grbit | SetColumnGrbit.ZeroLength, null);
}
else if (Encoding.Unicode == encoding)
{
// Optimization for setting Unicode strings.
unsafe
{
fixed (char* buffer = data)
{
JetSetColumn(
sesid,
tableid,
columnid,
new IntPtr(buffer),
checked(data.Length * sizeof(char)),
grbit,
null);
}
}
}
else if (encoding.GetMaxByteCount(data.Length) <= Caches.ColumnCache.BufferSize)
{
#if MANAGEDESENT_ON_WSA
// Encoding.GetBytes(char*, int, byte*, int) overload is missing in new Windows UI.
// So we can't use the ColumnCache. We'll just use a different GetBytes() overload.
byte[] buffer = encoding.GetBytes(data);
unsafe
{
fixed (byte* bytes = buffer)
{
JetSetColumn(sesid, tableid, columnid, new IntPtr(bytes), buffer.Length, grbit, null);
}
}
#else
// The encoding output will fix in a cached buffer. Get one to avoid
// more memory allocations.
byte[] buffer = null;
try
{
buffer = Caches.ColumnCache.Allocate();
unsafe
{
fixed (char* chars = data)
fixed (byte* bytes = buffer)
{
int dataSize = encoding.GetBytes(chars, data.Length, bytes, buffer.Length);
JetSetColumn(sesid, tableid, columnid, new IntPtr(bytes), dataSize, grbit, null);
}
}
}
finally
{
if (buffer != null)
{
Caches.ColumnCache.Free(ref buffer);
}
}
#endif
}
else
{
byte[] bytes = encoding.GetBytes(data);
JetSetColumn(sesid, tableid, columnid, bytes, bytes.Length, grbit, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data)
{
SetColumn(sesid, tableid, columnid, data, SetColumnGrbit.None);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="grbit">SetColumn options.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, SetColumnGrbit grbit)
{
int dataLength = (null == data) ? 0 : data.Length;
SetColumn(sesid, tableid, columnid, data, dataLength, grbit);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="dataSize">The size of data to set.</param>
/// <param name="grbit">SetColumn options.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, int dataSize, SetColumnGrbit grbit)
{
if ((null != data) && (0 == data.Length))
{
grbit |= SetColumnGrbit.ZeroLength;
}
if (data == null && dataSize > 0)
{
throw new ArgumentException(string.Format("data is null, but dataSize is: {0}", dataSize));
}
if (data != null && data.Length < dataSize)
{
throw new ArgumentException(string.Format("data.Length is less, than dataSize: data.Length={0}, dataSize={1}", data.Length, dataSize));
}
JetSetColumn(sesid, tableid, columnid, data, dataSize, grbit, null);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, bool data)
{
byte b = data ? (byte)0xff : (byte)0x0;
SetColumn(sesid, tableid, columnid, b);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte data)
{
unsafe
{
const int DataSize = sizeof(byte);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, short data)
{
unsafe
{
const int DataSize = sizeof(short);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, int data)
{
unsafe
{
const int DataSize = sizeof(int);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, long data)
{
unsafe
{
const int DataSize = sizeof(long);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, Guid data)
{
unsafe
{
const int DataSize = 16; // sizeof(Guid) isn't a compile-time constant
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, DateTime data)
{
SetColumn(sesid, tableid, columnid, data.ToOADate());
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, float data)
{
unsafe
{
const int DataSize = sizeof(float);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, double data)
{
unsafe
{
const int DataSize = sizeof(double);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Perform atomic addition on an Int32 column. The column must be of type
/// <see cref="JET_coltyp.Long"/>. This function allows multiple sessions to update the
/// same record concurrently without conflicts.
/// </summary>
/// <remarks>
/// This method wraps <see cref="JetEscrowUpdate"/>.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update.</param>
/// <param name="columnid">The column to update. This must be an escrow-updatable column.</param>
/// <param name="delta">The delta to apply to the column.</param>
/// <returns>The current value of the column as stored in the database (versioning is ignored).</returns>
public static int EscrowUpdate(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, int delta)
{
var previousValue = new byte[sizeof(int)];
int actualPreviousValueLength;
JetEscrowUpdate(
sesid,
tableid,
columnid,
BitConverter.GetBytes(delta),
sizeof(int),
previousValue,
previousValue.Length,
out actualPreviousValueLength,
EscrowUpdateGrbit.None);
Debug.Assert(
previousValue.Length == actualPreviousValueLength,
"Unexpected previous value length. Expected an Int32");
return BitConverter.ToInt32(previousValue, 0);
}
/// <summary>
/// Perform atomic addition on an Int64 column. The column must be of type
/// <see cref="VistaColtyp.LongLong"/>. This function allows multiple sessions to update the
/// same record concurrently without conflicts.
/// </summary>
/// <remarks>
/// This method wraps <see cref="JetEscrowUpdate"/>.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update.</param>
/// <param name="columnid">The column to update. This must be an escrow-updatable column.</param>
/// <param name="delta">The delta to apply to the column.</param>
/// <returns>The current value of the column as stored in the database (versioning is ignored).</returns>
public static long EscrowUpdate(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, long delta)
{
var previousValue = new byte[sizeof(long)];
int actualPreviousValueLength;
JetEscrowUpdate(
sesid,
tableid,
columnid,
BitConverter.GetBytes(delta),
sizeof(long),
previousValue,
previousValue.Length,
out actualPreviousValueLength,
EscrowUpdateGrbit.None);
Debug.Assert(
previousValue.Length == actualPreviousValueLength,
"Unexpected previous value length. Expected an Int64");
return BitConverter.ToInt64(previousValue, 0);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
[CLSCompliant(false)]
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, ushort data)
{
unsafe
{
const int DataSize = sizeof(ushort);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
[CLSCompliant(false)]
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, uint data)
{
unsafe
{
const int DataSize = sizeof(uint);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
[CLSCompliant(false)]
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, ulong data)
{
unsafe
{
const int DataSize = sizeof(ulong);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
#if MANAGEDESENT_SUPPORTS_SERIALIZATION
/// <summary>
/// Write a serialized form of an object to a column.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to write to. An update should be prepared.</param>
/// <param name="columnid">The column to write to.</param>
/// <param name="value">The object to write. The object must be serializable.</param>
[SuppressMessage("Exchange.Security", "EX0043:DoNotUseBinarySoapFormatter", Justification = "Suppress warning in current code base.The usage has already been verified.")]
public static void SerializeObjectToColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, object value)
{
if (null == value)
{
Api.SetColumn(sesid, tableid, columnid, null);
}
else
{
using (var stream = new ColumnStream(sesid, tableid, columnid))
{
var serializer = new BinaryFormatter
{
Context = new StreamingContext(StreamingContextStates.Persistence)
};
serializer.Serialize(stream, value);
}
}
}
#endif
/// <summary>
/// Sets columns from ColumnValue objects.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="values">The values to set.</param>
public static void SetColumns(JET_SESID sesid, JET_TABLEID tableid, params ColumnValue[] values)
{
if (null == values)
{
throw new ArgumentNullException("values");
}
if (0 == values.Length)
{
throw new ArgumentOutOfRangeException("values", values.Length, "must have at least one value");
}
unsafe
{
NATIVE_SETCOLUMN* nativeSetcolumns = stackalloc NATIVE_SETCOLUMN[values.Length];
Api.Check(values[0].SetColumns(sesid, tableid, values, nativeSetcolumns, 0));
}
}
/// <summary>
/// Verifies that the given encoding is valid for setting/retrieving data. Only
/// the ASCII and Unicode encodings are allowed. An <see cref="ArgumentOutOfRangeException"/>
/// is thrown if the encoding isn't valid.
/// </summary>
/// <param name="encoding">The encoding to check.</param>
private static void CheckEncodingIsValid(Encoding encoding)
{
#if MANAGEDESENT_ON_CORECLR
string webName = encoding.WebName;
if (webName != "utf-8" && webName != "utf-16")
{
throw new ArgumentOutOfRangeException(
"encoding", webName, "Invalid Encoding type. Only Unicode (utf-8 and utf-16) encodings are allowed.");
}
#else
const int AsciiCodePage = 20127; // from MSDN
const int UnicodeCodePage = 1200; // from MSDN
int codePage = encoding.CodePage;
if ((AsciiCodePage != codePage) && (UnicodeCodePage != codePage))
{
throw new ArgumentOutOfRangeException(
"encoding", codePage, "Invalid Encoding type. Only ASCII and Unicode encodings are allowed");
}
#endif
}
}
}

View File

@ -1,78 +0,0 @@
<StyleCopSettings Version="105">
<GlobalSettings>
<BooleanProperty Name="WriteCache">False</BooleanProperty>
<CollectionProperty Name="RecognizedWords">
<Value>api</Value>
<Value>coltyp</Value>
<Value>columndef</Value>
<Value>columnid</Value>
<Value>dbid</Value>
<Value>dll</Value>
<Value>ese</Value>
<Value>esent</Value>
<Value>grbit</Value>
<Value>grbits</Value>
<Value>interop</Value>
<Value>itag</Value>
<Value>lgpos</Value>
<Value>param</Value>
<Value>preread</Value>
<Value>sesid</Value>
<Value>tableid</Value>
</CollectionProperty>
</GlobalSettings>
<Analyzers>
<Analyzer AnalyzerId="StyleCop.CSharp.NamingRules">
<AnalyzerSettings>
<CollectionProperty Name="Hungarian">
<Value>c</Value>
<Value>cb</Value>
<Value>dw</Value>
<Value>f</Value>
<Value>h</Value>
<Value>ib</Value>
<Value>l</Value>
<Value>p</Value>
<Value>pv</Value>
<Value>rg</Value>
<Value>sz</Value>
<Value>ul</Value>
<Value>w</Value>
</CollectionProperty>
</AnalyzerSettings>
</Analyzer>
<Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules">
<Rules>
<Rule Name="DocumentationTextMustBeginWithACapitalLetter">
<RuleSettings>
<BooleanProperty Name="Enabled">True</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="DocumentationTextMustEndWithAPeriod">
<RuleSettings>
<BooleanProperty Name="Enabled">True</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="FileHeaderFileNameDocumentationMustMatchTypeName">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
</Rules>
<AnalyzerSettings>
<StringProperty Name="CompanyName">Microsoft Corporation</StringProperty>
<StringProperty Name="Copyright">Copyright (c) Microsoft Corporation.</StringProperty>
</AnalyzerSettings>
</Analyzer>
<Analyzer AnalyzerId="StyleCop.CSharp.MaintainabilityRules">
<Rules>
<Rule Name="FileMayOnlyContainASingleNamespace">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
</Rules>
<AnalyzerSettings />
</Analyzer>
</Analyzers>
</StyleCopSettings>

View File

@ -1,166 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="StringCache.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// Class that helps cache strings.
/// </summary>
internal static class StringCache
{
/// <summary>
/// Don't cache strings whose length is longer than this.
/// </summary>
private const int MaxLengthToCache = 128;
/// <summary>
/// Number of converted strings to hash.
/// </summary>
private const int NumCachedBoxedValues = 1031;
/// <summary>
/// Cached string values.
/// </summary>
private static readonly string[] CachedStrings = new string[NumCachedBoxedValues];
/// <summary>
/// Return the interned version of a string, or the original
/// string if it isn't interned.
/// </summary>
/// <param name="s">The string to try to intern.</param>
/// <returns>An interned copy of the string or the original string.</returns>
public static string TryToIntern(string s)
{
#if MANAGEDESENT_ON_WSA
// new Windows UI Core CLR does not support string interning.
return s;
#else
return string.IsInterned(s) ?? s;
#endif
}
/// <summary>
/// Convert a byte array to a string.
/// </summary>
/// <param name="value">The bytes to convert.</param>
/// <param name="startIndex">The starting index of the data to convert.</param>
/// <param name="count">The number of bytes to convert.</param>
/// <returns>A string converted from the data.</returns>
public static string GetString(byte[] value, int startIndex, int count)
{
unsafe
{
fixed (byte* data = value)
{
char* chars = (char*)(data + startIndex);
return GetString(chars, 0, count / sizeof(char));
}
}
}
/// <summary>
/// Convert a char array to a string, using a cached value if possible.
/// </summary>
/// <param name="value">The characters to convert.</param>
/// <param name="startIndex">The starting index of the data to convert.</param>
/// <param name="count">The number of characters to convert.</param>
/// <returns>A string converted from the data.</returns>
private static unsafe string GetString(char* value, int startIndex, int count)
{
string s;
if (0 == count)
{
s = string.Empty;
}
else if (count < MaxLengthToCache)
{
uint hash = CalculateHash(value, startIndex, count);
int index = unchecked((int)(hash % NumCachedBoxedValues));
s = CachedStrings[index];
if (null == s || !AreEqual(s, value, startIndex, count))
{
s = CreateNewString(value, startIndex, count);
CachedStrings[index] = s;
}
}
else
{
s = CreateNewString(value, startIndex, count);
}
return s;
}
/// <summary>
/// Calculate the hash of a string.
/// </summary>
/// <param name="value">The characters to hash.</param>
/// <param name="startIndex">The starting index of the data to hash.</param>
/// <param name="count">The number of characters to hash.</param>
/// <returns>The hash value of the data.</returns>
private static unsafe uint CalculateHash(char* value, int startIndex, int count)
{
uint hash = 0;
unchecked
{
for (int i = 0; i < count; ++i)
{
hash ^= value[startIndex + i];
hash *= 33;
}
}
return hash;
}
/// <summary>
/// Determine if a string matches a char array..
/// </summary>
/// <param name="s">The string to compare against.</param>
/// <param name="value">The characters.</param>
/// <param name="startIndex">The starting index of the data.</param>
/// <param name="count">The number of characters.</param>
/// <returns>True if the string matches the char array.</returns>
private static unsafe bool AreEqual(string s, char* value, int startIndex, int count)
{
if (s.Length != count)
{
return false;
}
unchecked
{
for (int i = 0; i < s.Length; ++i)
{
if (s[i] != value[startIndex + i])
{
return false;
}
}
}
return true;
}
/// <summary>
/// Convert a char array to a string.
/// </summary>
/// <param name="value">The characters to convert.</param>
/// <param name="startIndex">The starting index of the data to convert.</param>
/// <param name="count">The number of characters to convert.</param>
/// <returns>A string converted from the data.</returns>
private static unsafe string CreateNewString(char* value, int startIndex, int count)
{
// Encoding.Unicode.GetString copies the data to an array of chars and then
// makes a string from it, copying the data twice. Use the more efficient
// char* constructor.
return new string(value, startIndex, count);
}
}
}

View File

@ -1,128 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="StringColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A Unicode string column value.
/// </summary>
public class StringColumnValue : ColumnValue
{
/// <summary>
/// Internal value.
/// </summary>
private string internalValue;
/// <summary>
/// Gets the last set or retrieved value of the column. The
/// value is returned as a generic object.
/// </summary>
public override object ValueAsObject
{
[DebuggerStepThrough]
get { return this.Value; }
}
/// <summary>
/// Gets or sets the value of the column. Use <see cref="Api.SetColumns"/> to update a
/// record with the column value.
/// </summary>
public string Value
{
get
{
return this.internalValue;
}
set
{
this.internalValue = value;
this.Error = value == null ? JET_wrn.ColumnNull : JET_wrn.Success;
}
}
/// <summary>
/// Gets the byte length of a column value, which is zero if column is null, otherwise
/// it matches the byte length of the string value. The byte length is determined in
/// assumption of two bytes per character.
/// </summary>
public override int Length
{
get { return this.Value != null ? this.Value.Length * sizeof(char) : 0; }
}
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return 0; }
}
/// <summary>
/// Gets a string representation of this object.
/// </summary>
/// <returns>A string representation of this object.</returns>
public override string ToString()
{
return this.Value;
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
if (null != this.Value)
{
fixed (void* buffer = this.Value)
{
return this.SetColumns(
sesid, tableid, columnValues, nativeColumns, i, buffer, checked(this.Value.Length * sizeof(char)), true);
}
}
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, null, 0, false);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.Value = StringCache.GetString(value, startIndex, count);
}
}
}
}

View File

@ -1,487 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="SystemParameters.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using Microsoft.Isam.Esent.Interop.Vista;
using Microsoft.Isam.Esent.Interop.Windows7;
/// <summary>
/// This class provides static properties to set and get
/// global ESENT system parameters.
/// </summary>
public static partial class SystemParameters
{
/// <summary>
/// Gets or sets the maximum size of the database page cache. The size
/// is in database pages. If this parameter is left to its default value, then the
/// maximum size of the cache will be set to the size of physical memory when JetInit
/// is called.
/// </summary>
public static int CacheSizeMax
{
get
{
return GetIntegerParameter(JET_param.CacheSizeMax);
}
set
{
SetIntegerParameter(JET_param.CacheSizeMax, value);
}
}
/// <summary>
/// Gets or sets the size of the database cache in pages. By default the
/// database cache will automatically tune its size, setting this property
/// to a non-zero value will cause the cache to adjust itself to the target
/// size.
/// </summary>
public static int CacheSize
{
get
{
return GetIntegerParameter(JET_param.CacheSize);
}
set
{
SetIntegerParameter(JET_param.CacheSize, value);
}
}
/// <summary>
/// Gets or sets the size of the database pages, in bytes.
/// </summary>
public static int DatabasePageSize
{
get
{
return GetIntegerParameter(JET_param.DatabasePageSize);
}
set
{
SetIntegerParameter(JET_param.DatabasePageSize, value);
}
}
/// <summary>
/// Gets or sets the minimum size of the database page cache, in database pages.
/// </summary>
public static int CacheSizeMin
{
get
{
return GetIntegerParameter(JET_param.CacheSizeMin);
}
set
{
SetIntegerParameter(JET_param.CacheSizeMin, value);
}
}
/// <summary>
/// Gets or sets how many database file I/Os can be queued
/// per-disk in the host operating system at one time. A larger value
/// for this parameter can significantly help the performance of a large
/// database application.
/// </summary>
public static int OutstandingIOMax
{
get
{
return GetIntegerParameter(JET_param.OutstandingIOMax);
}
set
{
SetIntegerParameter(JET_param.OutstandingIOMax, value);
}
}
/// <summary>
/// Gets or sets the threshold at which the database page cache begins evicting pages from the
/// cache to make room for pages that are not cached. When the number of page buffers in the cache
/// drops below this threshold then a background process will be started to replenish that pool
/// of available buffers. This threshold is always relative to the maximum cache size as set by
/// JET_paramCacheSizeMax. This threshold must also always be less than the stop threshold as
/// set by JET_paramStopFlushThreshold.
/// <para>
/// The distance height of the start threshold will determine the response time that the database
/// page cache must have to produce available buffers before the application needs them. A high
/// start threshold will give the background process more time to react. However, a high start
/// threshold implies a higher stop threshold and that will reduce the effective size of the
/// database page cache.
/// </para>
/// </summary>
public static int StartFlushThreshold
{
get
{
return GetIntegerParameter(JET_param.StartFlushThreshold);
}
set
{
SetIntegerParameter(JET_param.StartFlushThreshold, value);
}
}
/// <summary>
/// Gets or sets the threshold at which the database page cache ends evicting pages from the cache to make
/// room for pages that are not cached. When the number of page buffers in the cache rises above
/// this threshold then the background process that was started to replenish that pool of available
/// buffers is stopped. This threshold is always relative to the maximum cache size as set by
/// JET_paramCacheSizeMax. This threshold must also always be greater than the start threshold
/// as set by JET_paramStartFlushThreshold.
/// <para>
/// The distance between the start threshold and the stop threshold affects the efficiency with
/// which database pages are flushed by the background process. A larger gap will make it
/// more likely that writes to neighboring pages may be combined. However, a high stop
/// threshold will reduce the effective size of the database page cache.
/// </para>
/// </summary>
public static int StopFlushThreshold
{
get
{
return GetIntegerParameter(JET_param.StopFlushThreshold);
}
set
{
SetIntegerParameter(JET_param.StopFlushThreshold, value);
}
}
/// <summary>
/// Gets or sets the maximum number of instances that can be created.
/// </summary>
public static int MaxInstances
{
get
{
return GetIntegerParameter(JET_param.MaxInstances);
}
set
{
SetIntegerParameter(JET_param.MaxInstances, value);
}
}
/// <summary>
/// Gets or sets the detail level of eventlog messages that are emitted
/// to the eventlog by the database engine. Higher numbers will result
/// in more detailed eventlog messages.
/// </summary>
public static int EventLoggingLevel
{
get
{
return GetIntegerParameter(JET_param.EventLoggingLevel);
}
set
{
SetIntegerParameter(JET_param.EventLoggingLevel, value);
}
}
/// <summary>
/// Gets the maximum key size. This depends on the Esent version and database
/// page size.
/// </summary>
public static int KeyMost
{
get
{
if (EsentVersion.SupportsVistaFeatures)
{
return GetIntegerParameter(VistaParam.KeyMost);
}
// All pre-Vista versions of Esent have 255 byte keys
return 255;
}
}
/// <summary>
/// Gets the maximum number of components in a sort or index key.
/// </summary>
public static int ColumnsKeyMost
{
get
{
return Api.Impl.Capabilities.ColumnsKeyMost;
}
}
/// <summary>
/// Gets the maximum size of a bookmark. <seealso cref="Api.JetGetBookmark"/>.
/// </summary>
public static int BookmarkMost
{
get
{
// This correctly returns 256 on pre-Vista systems
return KeyMost + 1;
}
}
/// <summary>
/// Gets the lv chunks size. This depends on the database page size.
/// </summary>
public static int LVChunkSizeMost
{
get
{
if (EsentVersion.SupportsWindows7Features)
{
return GetIntegerParameter(Windows7Param.LVChunkSizeMost);
}
// Can't retrieve the size directly, determine it from the database page size
const int ColumnLvPageOverhead = 82;
return GetIntegerParameter(JET_param.DatabasePageSize) - ColumnLvPageOverhead;
}
}
/// <summary>
/// Gets or sets a value specifying the default values for the
/// entire set of system parameters. When this parameter is set to
/// a specific configuration, all system parameter values are reset
/// to their default values for that configuration. If the
/// configuration is set for a specific instance then global system
/// parameters will not be reset to their default values.
/// Small Configuration (0): The database engine is optimized for memory use.
/// Legacy Configuration (1): The database engine has its traditional defaults.
/// <para>
/// Supported on Windows Vista and up. Ignored on Windows XP and
/// Windows Server 2003.
/// </para>
/// </summary>
public static int Configuration
{
get
{
if (EsentVersion.SupportsVistaFeatures)
{
return GetIntegerParameter(VistaParam.Configuration);
}
// return the legacy configuration value
return 1;
}
set
{
if (EsentVersion.SupportsVistaFeatures)
{
SetIntegerParameter(VistaParam.Configuration, value);
}
}
}
/// <summary>
/// Gets or sets a value indicating whether the database engine accepts
/// or rejects changes to a subset of the system parameters. This
/// parameter is used in conjunction with <see cref="Configuration"/> to
/// prevent some system parameters from being set away from the selected
/// configuration's defaults.
/// <para>
/// Supported on Windows Vista and up. Ignored on Windows XP and
/// Windows Server 2003.
/// </para>
/// </summary>
public static bool EnableAdvanced
{
get
{
if (EsentVersion.SupportsVistaFeatures)
{
return GetBoolParameter(VistaParam.EnableAdvanced);
}
// older versions always allow advanced settings
return true;
}
set
{
if (EsentVersion.SupportsVistaFeatures)
{
SetBoolParameter(VistaParam.EnableAdvanced, value);
}
}
}
/// <summary>
/// Gets or sets backwards compatibility with the file naming conventions of earlier releases of the database engine.
/// </summary>
public static int LegacyFileNames
{
get
{
if (EsentVersion.SupportsVistaFeatures)
{
return GetIntegerParameter(VistaParam.LegacyFileNames);
}
// return the legacy LegacyFileNames value
return 1;
}
set
{
if (EsentVersion.SupportsVistaFeatures)
{
SetIntegerParameter(VistaParam.LegacyFileNames, value);
}
}
}
/// <summary>
/// Gets or sets the value encoding what to do with exceptions generated within JET.
/// </summary>
public static JET_ExceptionAction ExceptionAction
{
get
{
return (JET_ExceptionAction)GetIntegerParameter(JET_param.ExceptionAction);
}
set
{
SetIntegerParameter(JET_param.ExceptionAction, (int)value);
}
}
/// <summary>
/// Gets or sets a value indicating whether the database engine should
/// use the OS file cache for all managed files.
/// </summary>
public static bool EnableFileCache
{
get
{
if (EsentVersion.SupportsVistaFeatures)
{
return GetBoolParameter(VistaParam.EnableFileCache);
}
// Pre-Vista versions of do not implement this.
return false;
}
set
{
if (EsentVersion.SupportsVistaFeatures)
{
SetBoolParameter(VistaParam.EnableFileCache, value);
}
}
}
/// <summary>
/// Gets or sets a value indicating whether the database engine should
/// use memory mapped file I/O for database files.
/// </summary>
public static bool EnableViewCache
{
get
{
if (EsentVersion.SupportsVistaFeatures)
{
return GetBoolParameter(VistaParam.EnableViewCache);
}
// Pre-Vista versions of do not implement this.
return false;
}
set
{
if (EsentVersion.SupportsVistaFeatures)
{
SetBoolParameter(VistaParam.EnableViewCache, value);
}
}
}
/// <summary>
/// Set a system parameter which is a string.
/// </summary>
/// <param name="param">The parameter to set.</param>
/// <param name="value">The value to set.</param>
private static void SetStringParameter(JET_param param, string value)
{
Api.JetSetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, param, 0, value);
}
/// <summary>
/// Get a system parameter which is a string.
/// </summary>
/// <param name="param">The parameter to get.</param>
/// <returns>The value of the parameter.</returns>
private static string GetStringParameter(JET_param param)
{
int ignored = 0;
string value;
Api.JetGetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, param, ref ignored, out value, 1024);
return value;
}
/// <summary>
/// Set a system parameter which is an integer.
/// </summary>
/// <param name="param">The parameter to set.</param>
/// <param name="value">The value to set.</param>
private static void SetIntegerParameter(JET_param param, int value)
{
Api.JetSetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, param, value, null);
}
/// <summary>
/// Get a system parameter which is an integer.
/// </summary>
/// <param name="param">The parameter to get.</param>
/// <returns>The value of the parameter.</returns>
private static int GetIntegerParameter(JET_param param)
{
int value = 0;
string ignored;
Api.JetGetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, param, ref value, out ignored, 0);
return value;
}
/// <summary>
/// Set a system parameter which is a boolean.
/// </summary>
/// <param name="param">The parameter to set.</param>
/// <param name="value">The value to set.</param>
private static void SetBoolParameter(JET_param param, bool value)
{
int setting = value ? 1 : 0;
Api.JetSetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, param, setting, null);
}
/// <summary>
/// Get a system parameter which is a boolean.
/// </summary>
/// <param name="param">The parameter to get.</param>
/// <returns>The value of the parameter.</returns>
private static bool GetBoolParameter(JET_param param)
{
int value = 0;
string ignored;
Api.JetGetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, param, ref value, out ignored, 0);
return value != 0;
}
}
}

View File

@ -1,114 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Table.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// A class that encapsulates a JET_TABLEID in a disposable object.
/// This opens an existing table. To create a table use the
/// JetCreateTable method.
/// </summary>
public class Table : EsentResource
{
/// <summary>
/// The session used to open the table.
/// </summary>
private JET_SESID sesid;
/// <summary>
/// The underlying JET_TABLEID.
/// </summary>
private JET_TABLEID tableid;
/// <summary>
/// The name of the table.
/// </summary>
private string name;
/// <summary>
/// Initializes a new instance of the Table class. The table is
/// opened from the given database.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database to open the table in.</param>
/// <param name="name">The name of the table.</param>
/// <param name="grbit">JetOpenTable options.</param>
public Table(JET_SESID sesid, JET_DBID dbid, string name, OpenTableGrbit grbit)
{
this.sesid = sesid;
this.name = name;
Api.JetOpenTable(this.sesid, dbid, this.name, null, 0, grbit, out this.tableid);
this.ResourceWasAllocated();
}
/// <summary>
/// Gets the name of this table.
/// </summary>
public string Name
{
get
{
this.CheckObjectIsNotDisposed();
return this.name;
}
}
/// <summary>
/// Gets the JET_TABLEID that this table contains.
/// </summary>
public JET_TABLEID JetTableid
{
get
{
this.CheckObjectIsNotDisposed();
return this.tableid;
}
}
/// <summary>
/// Implicit conversion operator from a Table to a JET_TABLEID. This
/// allows a Table to be used with APIs which expect a JET_TABLEID.
/// </summary>
/// <param name="table">The table to convert.</param>
/// <returns>The JET_TABLEID of the table.</returns>
public static implicit operator JET_TABLEID(Table table)
{
return table.JetTableid;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="Table"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="Table"/>.
/// </returns>
public override string ToString()
{
return this.name;
}
/// <summary>
/// Close the table.
/// </summary>
public void Close()
{
this.CheckObjectIsNotDisposed();
this.ReleaseResource();
}
/// <summary>
/// Free the underlying JET_TABLEID.
/// </summary>
protected override void ReleaseResource()
{
Api.JetCloseTable(this.sesid, this.tableid);
this.sesid = JET_SESID.Nil;
this.tableid = JET_TABLEID.Nil;
this.name = null;
this.ResourceWasReleased();
}
}
}

View File

@ -1,53 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="TableColumnInfoEnumerator.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Enumerate columns in a table specified by dbid and name.
/// </summary>
internal sealed class TableColumnInfoEnumerator : ColumnInfoEnumerator
{
/// <summary>
/// The database containing the table.
/// </summary>
private readonly JET_DBID dbid;
/// <summary>
/// The name of the table.
/// </summary>
private readonly string tablename;
/// <summary>
/// Initializes a new instance of the <see cref="TableColumnInfoEnumerator"/> class.
/// </summary>
/// <param name="sesid">
/// The session to use.
/// </param>
/// <param name="dbid">
/// The database containing the table.
/// </param>
/// <param name="tablename">
/// The name of the table.
/// </param>
public TableColumnInfoEnumerator(JET_SESID sesid, JET_DBID dbid, string tablename) : base(sesid)
{
this.dbid = dbid;
this.tablename = tablename;
}
/// <summary>
/// Open the table to be enumerated. This should set <see cref="TableEnumerator{T}.TableidToEnumerate"/>.
/// </summary>
protected override void OpenTable()
{
JET_COLUMNLIST columnlist;
Api.JetGetColumnInfo(this.Sesid, this.dbid, this.tablename, string.Empty, out columnlist);
this.Columnlist = columnlist;
this.TableidToEnumerate = this.Columnlist.tableid;
}
}
}

View File

@ -1,167 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="TableEnumerator.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
/// <summary>
/// Base class for enumerators that walk a table.
/// </summary>
/// <typeparam name="T">The type returned by the enumerator.</typeparam>
internal abstract class TableEnumerator<T> : IEnumerator<T>
{
/// <summary>
/// True if we are at the end of the table.
/// </summary>
private bool isAtEnd;
/// <summary>
/// True if we need to move to the first record in the table.
/// </summary>
private bool moveToFirst = true;
/// <summary>
/// Initializes a new instance of the <see cref="TableEnumerator{T}"/> class.
/// </summary>
/// <param name="sesid">
/// The session to use.
/// </param>
protected TableEnumerator(JET_SESID sesid)
{
this.Sesid = sesid;
this.TableidToEnumerate = JET_TABLEID.Nil;
}
/// <summary>
/// Gets the current entry.
/// </summary>
public T Current { get; private set; }
/// <summary>
/// Gets the current entry.
/// </summary>
object IEnumerator.Current
{
[DebuggerStepThrough]
get { return this.Current; }
}
/// <summary>
/// Gets the session used for the enumeration.
/// </summary>
protected JET_SESID Sesid { get; private set; }
/// <summary>
/// Gets or sets the table being enumerated.
/// </summary>
protected JET_TABLEID TableidToEnumerate { get; set; }
/// <summary>
/// Resets the enumerator. The next call to MoveNext will move
/// to the first entry.
/// </summary>
public void Reset()
{
this.isAtEnd = false;
this.moveToFirst = true;
}
/// <summary>
/// Disposes of any resources the enumerator is using.
/// </summary>
public void Dispose()
{
this.CloseTable();
GC.SuppressFinalize(this);
}
/// <summary>
/// Move to the next entry.
/// </summary>
/// <returns>
/// True if an entry was found, false otherwise.
/// </returns>
public bool MoveNext()
{
// Moving to the end is sticky (until Reset is called)
if (this.isAtEnd)
{
return false;
}
if (this.TableidToEnumerate.IsInvalid)
{
Debug.Assert(this.moveToFirst, "Table has not been opened so moveToFirst should be true");
this.OpenTable();
}
bool needMoveNext = true;
if (this.moveToFirst)
{
if (!Api.TryMoveFirst(this.Sesid, this.TableidToEnumerate))
{
this.isAtEnd = true;
return false;
}
this.moveToFirst = false;
needMoveNext = false;
}
while (needMoveNext || this.SkipCurrent())
{
if (!Api.TryMoveNext(this.Sesid, this.TableidToEnumerate))
{
this.isAtEnd = true;
return false;
}
needMoveNext = false;
}
this.Current = this.GetCurrent();
return true;
}
/// <summary>
/// Open the table to be enumerated. This should set <see cref="TableidToEnumerate"/>.
/// </summary>
protected abstract void OpenTable();
/// <summary>
/// Gets the entry the cursor is currently positioned on.
/// </summary>
/// <returns>The entry the cursor is currently positioned on.</returns>
protected abstract T GetCurrent();
/// <summary>
/// Determine if the current entry in the table being enumerated should
/// be skipped (not returned). By default this is false.
/// </summary>
/// <returns>True if the current entry should be skipped.</returns>
protected virtual bool SkipCurrent()
{
return false;
}
/// <summary>
/// Closes the table being enumerated.
/// </summary>
protected virtual void CloseTable()
{
if (!this.TableidToEnumerate.IsInvalid)
{
Api.JetCloseTable(this.Sesid, this.TableidToEnumerate);
}
this.TableidToEnumerate = JET_TABLEID.Nil;
}
}
}

View File

@ -1,70 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="TableIndexInfoEnumerator.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Enumerate columns in a table specified by dbid and name.
/// </summary>
internal sealed class TableIndexInfoEnumerator : IndexInfoEnumerator
{
/// <summary>
/// The database containing the table.
/// </summary>
private readonly JET_DBID dbid;
/// <summary>
/// The name of the table.
/// </summary>
private readonly string tablename;
/// <summary>
/// Initializes a new instance of the <see cref="TableIndexInfoEnumerator"/> class.
/// </summary>
/// <param name="sesid">
/// The session to use.
/// </param>
/// <param name="dbid">
/// The database containing the table.
/// </param>
/// <param name="tablename">
/// The name of the table.
/// </param>
public TableIndexInfoEnumerator(JET_SESID sesid, JET_DBID dbid, string tablename)
: base(sesid)
{
this.dbid = dbid;
this.tablename = tablename;
}
/// <summary>
/// Open the table to be enumerated. This should set <see cref="TableEnumerator{T}.TableidToEnumerate"/>.
/// </summary>
protected override void OpenTable()
{
JET_INDEXLIST indexlist;
Api.JetGetIndexInfo(this.Sesid, this.dbid, this.tablename, string.Empty, out indexlist, JET_IdxInfo.List);
this.Indexlist = indexlist;
this.TableidToEnumerate = this.Indexlist.tableid;
}
/// <summary>
/// Retrieves information about indexes on a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="indexname">The name of the index.</param>
/// <param name="result">Filled in with information about indexes on the table.</param>
/// <param name="infoLevel">The type of information to retrieve.</param>
protected override void GetIndexInfo(
JET_SESID sesid,
string indexname,
out string result,
JET_IdxInfo infoLevel)
{
Api.JetGetIndexInfo(sesid, this.dbid, this.tablename, indexname, out result, infoLevel);
}
}
}

Some files were not shown because too many files have changed in this diff Show More