├── .gitignore ├── .vs └── LiteGraph │ ├── DesignTimeBuild │ └── .dtbcache.v2 │ └── v16 │ └── .suo ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DONATIONS.md ├── Docker ├── compose-down.bat ├── compose-down.sh ├── compose-up.bat ├── compose-up.sh ├── compose.yaml ├── litegraph.db ├── litegraph.json ├── run.bat └── run.sh ├── LICENSE.md ├── LiteGraph.postman_collection.json ├── README.md ├── REST_API.md ├── assets ├── SampleGraphs.pptx ├── default1-graph.png ├── default2-graph.png ├── favicon.ico ├── favicon.png ├── favicon.pptx ├── icon.ico ├── icon.png ├── icon.pptx └── magnifying-glass.png └── src ├── LiteGraph.Server ├── API │ ├── Agnostic │ │ └── ServiceHandler.cs │ └── REST │ │ └── RestServiceHandler.cs ├── Classes │ ├── ApiErrorEnum.cs │ ├── ApiErrorResponse.cs │ ├── ApiVersionEnum.cs │ ├── AuthenticationContext.cs │ ├── AuthenticationResultEnum.cs │ ├── AuthenticationToken.cs │ ├── AuthorizationContext.cs │ ├── AuthorizationResultEnum.cs │ ├── BackupRequest.cs │ ├── Constants.cs │ ├── DebugSettings.cs │ ├── EncryptionSettings.cs │ ├── LiteGraphSettings.cs │ ├── RequestContext.cs │ ├── RequestTypeEnum.cs │ ├── ResponseContext.cs │ ├── RouteRequest.cs │ ├── RouteResponse.cs │ ├── Settings.cs │ ├── StorageSettings.cs │ └── UrlContext.cs ├── CopyDbFromTest.bat ├── Dockerbuild.bat ├── Dockerfile ├── Dockerrun.bat ├── Dockerrun.sh ├── LiteGraph.Server.csproj ├── LiteGraphServer.cs ├── Services │ └── AuthenticationService.cs ├── assets │ └── favicon.ico ├── clean.bat └── clean.sh ├── LiteGraph.sln ├── LiteGraph ├── BackupFile.cs ├── CachingSettings.cs ├── Client │ ├── Implementations │ │ ├── AdminMethods.cs │ │ ├── BatchMethods.cs │ │ ├── CredentialMethods.cs │ │ ├── EdgeMethods.cs │ │ ├── GraphMethods.cs │ │ ├── LabelMethods.cs │ │ ├── NodeMethods.cs │ │ ├── TagMethods.cs │ │ ├── TenantMethods.cs │ │ ├── UserMethods.cs │ │ └── VectorMethods.cs │ └── Interfaces │ │ ├── IAdminMethods.cs │ │ ├── IBatchMethods.cs │ │ ├── ICredentialMethods.cs │ │ ├── IEdgeMethods.cs │ │ ├── IGraphMethods.cs │ │ ├── ILabelMethods.cs │ │ ├── INodeMethods.cs │ │ ├── ITagMethods.cs │ │ ├── ITenantMethods.cs │ │ ├── IUserMethods.cs │ │ └── IVectorMethods.cs ├── Constants.cs ├── Credential.cs ├── Edge.cs ├── EdgeBetween.cs ├── EnumerationOrderEnum.cs ├── ExistenceRequest.cs ├── ExistenceResult.cs ├── Gexf │ ├── GexfAttribute.cs │ ├── GexfAttributeValue.cs │ ├── GexfAttributeValues.cs │ ├── GexfAttributes.cs │ ├── GexfDocument.cs │ ├── GexfEdge.cs │ ├── GexfEdges.cs │ ├── GexfGraph.cs │ ├── GexfMetadata.cs │ ├── GexfNode.cs │ ├── GexfNodes.cs │ └── GexfWriter.cs ├── Graph.cs ├── GraphRepositories │ ├── GraphRepositoryBase.cs │ ├── Interfaces │ │ ├── IAdminMethods.cs │ │ ├── IBatchMethods.cs │ │ ├── ICredentialMethods.cs │ │ ├── IEdgeMethods.cs │ │ ├── IGraphMethods.cs │ │ ├── ILabelMethods.cs │ │ ├── INodeMethods.cs │ │ ├── ITagMethods.cs │ │ ├── ITenantMethods.cs │ │ ├── IUserMethods.cs │ │ └── IVectorMethods.cs │ └── Sqlite │ │ ├── Converters.cs │ │ ├── Implementations │ │ ├── AdminMethods.cs │ │ ├── BatchMethods.cs │ │ ├── CredentialMethods.cs │ │ ├── EdgeMethods.cs │ │ ├── GraphMethods.cs │ │ ├── LabelMethods.cs │ │ ├── NodeMethods.cs │ │ ├── TagMethods.cs │ │ ├── TenantMethods.cs │ │ ├── UserMethods.cs │ │ └── VectorMethods.cs │ │ ├── Queries │ │ ├── CredentialQueries.cs │ │ ├── EdgeQueries.cs │ │ ├── GraphQueries.cs │ │ ├── LabelQueries.cs │ │ ├── NodeQueries.cs │ │ ├── SetupQueries.cs │ │ ├── TagQueries.cs │ │ ├── TenantQueries.cs │ │ ├── UserQueries.cs │ │ └── VectorQueries.cs │ │ ├── Sanitizer.cs │ │ └── SqliteGraphRepository.cs ├── Helpers │ ├── FileHelpers.cs │ ├── HashHelper.cs │ ├── NvcHelpers.cs │ ├── StringHelper.cs │ └── VectorHelper.cs ├── LICENSE.md ├── LabelMetadata.cs ├── LiteGraph.csproj ├── LiteGraph.xml ├── LiteGraphClient.cs ├── LoggingSettings.cs ├── Node.cs ├── RouteDetail.cs ├── SearchRequest.cs ├── SearchResult.cs ├── SearchTypeEnum.cs ├── Serialization │ ├── ISerializer.cs │ └── Serializer.cs ├── SeverityEnum.cs ├── StorageSettings.cs ├── SyslogServer.cs ├── TagMetadata.cs ├── TenantMetadata.cs ├── UserMaster.cs ├── VectorMetadata.cs ├── VectorSearchDomainEnum.cs ├── VectorSearchRequest.cs ├── VectorSearchResult.cs ├── VectorSearchTypeEnum.cs └── assets │ ├── favicon.ico │ └── favicon.png ├── Test.RamDatabase ├── Program.cs ├── Test.RamDatabase.csproj └── TestClasses.cs └── Test ├── Program.cs ├── Test.csproj ├── TestClasses.cs ├── clean.bat └── clean.sh /.vs/LiteGraph/DesignTimeBuild/.dtbcache.v2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/.vs/LiteGraph/DesignTimeBuild/.dtbcache.v2 -------------------------------------------------------------------------------- /.vs/LiteGraph/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/.vs/LiteGraph/v16/.suo -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## Current Version 4 | 5 | v4.0.x 6 | 7 | - Major internal refactor for both the graph repository base and the client class 8 | - Separation of responsibilities; graph repository base owns primitives, client class owns validation and cross-cutting 9 | - Consistency in interface API names and behaviors 10 | - Consistency in passing of query parameters such as skip to implementations and primitives 11 | - Consolidation of create, update, and delete actions within a single transaction 12 | - Batch APIs for creation and deletion of labels, tags, vectors, edges, and nodes 13 | - Simple database caching to offload existence validation for tenants, graphs, nodes, and edges 14 | - Dependency updates and bug fixes 15 | - Minor Postman fixes 16 | 17 | ## Previous Versions 18 | 19 | v3.1.x 20 | 21 | - Added support for labels on graphs, nodes, edges (string list) 22 | - Added support for vector persistence and search 23 | - Updated SDK, test, and Postman collections accordingly 24 | - Updated GEXF export to support labels and tags 25 | - Internal refactor to reduce code bloat 26 | - Multiple bugfixes and QoL improvements 27 | 28 | v3.0.x 29 | 30 | - Major internal refactor to support multitenancy and authentication, including tenants (`TenantMetadata`), users (`UserMaster`), and credentials (`Credential`) 31 | - Graph, node, and edge objects are now contained within a given tenant (`TenantGUID`) 32 | - Extensible key and value metadata (`TagMetadata`) support for graphs, nodes, and edges 33 | - Schema changes to make column names more accurate (`id` becomes `guid`) 34 | - Setup script to create default records 35 | - Environment variables for webserver port (`LITEGRAPH_PORT`) and database filename (`LITEGRAPH_DB`) 36 | - Moved logic into a protocol-agnostic handler layer to support future protocols 37 | - Added last update UTC timestamp to each object (`LastUpdateUtc`) 38 | - Authentication using bearer tokens (`Authorization: Bearer [token]`) 39 | - System administrator bearer token defined within the settings file (`Settings.LiteGraph.AdminBearerToken`) with default value `litegraphadmin` 40 | - Tag-based retrieval and filtering for graphs, nodes, and edges 41 | - Updated SDK and test project 42 | - Updated Postman collection 43 | 44 | v2.1.0 45 | 46 | - Added batch APIs for existence, deletion, and creation 47 | - Minor internal refactor 48 | 49 | v2.0.0 50 | 51 | - Major overhaul, refactor, and breaking changes 52 | - Integrated webserver and RESTful API 53 | - Extensibility through base repository class 54 | - Hierarchical expression support while filtering over graph, node, and edge data objects 55 | - Removal of property constraints on nodes and edges 56 | 57 | v1.0.0 58 | 59 | - Initial release -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | - Using welcoming and inclusive language 12 | - Being respectful of differing viewpoints and experiences 13 | - Gracefully accepting constructive criticism 14 | - Focusing on what is best for the community 15 | - Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | - The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | - Trolling, insulting/derogatory comments, and personal or political attacks 21 | - Public or private harassment 22 | - Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | - Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 44 | 45 | For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq 46 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for your interest in contributing! 4 | 5 | The following is a set of guidelines for contributing to our project on Github. These are mostly guidelines, not rules. 6 | 7 | ## Code of Conduct 8 | 9 | This project and everyone participating in it is governed by the Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to project moderators. 10 | 11 | ## Pull Requests 12 | 13 | Please follow these guidelines when submitting pull requests (PRs): 14 | 15 | - PRs should be manageable in size to make it easy for us to validate and integrate 16 | - Each PR should be contained to a single fix or a single feature 17 | - Describe the motivation for the PR 18 | - Describe a methodology to test and validate, if appropriate 19 | 20 | Please ensure that the code in your PR follows a style similar to that of the project. If you find a material discrepancy between the style followed by the project and a de facto standard style given the project language and framework, please let us know so we can amend and make our code more maintainable. 21 | 22 | ## Asking Questions 23 | 24 | Prior to asking questions, please review closed issues and wiki pages. If your question is not answered in either of those places, please feel free to file an issue! This will also help us to build out documentation. 25 | 26 | ## Reporting Bugs 27 | 28 | If you encounter an issue, please let us know! We kindly ask that you supply the following information with your bug report when you file an issue. Feel free to copy/paste from the below and use as a template. 29 | 30 | --- Bug Report --- 31 | 32 | Operating system and version: Windows 10 33 | Framework and runtime: .NET Core 2.0 34 | Issue encountered: The widget shifted left 35 | Expected behavior: The widget should have shifted right 36 | Steps to reproduce: Instantiate the widget and call .ShiftRight() 37 | Sample code encapsulating the problem: 38 | ``` 39 | Widget widget = new Widget(); 40 | widget.ShiftRight(); 41 | ``` 42 | Exception details: [insert exception output here] 43 | Stack trace: [if appropriate] 44 | 45 | --- End --- 46 | 47 | ## Suggesting Enhancements 48 | 49 | Should there be a way that you feel we could improve upon this project, please feel free to file an issue and use the template below to provide the necessary details to support the request. 50 | 51 | Some basic guidelines for suggesting enhancements: 52 | 53 | - Use a clear and descriptive title for the issue to identify the suggestion. 54 | - Provide a step-by-step description of the suggested enhancement in as many details as possible. 55 | - Provide specific examples to demonstrate the steps including copy/pasteable snippets where possible 56 | - Describe the current behavior and the behavior you would like to see 57 | - Describe the usefulness of the enhancement to yourself and potentially to others 58 | 59 | --- Enhancement Request --- 60 | 61 | Enhancement request title: Widgets should have a color attribute 62 | Use case: I want to specify what color a widget is 63 | Current behavior: Widgets don't have a color 64 | Requested behavior: Allow me to specify a widget's color 65 | Recommended implementation: Add a Color attribute to the Widget class 66 | Usefulness of the enhancement: All widgets have color, and everyone has to build their own implementation to set this 67 | 68 | --- End --- 69 | -------------------------------------------------------------------------------- /DONATIONS.md: -------------------------------------------------------------------------------- 1 | ## Donations 2 | 3 | If you're interested in financially supporting this work on other open source projects I manage, first of all, thank you! It brings me delight to know that this software has helped you in some way. Please find below address details for donations using 4 | 5 | ### Traditional 6 | 7 | | Method | Address | 8 | |--------|---------| 9 | | PayPal | @joelchristner - https://paypal.me/joelchristner?country.x=US&locale.x=en_US | 10 | | Venmo | @Joel-Christner - https://account.venmo.com/u/Joel-Christner | 11 | 12 | ### Cryptocurrency (Mainstream) 13 | 14 | | Method | Address | 15 | |----------|---------| 16 | | Bitcoin | 3HRgnvEWQBDdWDp75CFDsz3PirCYmftDwU | 17 | | Ethereum | 0xE064dC84270e17e2Ac34b2552461d672BdBC5e36 | 18 | 19 | ### Cryptocurrency (Altcoins) 20 | 21 | | Method | Address | 22 | |--------|---------| 23 | | XRP | Tag 1765608084 Address rw2ciyaNshpHe7bCHo4bRWq6pqqynnWKQg | 24 | | Shiba Inu SHIB | 0xdA58D4ba0d5823d80a0C42C69E139124B889c69a | 25 | | Algorand ALGO | FFKA23KC4BHEU5HM4OQHLEILVIYDLRXYK6WD6UI573JPUGHZR43JVHAF7A | 26 | | Stellar Lumens XML | Memo 2264929895 Address GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37 | 27 | | Dogecoin DOGE | DQ2dn4UifpYA8RyuNF1t112Y1XH5L42Rxv | 28 | | Cardano ADA | addr1vxrxyrv0phgr2xcl08dj0sfy425mhqehuu4dy99ja4nhtwqfsvgjk | 29 | 30 | If you have a coin you prefer to use, please let me know! 31 | -------------------------------------------------------------------------------- /Docker/compose-down.bat: -------------------------------------------------------------------------------- 1 | docker compose -f compose.yaml down 2 | -------------------------------------------------------------------------------- /Docker/compose-down.sh: -------------------------------------------------------------------------------- 1 | docker compose -f compose.yaml down 2 | -------------------------------------------------------------------------------- /Docker/compose-up.bat: -------------------------------------------------------------------------------- 1 | docker compose -f compose.yaml up 2 | -------------------------------------------------------------------------------- /Docker/compose-up.sh: -------------------------------------------------------------------------------- 1 | docker compose -f compose.yaml up & 2 | -------------------------------------------------------------------------------- /Docker/compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | 3 | # 4 | # LiteGraph 5 | # See https://hub.docker.com/r/jchristn/litegraph 6 | # and https://github.com/jchristn/LiteGraph 7 | # 8 | 9 | litegraph: 10 | container_name: 'litegraph' 11 | image: 'jchristn/litegraph:v4.0.0' 12 | network_mode: 'host' 13 | stdin_open: true 14 | tty: true 15 | volumes: 16 | - ./litegraph.json:/app/litegraph.json 17 | - ./litegraph.db:/app/litegraph.db 18 | - ./logs/:/app/logs/ 19 | - ./backups/:/app/backups/ 20 | healthcheck: 21 | test: curl --fail http://localhost:8701 22 | -------------------------------------------------------------------------------- /Docker/litegraph.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/Docker/litegraph.db -------------------------------------------------------------------------------- /Docker/litegraph.json: -------------------------------------------------------------------------------- 1 | { 2 | "CreatedUtc": "2025-01-27T22:19:01.489573Z", 3 | "Logging": { 4 | "Enable": true, 5 | "Servers": [ 6 | { 7 | "Hostname": "127.0.0.1", 8 | "Port": 514 9 | } 10 | ], 11 | "LogDirectory": "./logs/", 12 | "LogFilename": "litegraph.log", 13 | "ConsoleLogging": true, 14 | "EnableColors": true, 15 | "MinimumSeverity": 0, 16 | "Header": "[LiteGraph] ", 17 | "LogQueries": false, 18 | "LogResults": false 19 | }, 20 | "Caching": { 21 | "Enable": true, 22 | "Capacity": 1000, 23 | "EvictCount": 100 24 | }, 25 | "Rest": { 26 | "Hostname": "*", 27 | "Port": 8701, 28 | "IO": { 29 | "StreamBufferSize": 65536, 30 | "MaxRequests": 1024, 31 | "ReadTimeoutMs": 10000, 32 | "MaxIncomingHeadersSize": 65536, 33 | "EnableKeepAlive": false 34 | }, 35 | "Ssl": { 36 | "Enable": false, 37 | "MutuallyAuthenticate": false, 38 | "AcceptInvalidAcertificates": true 39 | }, 40 | "Headers": { 41 | "IncludeContentLength": true, 42 | "DefaultHeaders": { 43 | "Access-Control-Allow-Origin": "*", 44 | "Access-Control-Allow-Methods": "OPTIONS, HEAD, GET, PUT, POST, DELETE, PATCH", 45 | "Access-Control-Allow-Headers": "*", 46 | "Access-Control-Expose-Headers": "", 47 | "Accept": "*/*", 48 | "Accept-Language": "en-US, en", 49 | "Accept-Charset": "ISO-8859-1, utf-8", 50 | "Cache-Control": "no-cache", 51 | "Connection": "close", 52 | "Host": "localhost:8000" 53 | } 54 | }, 55 | "AccessControl": { 56 | "DenyList": {}, 57 | "PermitList": {}, 58 | "Mode": "DefaultPermit" 59 | }, 60 | "Debug": { 61 | "AccessControl": false, 62 | "Routing": false, 63 | "Requests": false, 64 | "Responses": false 65 | } 66 | }, 67 | "LiteGraph": { 68 | "AdminBearerToken": "litegraphadmin", 69 | "GraphRepositoryFilename": "litegraph.db", 70 | "MaxConcurrentOperations": 4, 71 | "InMemory": false 72 | }, 73 | "Encryption": { 74 | "Key": "0000000000000000000000000000000000000000000000000000000000000000", 75 | "Iv": "00000000000000000000000000000000" 76 | }, 77 | "Storage": { 78 | "BackupsDirectory": "./backups/" 79 | }, 80 | "Debug": { 81 | "Authentication": false, 82 | "Exceptions": true, 83 | "Requests": false, 84 | "DatabaseQueries": false 85 | } 86 | } -------------------------------------------------------------------------------- /Docker/run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | IF "%1" == "" GOTO :Usage 4 | 5 | if not exist litegraph.json ( 6 | echo Configuration file litegraph.json not found. 7 | exit /b 1 8 | ) 9 | 10 | REM Items that require persistence 11 | REM litegraph.json 12 | REM litegraph.db 13 | REM logs/ 14 | REM backups/ 15 | 16 | REM Argument order matters! 17 | 18 | docker run ^ 19 | -p 8701:8701 ^ 20 | -t ^ 21 | -i ^ 22 | -e "TERM=xterm-256color" ^ 23 | -v .\litegraph.json:/app/litegraph.json ^ 24 | -v .\litegraph.db:/app/litegraph.db ^ 25 | -v .\logs\:/app/logs/ ^ 26 | -v .\backups\:/app/backups/ ^ 27 | jchristn/litegraph:%1 28 | 29 | GOTO :Done 30 | 31 | :Usage 32 | ECHO Provide one argument indicating the tag. 33 | ECHO Example: dockerrun.bat v3.1.0 34 | :Done 35 | @echo on 36 | -------------------------------------------------------------------------------- /Docker/run.sh: -------------------------------------------------------------------------------- 1 | if [ -z "${IMG_TAG}" ]; then 2 | IMG_TAG='v3.1.0' 3 | fi 4 | 5 | echo Using image tag $IMG_TAG 6 | 7 | if [ ! -f "litegraph.json" ] 8 | then 9 | echo Configuration file litegraph.json not found. 10 | exit 11 | fi 12 | 13 | # Items that require persistence 14 | # litegraph.json 15 | # litegraph.db 16 | # logs/ 17 | # backups/ 18 | 19 | # Argument order matters! 20 | 21 | docker run \ 22 | -p 8701:8701 \ 23 | -t \ 24 | -i \ 25 | -e "TERM=xterm-256color" \ 26 | -v ./litegraph.json:/app/litegraph.json \ 27 | -v ./litegraph.db:/app/litegraph.db \ 28 | -v ./logs/:/app/logs/ \ 29 | -v ./backups/:/app/backups/ \ 30 | jchristn/litegraph:$IMG_TAG 31 | 32 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /assets/SampleGraphs.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/assets/SampleGraphs.pptx -------------------------------------------------------------------------------- /assets/default1-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/assets/default1-graph.png -------------------------------------------------------------------------------- /assets/default2-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/assets/default2-graph.png -------------------------------------------------------------------------------- /assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/assets/favicon.ico -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/assets/favicon.png -------------------------------------------------------------------------------- /assets/favicon.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/assets/favicon.pptx -------------------------------------------------------------------------------- /assets/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/assets/icon.ico -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/assets/icon.png -------------------------------------------------------------------------------- /assets/icon.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/assets/icon.pptx -------------------------------------------------------------------------------- /assets/magnifying-glass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/assets/magnifying-glass.png -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/ApiErrorEnum.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System.Runtime.Serialization; 4 | using System.Text.Json.Serialization; 5 | 6 | /// 7 | /// API error codes. 8 | /// 9 | [JsonConverter(typeof(JsonStringEnumConverter))] 10 | public enum ApiErrorEnum 11 | { 12 | /// 13 | /// Authentication failed. 14 | /// 15 | [EnumMember(Value = "AuthenticationFailed")] 16 | AuthenticationFailed, 17 | /// 18 | /// Authorization failed. 19 | /// 20 | [EnumMember(Value = "AuthorizationFailed")] 21 | AuthorizationFailed, 22 | /// 23 | /// Bad request. 24 | /// 25 | [EnumMember(Value = "BadRequest")] 26 | BadRequest, 27 | /// 28 | /// Conflict. 29 | /// 30 | [EnumMember(Value = "Conflict")] 31 | Conflict, 32 | /// 33 | /// DeserializationError. 34 | /// 35 | [EnumMember(Value = "DeserializationError")] 36 | DeserializationError, 37 | /// 38 | /// Inactive. 39 | /// 40 | [EnumMember(Value = "Inactive")] 41 | Inactive, 42 | /// 43 | /// Internal error. 44 | /// 45 | [EnumMember(Value = "InternalError")] 46 | InternalError, 47 | /// 48 | /// Invalid range. 49 | /// 50 | [EnumMember(Value = "InvalidRange")] 51 | InvalidRange, 52 | /// 53 | /// In use. 54 | /// 55 | [EnumMember(Value = "InUse")] 56 | InUse, 57 | /// 58 | /// Not empty. 59 | /// 60 | [EnumMember(Value = "NotEmpty")] 61 | NotEmpty, 62 | /// 63 | /// Not found. 64 | /// 65 | [EnumMember(Value = "NotFound")] 66 | NotFound, 67 | /// 68 | /// Request too large. 69 | /// 70 | [EnumMember(Value = "TooLarge")] 71 | TooLarge 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/ApiVersionEnum.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System.Runtime.Serialization; 4 | using System.Text.Json.Serialization; 5 | 6 | /// 7 | /// API versions. 8 | /// 9 | [JsonConverter(typeof(JsonStringEnumConverter))] 10 | public enum ApiVersionEnum 11 | { 12 | /// 13 | /// Unknown. 14 | /// 15 | [EnumMember(Value = "Unknown")] 16 | Unknown, 17 | /// 18 | /// V1.0. 19 | /// 20 | [EnumMember(Value = "v1.0")] 21 | V1_0 22 | } 23 | } -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/AuthenticationContext.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using WatsonWebserver.Core; 9 | 10 | /// 11 | /// Authentication context. 12 | /// 13 | public class AuthenticationContext 14 | { 15 | #region Public-Members 16 | 17 | /// 18 | /// Email address. 19 | /// 20 | public string Email { get; set; } = null; 21 | 22 | /// 23 | /// Password. 24 | /// 25 | public string Password { get; set; } = null; 26 | 27 | /// 28 | /// Bearer token. 29 | /// 30 | public string BearerToken { get; set; } = null; 31 | 32 | /// 33 | /// Security token. 34 | /// 35 | public string SecurityToken { get; set; } = null; 36 | 37 | /// 38 | /// Tenant GUID. 39 | /// 40 | public Guid? TenantGUID { get; set; } = null; 41 | 42 | /// 43 | /// Tenant. 44 | /// 45 | public TenantMetadata Tenant { get; set; } = null; 46 | 47 | /// 48 | /// User GUID. 49 | /// 50 | public Guid? UserGUID { get; set; } = null; 51 | 52 | /// 53 | /// User. 54 | /// 55 | public UserMaster User { get; set; } = null; 56 | 57 | /// 58 | /// Credential GUID. 59 | /// 60 | public Guid? CredentialGUID { get; set; } = null; 61 | 62 | /// 63 | /// Credential. 64 | /// 65 | public Credential Credential { get; set; } = null; 66 | 67 | /// 68 | /// Boolean indicating if the user is a system administrator using the administrator bearer token. 69 | /// 70 | public bool IsAdmin { get; set; } = false; 71 | 72 | /// 73 | /// Authentication result. 74 | /// 75 | public AuthenticationResultEnum Result { get; set; } = AuthenticationResultEnum.NotFound; 76 | 77 | #endregion 78 | 79 | #region Private-Members 80 | 81 | #endregion 82 | 83 | #region Constructors-and-Factories 84 | 85 | /// 86 | /// Instantiate. 87 | /// 88 | public AuthenticationContext() 89 | { 90 | 91 | } 92 | 93 | #endregion 94 | 95 | #region Public-Methods 96 | 97 | #endregion 98 | 99 | #region Private-Methods 100 | 101 | #endregion 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/AuthenticationResultEnum.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Runtime.Serialization; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// Authentication result. 12 | /// 13 | public enum AuthenticationResultEnum 14 | { 15 | /// 16 | /// Success. 17 | /// 18 | [EnumMember(Value = "Success")] 19 | Success, 20 | /// 21 | /// Not found. 22 | /// 23 | [EnumMember(Value = "NotFound")] 24 | NotFound, 25 | /// 26 | /// Inactive. 27 | /// 28 | [EnumMember(Value = "Inactive")] 29 | Inactive, 30 | /// 31 | /// Invalid. 32 | /// 33 | [EnumMember(Value = "Invalid")] 34 | Invalid 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/AuthenticationToken.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | using PrettyId; 7 | 8 | /// 9 | /// Authentication token details. 10 | /// 11 | public class AuthenticationToken 12 | { 13 | #region Public-Members 14 | 15 | /// 16 | /// Timestamp when the token was issued, in UTC time. 17 | /// 18 | public DateTime TimestampUtc { get; set; } = DateTime.UtcNow; 19 | 20 | /// 21 | /// Timestamp when the token will expire, in UTC time. 22 | /// 23 | public DateTime ExpirationUtc { get; set; } = DateTime.UtcNow.AddHours(24); 24 | 25 | /// 26 | /// Boolean to indicate if the token is expired. 27 | /// 28 | public bool IsExpired 29 | { 30 | get 31 | { 32 | return TimestampUtc > ExpirationUtc; 33 | } 34 | } 35 | 36 | /// 37 | /// Random string. 38 | /// 39 | public string Random { get; set; } = IdGenerator.GenerateBase64(); 40 | 41 | /// 42 | /// Tenant GUID. 43 | /// 44 | public Guid? TenantGUID { get; set; } = null; 45 | 46 | /// 47 | /// Tenant. 48 | /// 49 | public TenantMetadata Tenant { get; set; } = null; 50 | 51 | /// 52 | /// User GUID. 53 | /// 54 | public Guid? UserGUID { get; set; } = null; 55 | 56 | /// 57 | /// User. 58 | /// 59 | public UserMaster User { get; set; } = null; 60 | 61 | /// 62 | /// Token. 63 | /// 64 | public string Token { get; set; } = null; 65 | 66 | /// 67 | /// Boolean indicating whether or not the token is valid. 68 | /// 69 | public bool Valid { get; set; } = true; 70 | 71 | #endregion 72 | 73 | #region Private-Members 74 | 75 | #endregion 76 | 77 | #region Constructors-and-Factories 78 | 79 | /// 80 | /// Instantiate. 81 | /// 82 | public AuthenticationToken() 83 | { 84 | 85 | } 86 | 87 | #endregion 88 | 89 | #region Public-Methods 90 | 91 | #endregion 92 | 93 | #region Private-Methods 94 | 95 | #endregion 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/AuthorizationContext.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using WatsonWebserver.Core; 9 | 10 | /// 11 | /// Authorization context. 12 | /// 13 | public class AuthorizationContext 14 | { 15 | #region Public-Members 16 | 17 | /// 18 | /// Authorization result. 19 | /// 20 | public AuthorizationResultEnum Result { get; set; } = AuthorizationResultEnum.Denied; 21 | 22 | #endregion 23 | 24 | #region Private-Members 25 | 26 | #endregion 27 | 28 | #region Constructors-and-Factories 29 | 30 | /// 31 | /// Instantiate. 32 | /// 33 | public AuthorizationContext() 34 | { 35 | 36 | } 37 | 38 | #endregion 39 | 40 | #region Public-Methods 41 | 42 | #endregion 43 | 44 | #region Private-Methods 45 | 46 | #endregion 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/AuthorizationResultEnum.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Runtime.Serialization; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// Authorization result. 12 | /// 13 | public enum AuthorizationResultEnum 14 | { 15 | /// 16 | /// Permitted. 17 | /// 18 | [EnumMember(Value = "Permitted")] 19 | Permitted, 20 | /// 21 | /// Denied. 22 | /// 23 | [EnumMember(Value = "Denied")] 24 | Denied, 25 | /// 26 | /// Not found. 27 | /// 28 | [EnumMember(Value = "NotFound")] 29 | NotFound, 30 | /// 31 | /// Conflict. 32 | /// 33 | [EnumMember(Value = "Conflict")] 34 | Conflict 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/BackupRequest.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// Backup request. 12 | /// 13 | public class BackupRequest 14 | { 15 | #region Public-Members 16 | 17 | /// 18 | /// File to which the backup should be written. 19 | /// 20 | public string Filename 21 | { 22 | get 23 | { 24 | return _Filename; 25 | } 26 | set 27 | { 28 | if (String.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Filename)); 29 | if (value.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) 30 | throw new ArgumentException("The specified filename contains invalid characters."); 31 | _Filename = value; 32 | } 33 | } 34 | 35 | #endregion 36 | 37 | #region Private-Members 38 | 39 | private string _Filename = "litegraph-backup-" + DateTime.UtcNow.ToString("yyyyMMdd-HHmmss") + ".db"; 40 | 41 | #endregion 42 | 43 | #region Constructors-and-Factories 44 | 45 | /// 46 | /// Backup requets. 47 | /// 48 | public BackupRequest() 49 | { 50 | 51 | } 52 | 53 | #endregion 54 | 55 | #region Public-Methods 56 | 57 | #endregion 58 | 59 | #region Private-Methods 60 | 61 | #endregion 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | 5 | /// 6 | /// Constants. 7 | /// 8 | internal static class Constants 9 | { 10 | /// 11 | /// Logo. 12 | /// 13 | public static string Logo = 14 | @" _ _ _ _ " + Environment.NewLine + 15 | @" | (_) |_ ___ __ _ _ _ __ _ _ __| |_ " + Environment.NewLine + 16 | @" | | | _/ -_) _` | '_/ _` | '_ \ ' \ " + Environment.NewLine + 17 | @" |_|_|\__\___\__, |_| \__,_| .__/_||_| " + Environment.NewLine + 18 | @" |___/ |_| " + Environment.NewLine; 19 | 20 | /// 21 | /// Product name. 22 | /// 23 | public static string ProductName = " LiteGraph Server"; 24 | 25 | /// 26 | /// Copyright. 27 | /// 28 | public static string Copyright = " (c)2025 Joel Christner"; 29 | 30 | /// 31 | /// Settings file. 32 | /// 33 | public static string SettingsFile = "./litegraph.json"; 34 | 35 | /// 36 | /// Log file directory. 37 | /// 38 | public static string LogDirectory = "./logs/"; 39 | 40 | /// 41 | /// Log filename. 42 | /// 43 | public static string LogFilename = "litegraph.log"; 44 | 45 | #region Environment-Variables 46 | 47 | /// 48 | /// Webserver port environment variable. 49 | /// 50 | public static string WebserverPortEnvironmentVariable = "LITEGRAPH_PORT"; 51 | 52 | /// 53 | /// Data database filename environment variable. 54 | /// 55 | public static string DatabaseFilenameEnvironmentVariable = "LITEGRAPH_DB"; 56 | 57 | #endregion 58 | 59 | #region Content-Types 60 | 61 | /// 62 | /// Content-type value for XML. 63 | /// 64 | public static string XmlContentType = "application/xml"; 65 | 66 | /// 67 | /// Content-type value for JSON. 68 | /// 69 | public static string JsonContentType = "application/json"; 70 | 71 | /// 72 | /// Content-type value for HTML. 73 | /// 74 | public static string HtmlContentType = "text/html"; 75 | 76 | /// 77 | /// Favicon content type. 78 | /// 79 | public static string FaviconContentType = "image/x-icon"; 80 | 81 | #endregion 82 | 83 | #region HTML 84 | 85 | /// 86 | /// Default homepage contents. 87 | /// 88 | public static string DefaultHomepage = 89 | "" 90 | + "LiteGraph" 91 | + "" 92 | + "
" + Logo + Environment.NewLine
 93 |             + " Your LiteGraph node is operational

" 94 | + "" 95 | + ""; 96 | 97 | /// 98 | /// Favicon file. 99 | /// 100 | public static string FaviconFile = "./assets/favicon.ico"; 101 | 102 | #endregion 103 | 104 | #region Headers 105 | 106 | /// 107 | /// Hostname header key. 108 | /// 109 | public static string HostnameHeader = "x-hostname"; 110 | 111 | /// 112 | /// Authorization header. 113 | /// 114 | public static string AuthorizationHeader = "Authorization"; 115 | 116 | /// 117 | /// Email header. 118 | /// 119 | public static string EmailHeader = "x-email"; 120 | 121 | /// 122 | /// Password header. 123 | /// 124 | public static string PasswordHeader = "x-password"; 125 | 126 | /// 127 | /// Tenant GUID header. 128 | /// 129 | public static string TenantGuidHeader = "x-tenant-guid"; 130 | 131 | /// 132 | /// Token header. 133 | /// 134 | public static string TokenHeader = "x-token"; 135 | 136 | #endregion 137 | 138 | #region Querystring 139 | 140 | /// 141 | /// Enumeration order querystring. 142 | /// 143 | public static string EnumerationOrderQuerystring = "order"; 144 | 145 | /// 146 | /// Skip querystring key. 147 | /// 148 | public static string SkipQuerystring = "skip"; 149 | 150 | /// 151 | /// Force querystring key. 152 | /// 153 | public static string ForceQuerystring = "force"; 154 | 155 | /// 156 | /// Include data querystring key. 157 | /// 158 | public static string IncludeDataQuerystring = "incldata"; 159 | 160 | /// 161 | /// From GUID querystring key. 162 | /// 163 | public static string FromGuidQuerystring = "from"; 164 | 165 | /// 166 | /// To GUID querystring key. 167 | /// 168 | public static string ToGuidQuerystring = "to"; 169 | 170 | #endregion 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/DebugSettings.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | 5 | /// 6 | /// Debug settings. 7 | /// 8 | public class DebugSettings 9 | { 10 | /// 11 | /// Debug authentication. 12 | /// 13 | public bool Authentication { get; set; } = false; 14 | 15 | /// 16 | /// Debug exceptions. 17 | /// 18 | public bool Exceptions { get; set; } = true; 19 | 20 | /// 21 | /// Debug requests. 22 | /// 23 | public bool Requests { get; set; } = false; 24 | 25 | /// 26 | /// Debug database queries. 27 | /// 28 | public bool DatabaseQueries { get; set; } = false; 29 | 30 | /// 31 | /// Instantiate. 32 | /// 33 | public DebugSettings() 34 | { 35 | 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/EncryptionSettings.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | /// 7 | /// Encryption settings. 8 | /// 9 | public class EncryptionSettings 10 | { 11 | #region Public-Members 12 | 13 | /// 14 | /// Encryption key as a hex string. 15 | /// Value must be 64 hexadecimal characters, representing 32 bytes. 16 | /// 17 | public string Key 18 | { 19 | get 20 | { 21 | return _Key; 22 | } 23 | set 24 | { 25 | if (String.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Key)); 26 | if (value.Length != 64) throw new ArgumentException("Supplied encryption key must be a hex string containing 64 characters representing 32 bytes."); 27 | _Key = value; 28 | } 29 | } 30 | 31 | /// 32 | /// Initialization vector as a hex string. 33 | /// Value must be 32 hexadecimal characters, representing 16 bytes. 34 | /// 35 | public string Iv 36 | { 37 | get 38 | { 39 | return _Iv; 40 | } 41 | set 42 | { 43 | if (String.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Iv)); 44 | if (value.Length != 32) throw new ArgumentException("Supplied initialization vector must be a hex string containing 32 characters representing 16 bytes."); 45 | _Iv = value; 46 | } 47 | } 48 | 49 | #endregion 50 | 51 | #region Private-Members 52 | 53 | private string _Key = "0000000000000000000000000000000000000000000000000000000000000000"; 54 | private string _Iv = "00000000000000000000000000000000"; 55 | 56 | #endregion 57 | 58 | #region Constructors-and-Factories 59 | 60 | /// 61 | /// Instantiate. 62 | /// 63 | public EncryptionSettings() 64 | { 65 | 66 | } 67 | 68 | #endregion 69 | 70 | #region Public-Methods 71 | 72 | #endregion 73 | 74 | #region Private-Methods 75 | 76 | #endregion 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/LiteGraphSettings.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | /// 7 | /// LiteGraph settings. 8 | /// 9 | public class LiteGraphSettings 10 | { 11 | #region Public-Members 12 | 13 | /// 14 | /// Administrator bearer token. 15 | /// 16 | public string AdminBearerToken 17 | { 18 | get 19 | { 20 | return _AdminBearerToken; 21 | } 22 | set 23 | { 24 | if (String.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(AdminBearerToken)); 25 | _AdminBearerToken = value; 26 | } 27 | } 28 | 29 | /// 30 | /// Sqlite data repository filename. 31 | /// 32 | public string GraphRepositoryFilename 33 | { 34 | get 35 | { 36 | return _GraphRepositoryFilename; 37 | } 38 | set 39 | { 40 | if (String.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(GraphRepositoryFilename)); 41 | _GraphRepositoryFilename = value; 42 | } 43 | } 44 | 45 | /// 46 | /// Maximum number of concurrent operations. 47 | /// For higher concurrency, use a lower number (e.g. 1). 48 | /// For lower concurrency, use a higher number (e.g. 10). 49 | /// This value dictates the maximum number of operations that may be operating in parallel at any one given time. 50 | /// 51 | public int MaxConcurrentOperations 52 | { 53 | get 54 | { 55 | return _MaxConcurrentOperations; 56 | } 57 | } 58 | 59 | /// 60 | /// Boolean indicating if the database should be in-memory. 61 | /// 62 | public bool InMemory { get; set; } = false; 63 | 64 | #endregion 65 | 66 | #region Private-Members 67 | 68 | private string _AdminBearerToken = "litegraphadmin"; 69 | private string _GraphRepositoryFilename = "litegraph.db"; 70 | private int _MaxConcurrentOperations = 4; 71 | 72 | #endregion 73 | 74 | #region Constructors-and-Factories 75 | 76 | /// 77 | /// Instantiate. 78 | /// 79 | public LiteGraphSettings() 80 | { 81 | 82 | } 83 | 84 | #endregion 85 | 86 | #region Public-Methods 87 | 88 | #endregion 89 | 90 | #region Private-Methods 91 | 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/RouteRequest.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using ExpressionTree; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// Route request. 12 | /// 13 | public class RouteRequest 14 | { 15 | #region Public-Members 16 | 17 | /// 18 | /// Tenant GUID. 19 | /// 20 | public Guid TenantGUID { get; set; } = default(Guid); 21 | 22 | /// 23 | /// Graph GUID. 24 | /// 25 | public Guid GraphGUID { get; set; } = default(Guid); 26 | 27 | /// 28 | /// From node GUID. 29 | /// 30 | public Guid From { get; set; } = default(Guid); 31 | 32 | /// 33 | /// To node GUID. 34 | /// 35 | public Guid To { get; set; } = default(Guid); 36 | 37 | /// 38 | /// Edge filters. 39 | /// 40 | public Expr EdgeFilter { get; set; } = null; 41 | 42 | /// 43 | /// Node filters. 44 | /// 45 | public Expr NodeFilter { get; set; } = null; 46 | 47 | #endregion 48 | 49 | #region Private-Members 50 | 51 | #endregion 52 | 53 | #region Constructors-and-Factories 54 | 55 | /// 56 | /// Route request. 57 | /// 58 | public RouteRequest() 59 | { 60 | 61 | } 62 | 63 | #endregion 64 | 65 | #region Public-Methods 66 | 67 | #endregion 68 | 69 | #region Private-Methods 70 | 71 | #endregion 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/RouteResponse.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using ExpressionTree; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | using Timestamps; 11 | 12 | /// 13 | /// Route response. 14 | /// 15 | public class RouteResponse 16 | { 17 | #region Public-Members 18 | 19 | /// 20 | /// Timestamp. 21 | /// 22 | public Timestamp Timestamp 23 | { 24 | get 25 | { 26 | return _Timestamp; 27 | } 28 | set 29 | { 30 | if (value == null) throw new ArgumentNullException(nameof(Timestamp)); 31 | _Timestamp = value; 32 | } 33 | } 34 | 35 | /// 36 | /// Routes. 37 | /// 38 | public List Routes 39 | { 40 | get 41 | { 42 | return _Routes; 43 | } 44 | set 45 | { 46 | if (value == null) value = new List(); 47 | _Routes = value; 48 | } 49 | } 50 | 51 | #endregion 52 | 53 | #region Private-Members 54 | 55 | private Timestamp _Timestamp = new Timestamp(); 56 | private List _Routes = new List(); 57 | 58 | #endregion 59 | 60 | #region Constructors-and-Factories 61 | 62 | /// 63 | /// Route request. 64 | /// 65 | public RouteResponse() 66 | { 67 | 68 | } 69 | 70 | #endregion 71 | 72 | #region Public-Methods 73 | 74 | #endregion 75 | 76 | #region Private-Methods 77 | 78 | #endregion 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/Settings.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using System; 4 | using WatsonWebserver.Core; 5 | 6 | /// 7 | /// Settings. 8 | /// 9 | public class Settings 10 | { 11 | #region Public-Members 12 | 13 | /// 14 | /// Timestamp from creation, in UTC time. 15 | /// 16 | public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; 17 | 18 | /// 19 | /// Logging settings. 20 | /// 21 | public LoggingSettings Logging 22 | { 23 | get 24 | { 25 | return _Logging; 26 | } 27 | set 28 | { 29 | if (value == null) throw new ArgumentNullException(nameof(Logging)); 30 | _Logging = value; 31 | } 32 | } 33 | 34 | /// 35 | /// Caching settings. 36 | /// 37 | public CachingSettings Caching 38 | { 39 | get 40 | { 41 | return _Caching; 42 | } 43 | set 44 | { 45 | if (value == null) value = new CachingSettings(); 46 | _Caching = value; 47 | } 48 | } 49 | 50 | /// 51 | /// REST settings. 52 | /// 53 | public WebserverSettings Rest 54 | { 55 | get 56 | { 57 | return _Rest; 58 | } 59 | set 60 | { 61 | if (value == null) throw new ArgumentNullException(nameof(Rest)); 62 | _Rest = value; 63 | } 64 | } 65 | 66 | /// 67 | /// LiteGraph settings. 68 | /// 69 | public LiteGraphSettings LiteGraph 70 | { 71 | get 72 | { 73 | return _LiteGraph; 74 | } 75 | set 76 | { 77 | if (value == null) throw new ArgumentNullException(nameof(LiteGraph)); 78 | _LiteGraph = value; 79 | } 80 | } 81 | 82 | /// 83 | /// Encryption settings. 84 | /// 85 | public EncryptionSettings Encryption 86 | { 87 | get 88 | { 89 | return _Encryption; 90 | } 91 | set 92 | { 93 | if (value == null) throw new ArgumentNullException(nameof(EncryptionSettings)); 94 | _Encryption = value; 95 | } 96 | } 97 | 98 | /// 99 | /// Storage settings. 100 | /// 101 | public StorageSettings Storage 102 | { 103 | get 104 | { 105 | return _Storage; 106 | } 107 | set 108 | { 109 | if (value == null) throw new ArgumentNullException(nameof(Storage)); 110 | _Storage = value; 111 | } 112 | } 113 | 114 | /// 115 | /// Debug settings. 116 | /// 117 | public DebugSettings Debug 118 | { 119 | get 120 | { 121 | return _Debug; 122 | } 123 | set 124 | { 125 | if (value == null) throw new ArgumentNullException(nameof(Debug)); 126 | _Debug = value; 127 | } 128 | } 129 | 130 | #endregion 131 | 132 | #region Private-Members 133 | 134 | private LoggingSettings _Logging = new LoggingSettings(); 135 | private CachingSettings _Caching = new CachingSettings(); 136 | private WebserverSettings _Rest = new WebserverSettings(); 137 | private LiteGraphSettings _LiteGraph = new LiteGraphSettings(); 138 | private EncryptionSettings _Encryption = new EncryptionSettings(); 139 | private StorageSettings _Storage = new StorageSettings(); 140 | private DebugSettings _Debug = new DebugSettings(); 141 | 142 | #endregion 143 | 144 | #region Constructors-and-Factories 145 | 146 | /// 147 | /// Instantiate. 148 | /// 149 | public Settings() 150 | { 151 | Rest.Hostname = "localhost"; 152 | Rest.Port = 8701; 153 | Rest.Ssl.Enable = false; 154 | } 155 | 156 | #endregion 157 | 158 | #region Public-Methods 159 | 160 | #endregion 161 | 162 | #region Private-Methods 163 | 164 | #endregion 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Classes/StorageSettings.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Server.Classes 2 | { 3 | using LiteGraph.Helpers; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | 8 | /// 9 | /// Storage settings. 10 | /// 11 | public class StorageSettings 12 | { 13 | #region Public-Members 14 | 15 | public string BackupsDirectory 16 | { 17 | get 18 | { 19 | return _BackupsDirectory; 20 | } 21 | set 22 | { 23 | if (String.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(BackupsDirectory)); 24 | _BackupsDirectory = FileHelpers.NormalizeDirectory(value); 25 | if (!Directory.Exists(_BackupsDirectory)) Directory.CreateDirectory(_BackupsDirectory); 26 | } 27 | } 28 | 29 | #endregion 30 | 31 | #region Private-Members 32 | 33 | private string _BackupsDirectory = "./backups/"; 34 | 35 | #endregion 36 | 37 | #region Constructors-and-Factories 38 | 39 | /// 40 | /// Instantiate. 41 | /// 42 | public StorageSettings() 43 | { 44 | 45 | } 46 | 47 | #endregion 48 | 49 | #region Public-Methods 50 | 51 | #endregion 52 | 53 | #region Private-Methods 54 | 55 | #endregion 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/CopyDbFromTest.bat: -------------------------------------------------------------------------------- 1 | copy ..\..\..\..\Test\bin\Debug\net8.0\litegraph.db -------------------------------------------------------------------------------- /src/LiteGraph.Server/Dockerbuild.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | IF "%1" == "" GOTO :Usage 3 | IF "%2" == "" GOTO :Usage 4 | ECHO. 5 | ECHO Building for linux/amd64 and linux/arm64/v8... 6 | docker buildx build -f Dockerfile --platform linux/amd64,linux/arm64/v8 --tag jchristn/litegraph:%1 --load . 7 | 8 | IF "%2" NEQ "1" GOTO :Done 9 | 10 | ECHO. 11 | ECHO Pushing image... 12 | docker push jchristn/litegraph:%1 13 | 14 | GOTO :Done 15 | 16 | :Usage 17 | ECHO. 18 | ECHO Provide two arguments; the first being the version and the second being 1 or 0 to indicate whether or not to push. 19 | ECHO Example: dockerbuild.bat v2.0.0 1 20 | 21 | :Done 22 | ECHO. 23 | ECHO Done 24 | @ECHO ON 25 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env 2 | RUN apt-get update && apt-get install -y iputils-ping traceroute net-tools curl wget dnsutils iproute2 vim file && rm -rf /var/lib/apt/lists/* 3 | WORKDIR /app 4 | 5 | # Copy everything from source directory into /App 6 | COPY . ./ 7 | EXPOSE 8701 8 | ENTRYPOINT ["dotnet", "LiteGraph.Server.dll"] 9 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Dockerrun.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | IF "%1" == "" GOTO :Usage 4 | 5 | if not exist litegraph.json ( 6 | echo Configuration file litegraph.json not found. 7 | exit /b 1 8 | ) 9 | 10 | REM Items that require persistence 11 | REM litegraph.json 12 | REM litegraph.db 13 | REM logs/ 14 | 15 | REM Argument order matters! 16 | 17 | docker run ^ 18 | -p 8701:8701 ^ 19 | -t ^ 20 | -i ^ 21 | -e "TERM=xterm-256color" ^ 22 | -v .\litegraph.json:/app/litegraph.json ^ 23 | -v .\litegraph.db:/app/litegraph.db ^ 24 | -v .\logs\:/app/logs/ ^ 25 | jchristn/litegraph:%1 26 | 27 | GOTO :Done 28 | 29 | :Usage 30 | ECHO Provide one argument indicating the tag. 31 | ECHO Example: dockerrun.bat v2.0.0 32 | :Done 33 | @echo on 34 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/Dockerrun.sh: -------------------------------------------------------------------------------- 1 | if [ -z "${IMG_TAG}" ]; then 2 | IMG_TAG='v2.0.0' 3 | fi 4 | 5 | echo Using image tag $IMG_TAG 6 | 7 | if [ ! -f "litegraph.json" ] 8 | then 9 | echo Configuration file litegraph.json not found. 10 | exit 11 | fi 12 | 13 | # Items that require persistence 14 | # litegraph.json 15 | # litegraph.db 16 | # logs/ 17 | 18 | # Argument order matters! 19 | 20 | docker run \ 21 | -p 8701:8701 \ 22 | -t \ 23 | -i \ 24 | -e "TERM=xterm-256color" \ 25 | -v ./litegraph.json:/app/litegraph.json \ 26 | -v ./litegraph.db:/app/litegraph.db \ 27 | -v ./logs/:/app/logs/ \ 28 | jchristn/litegraph:$IMG_TAG 29 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/LiteGraph.Server.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Always 23 | 24 | 25 | Always 26 | 27 | 28 | Always 29 | 30 | 31 | Always 32 | 33 | 34 | Always 35 | 36 | 37 | Always 38 | 39 | 40 | Always 41 | 42 | 43 | Always 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/src/LiteGraph.Server/assets/favicon.ico -------------------------------------------------------------------------------- /src/LiteGraph.Server/clean.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | del /q litegraph.json 3 | del /q litegraph.db 4 | del /q /s logs 5 | @echo on 6 | -------------------------------------------------------------------------------- /src/LiteGraph.Server/clean.sh: -------------------------------------------------------------------------------- 1 | rm -f litegraph.json 2 | rm -f litegraph.db 3 | rm -rf logs 4 | -------------------------------------------------------------------------------- /src/LiteGraph.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.10.34928.147 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiteGraph", "LiteGraph\LiteGraph.csproj", "{530AA793-5D92-401D-BF77-4C5199E7C1A8}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj", "{F30D39C7-B0F1-4FB4-831F-52D49616EACC}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiteGraph.Server", "LiteGraph.Server\LiteGraph.Server.csproj", "{5DAF0F2C-6C68-4DF5-A901-62BFD44FC55A}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.RamDatabase", "Test.RamDatabase\Test.RamDatabase.csproj", "{5449BE30-6E41-473F-9BFE-262B916FB787}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {530AA793-5D92-401D-BF77-4C5199E7C1A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {530AA793-5D92-401D-BF77-4C5199E7C1A8}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {530AA793-5D92-401D-BF77-4C5199E7C1A8}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {530AA793-5D92-401D-BF77-4C5199E7C1A8}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {F30D39C7-B0F1-4FB4-831F-52D49616EACC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {F30D39C7-B0F1-4FB4-831F-52D49616EACC}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {F30D39C7-B0F1-4FB4-831F-52D49616EACC}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {F30D39C7-B0F1-4FB4-831F-52D49616EACC}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {5DAF0F2C-6C68-4DF5-A901-62BFD44FC55A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {5DAF0F2C-6C68-4DF5-A901-62BFD44FC55A}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {5DAF0F2C-6C68-4DF5-A901-62BFD44FC55A}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {5DAF0F2C-6C68-4DF5-A901-62BFD44FC55A}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {5449BE30-6E41-473F-9BFE-262B916FB787}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {5449BE30-6E41-473F-9BFE-262B916FB787}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {5449BE30-6E41-473F-9BFE-262B916FB787}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {5449BE30-6E41-473F-9BFE-262B916FB787}.Release|Any CPU.Build.0 = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {67C5ECF8-D65A-4D16-BAC6-EAE63450A728} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /src/LiteGraph/BackupFile.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Security.Cryptography; 6 | using System.Text.Json.Serialization; 7 | using PrettyId; 8 | 9 | /// 10 | /// Backup file. 11 | /// 12 | public class BackupFile 13 | { 14 | #region Public-Members 15 | 16 | /// 17 | /// Filename. 18 | /// 19 | public string Filename { get; set; } = null; 20 | 21 | /// 22 | /// File length. 23 | /// 24 | public long Length 25 | { 26 | get 27 | { 28 | return _Length; 29 | } 30 | set 31 | { 32 | if (value < 0) throw new ArgumentOutOfRangeException(nameof(Length)); 33 | _Length = value; 34 | } 35 | } 36 | 37 | /// 38 | /// MD5 hash. 39 | /// 40 | public string MD5Hash { get; set; } = null; 41 | 42 | /// 43 | /// SHA1 hash. 44 | /// 45 | public string SHA1Hash { get; set; } = null; 46 | 47 | /// 48 | /// SHA256 hash. 49 | /// 50 | public string SHA256Hash { get; set; } = null; 51 | 52 | /// 53 | /// Creation timestamp, in UTC. 54 | /// 55 | public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; 56 | 57 | /// 58 | /// Timestamp from last update, in UTC. 59 | /// 60 | public DateTime LastUpdateUtc { get; set; } = DateTime.UtcNow; 61 | 62 | /// 63 | /// Timestamp from last access, in UTC. 64 | /// 65 | public DateTime LastAccessUtc { get; set; } = DateTime.UtcNow; 66 | 67 | /// 68 | /// File contents. 69 | /// 70 | public byte[] Data { get; set; } = null; 71 | 72 | #endregion 73 | 74 | #region Private-Members 75 | 76 | private long _Length = 0; 77 | 78 | #endregion 79 | 80 | #region Constructors-and-Factories 81 | 82 | /// 83 | /// Instantiate. 84 | /// 85 | public BackupFile() 86 | { 87 | 88 | } 89 | 90 | #endregion 91 | 92 | #region Public-Methods 93 | 94 | #endregion 95 | 96 | #region Private-Methods 97 | 98 | #endregion 99 | } 100 | } -------------------------------------------------------------------------------- /src/LiteGraph/CachingSettings.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Caching; 9 | 10 | /// 11 | /// Caching settings. 12 | /// 13 | public class CachingSettings 14 | { 15 | #region Public-Members 16 | 17 | /// 18 | /// Enable or disable caching. 19 | /// 20 | public bool Enable { get; set; } = true; 21 | 22 | /// 23 | /// Maximum number of records to cache, per resource type. 24 | /// 25 | public int Capacity 26 | { 27 | get 28 | { 29 | return _Capacity; 30 | } 31 | set 32 | { 33 | if (value < 1) throw new ArgumentOutOfRangeException(nameof(Capacity)); 34 | _Capacity = value; 35 | } 36 | } 37 | 38 | /// 39 | /// Number of records to evict when capacity pressure is encountered. 40 | /// It is recommended that this value be approximately 10% to 25% of the capacity. 41 | /// 42 | public int EvictCount 43 | { 44 | get 45 | { 46 | return _EvictCount; 47 | } 48 | set 49 | { 50 | if (value < 1) throw new ArgumentOutOfRangeException(nameof(EvictCount)); 51 | _EvictCount = value; 52 | } 53 | } 54 | 55 | #endregion 56 | 57 | #region Private-Members 58 | 59 | private int _Capacity = 1000; 60 | private int _EvictCount = 100; 61 | 62 | #endregion 63 | 64 | #region Constructors-and-Factories 65 | 66 | /// 67 | /// Caching settings. 68 | /// 69 | public CachingSettings() 70 | { 71 | 72 | } 73 | 74 | #endregion 75 | 76 | #region Public-Methods 77 | 78 | #endregion 79 | 80 | #region Private-Methods 81 | 82 | #endregion 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/LiteGraph/Client/Implementations/BatchMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Client.Implementations 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Runtime.Serialization.Json; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using LiteGraph.Client.Interfaces; 11 | using LiteGraph.GraphRepositories; 12 | using LiteGraph.GraphRepositories.Sqlite; 13 | using LiteGraph.GraphRepositories.Sqlite.Queries; 14 | using LiteGraph.Serialization; 15 | 16 | using LoggingSettings = LoggingSettings; 17 | 18 | /// 19 | /// Batch methods. 20 | /// Client implementations are responsible for input validation and cross-cutting logic. 21 | /// 22 | public class BatchMethods : IBatchMethods 23 | { 24 | #region Public-Members 25 | 26 | #endregion 27 | 28 | #region Private-Members 29 | 30 | private LiteGraphClient _Client = null; 31 | private GraphRepositoryBase _Repo = null; 32 | 33 | #endregion 34 | 35 | #region Constructors-and-Factories 36 | 37 | /// 38 | /// Batch methods. 39 | /// 40 | /// LiteGraph client. 41 | /// Graph repository. 42 | public BatchMethods(LiteGraphClient client, GraphRepositoryBase repo) 43 | { 44 | _Client = client ?? throw new ArgumentNullException(nameof(client)); 45 | _Repo = repo ?? throw new ArgumentNullException(nameof(repo)); 46 | } 47 | 48 | #endregion 49 | 50 | #region Public-Methods 51 | 52 | /// 53 | public ExistenceResult Existence(Guid tenantGuid, Guid graphGuid, ExistenceRequest req) 54 | { 55 | if (req == null) throw new ArgumentNullException(nameof(req)); 56 | if (!req.ContainsExistenceRequest()) throw new ArgumentException("Supplied existence request contains no valid existence filters."); 57 | 58 | _Client.ValidateGraphExists(tenantGuid, graphGuid); 59 | 60 | return _Repo.Batch.Existence(tenantGuid, graphGuid, req); 61 | } 62 | 63 | #endregion 64 | 65 | #region Private-Methods 66 | 67 | #endregion 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/LiteGraph/Client/Interfaces/IAdminMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Client.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for admin methods. 16 | /// Client implementations are responsible for input validation and cross-cutting logic. 17 | /// 18 | public interface IAdminMethods 19 | { 20 | /// 21 | /// Backup request. 22 | /// 23 | /// Output filename. 24 | void Backup(string outputFilename); 25 | 26 | /// 27 | /// List backups request. 28 | /// 29 | /// Enumerable of backup files. 30 | IEnumerable ListBackups(); 31 | 32 | /// 33 | /// Read the contents of a backup file. 34 | /// 35 | /// Backup filename. 36 | /// File contents. 37 | BackupFile ReadBackup(string backupFilename); 38 | 39 | /// 40 | /// Check if a backup file exists. 41 | /// 42 | /// Backup filename. 43 | /// True if exists. 44 | bool BackupExists(string backupFilename); 45 | 46 | /// 47 | /// Delete a backup file. 48 | /// 49 | /// Backup filename. 50 | void DeleteBackup(string backupFilename); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/LiteGraph/Client/Interfaces/IBatchMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Client.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for batch methods. 16 | /// Client implementations are responsible for input validation and cross-cutting logic. 17 | /// 18 | public interface IBatchMethods 19 | { 20 | /// 21 | /// Batch existence request. 22 | /// 23 | /// Tenant GUID. 24 | /// Graph GUID. 25 | /// Existence request. 26 | /// Existence result. 27 | ExistenceResult Existence(Guid tenantGuid, Guid graphGuid, ExistenceRequest req); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/LiteGraph/Client/Interfaces/ICredentialMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Client.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for credential methods. 16 | /// Client implementations are responsible for input validation and cross-cutting logic. 17 | /// 18 | public interface ICredentialMethods 19 | { 20 | /// 21 | /// Create a credential. 22 | /// 23 | /// Credential. 24 | /// Credential. 25 | Credential Create(Credential credential); 26 | 27 | /// 28 | /// Read all credentials in a given tenant. 29 | /// 30 | /// Tenant GUID. 31 | /// Enumeration order. 32 | /// The number of records to skip. 33 | /// Credentials. 34 | IEnumerable ReadAllInTenant( 35 | Guid tenantGuid, 36 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 37 | int skip = 0); 38 | 39 | /// 40 | /// Read credentials. 41 | /// 42 | /// Tenant GUID. 43 | /// User GUID. 44 | /// Bearer token. 45 | /// Enumeration order. 46 | /// Number of records to skip. 47 | /// Credentials. 48 | IEnumerable ReadMany( 49 | Guid? tenantGuid, 50 | Guid? userGuid, 51 | string bearerToken, 52 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 53 | int skip = 0); 54 | 55 | /// 56 | /// Read a credential by GUID. 57 | /// 58 | /// Tenant GUID. 59 | /// GUID. 60 | /// Credential. 61 | Credential ReadByGuid(Guid tenantGuid, Guid guid); 62 | 63 | /// 64 | /// Read a credential by bearer token. 65 | /// 66 | /// Bearer token. 67 | /// Credential. 68 | Credential ReadByBearerToken(string bearerToken); 69 | 70 | /// 71 | /// Update a credential. 72 | /// 73 | /// Credential. 74 | /// Credential. 75 | Credential Update(Credential cred); 76 | 77 | /// 78 | /// Delete credentials associated with a tenant. 79 | /// 80 | /// Tenant GUID. 81 | void DeleteAllInTenant(Guid tenantGuid); 82 | 83 | /// 84 | /// Delete a credential. 85 | /// 86 | /// Tenant GUID. 87 | /// GUID. 88 | void DeleteByGuid(Guid tenantGuid, Guid guid); 89 | 90 | /// 91 | /// Delete credentials associated with a user. 92 | /// 93 | /// Tenant GUID. 94 | /// User GUID. 95 | void DeleteByUser(Guid tenantGuid, Guid userGuid); 96 | 97 | /// 98 | /// Check if a credential exists by GUID. 99 | /// 100 | /// Tenant GUID. 101 | /// GUID. 102 | /// True if exists. 103 | bool ExistsByGuid(Guid tenantGuid, Guid guid); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/LiteGraph/Client/Interfaces/IGraphMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Client.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for graph methods. 16 | /// Client implementations are responsible for input validation and cross-cutting logic. 17 | /// 18 | public interface IGraphMethods 19 | { 20 | /// 21 | /// Create a graph. 22 | /// 23 | /// Graph. 24 | /// Graph. 25 | Graph Create(Graph graph); 26 | 27 | /// 28 | /// Read all graphs in a given tenant. 29 | /// 30 | /// Tenant GUID. 31 | /// Enumeration order. 32 | /// The number of records to skip. 33 | /// Graphs. 34 | IEnumerable ReadAllInTenant( 35 | Guid tenantGuid, 36 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 37 | int skip = 0); 38 | 39 | /// 40 | /// Read graphs. 41 | /// 42 | /// Tenant GUID. 43 | /// Labels. 44 | /// Tags on which to match. 45 | /// 46 | /// Graph filter expression for Data JSON body. 47 | /// Expression left terms must follow the form of Sqlite JSON paths. 48 | /// For example, to retrieve the 'Name' property, use '$.Name', OperatorEnum.Equals, '[name here]'. 49 | /// Enumeration order. 50 | /// The number of records to skip. 51 | /// Graphs. 52 | IEnumerable ReadMany( 53 | Guid tenantGuid, 54 | List labels = null, 55 | NameValueCollection tags = null, 56 | Expr graphFilter = null, 57 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 58 | int skip = 0); 59 | 60 | /// 61 | /// Read first. 62 | /// 63 | /// Tenant GUID. 64 | /// Labels. 65 | /// Tags on which to match. 66 | /// 67 | /// Graph filter expression for Data JSON body. 68 | /// Expression left terms must follow the form of Sqlite JSON paths. 69 | /// For example, to retrieve the 'Name' property, use '$.Name', OperatorEnum.Equals, '[name here]'. 70 | /// Enumeration order. 71 | /// Graph. 72 | Graph ReadFirst( 73 | Guid tenantGuid, 74 | List labels = null, 75 | NameValueCollection tags = null, 76 | Expr graphFilter = null, 77 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending); 78 | 79 | /// 80 | /// Read a graph by GUID. 81 | /// 82 | /// Tenant GUID. 83 | /// GUID. 84 | /// Graph. 85 | Graph ReadByGuid(Guid tenantGuid, Guid guid); 86 | 87 | /// 88 | /// Update a graph. 89 | /// 90 | /// Graph. 91 | /// Graph. 92 | Graph Update(Graph graph); 93 | 94 | /// 95 | /// Delete a graph. 96 | /// 97 | /// Tenant GUID. 98 | /// GUID. 99 | /// True to force deletion of nodes and edges. 100 | void DeleteByGuid(Guid tenantGuid, Guid guid, bool force = false); 101 | 102 | /// 103 | /// Delete graphs associated with a tenant. Deletion is forceful. 104 | /// 105 | /// Tenant GUID. 106 | void DeleteAllInTenant(Guid tenantGuid); 107 | 108 | /// 109 | /// Check if a graph exists by GUID. 110 | /// 111 | /// Tenant GUID. 112 | /// GUID. 113 | /// True if exists. 114 | bool ExistsByGuid(Guid tenantGuid, Guid guid); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/LiteGraph/Client/Interfaces/ITenantMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Client.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for tenant methods. 16 | /// Client implementations are responsible for input validation and cross-cutting logic. 17 | /// 18 | public interface ITenantMethods 19 | { 20 | /// 21 | /// Create a tenant. 22 | /// 23 | /// Tenant. 24 | /// Tenant. 25 | TenantMetadata Create(TenantMetadata tenant); 26 | 27 | /// 28 | /// Read tenants. 29 | /// 30 | /// Enumeration order. 31 | /// The number of records to skip. 32 | /// Tenants. 33 | IEnumerable ReadMany( 34 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 35 | int skip = 0); 36 | 37 | /// 38 | /// Read a tenant by GUID. 39 | /// 40 | /// GUID. 41 | /// Tenant. 42 | TenantMetadata ReadByGuid(Guid guid); 43 | 44 | /// 45 | /// Update a tenant. 46 | /// 47 | /// Tenant. 48 | /// Tenant. 49 | TenantMetadata Update(TenantMetadata tenant); 50 | 51 | /// 52 | /// Delete a tenant. 53 | /// 54 | /// GUID. 55 | /// True to force deletion of users and credentials. 56 | void DeleteByGuid(Guid guid, bool force = false); 57 | 58 | /// 59 | /// Check if a tenant exists by GUID. 60 | /// 61 | /// GUID. 62 | /// True if exists. 63 | bool ExistsByGuid(Guid guid); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/LiteGraph/Client/Interfaces/IUserMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Client.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for user methods. 16 | /// Client implementations are responsible for input validation and cross-cutting logic. 17 | /// 18 | public interface IUserMethods 19 | { 20 | /// 21 | /// Create a user. 22 | /// 23 | /// User. 24 | /// User. 25 | UserMaster Create(UserMaster user); 26 | 27 | /// 28 | /// Read all users in a given tenant. 29 | /// 30 | /// Tenant GUID. 31 | /// Enumeration order. 32 | /// The number of records to skip. 33 | /// Users. 34 | IEnumerable ReadAllInTenant( 35 | Guid tenantGuid, 36 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 37 | int skip = 0); 38 | 39 | /// 40 | /// Read users. 41 | /// 42 | /// Tenant GUID. 43 | /// Email. 44 | /// Enumeration order. 45 | /// Number of records to skip. 46 | /// Users. 47 | IEnumerable ReadMany( 48 | Guid? tenantGuid, 49 | string email, 50 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 51 | int skip = 0); 52 | 53 | /// 54 | /// Read a user by GUID. 55 | /// 56 | /// Tenant GUID. 57 | /// GUID. 58 | /// User. 59 | UserMaster ReadByGuid(Guid tenantGuid, Guid guid); 60 | 61 | /// 62 | /// Read tenants associated with a given email address. 63 | /// 64 | /// Email address. 65 | /// List of tenants. 66 | List ReadTenantsByEmail(string email); 67 | 68 | /// 69 | /// Read a user by email. 70 | /// 71 | /// Tenant GUID. 72 | /// Email. 73 | /// User. 74 | UserMaster ReadByEmail(Guid tenantGuid, string email); 75 | 76 | /// 77 | /// Update a user. 78 | /// 79 | /// User. 80 | /// User. 81 | UserMaster Update(UserMaster user); 82 | 83 | /// 84 | /// Delete a user. 85 | /// 86 | /// Tenant GUID. 87 | /// GUID. 88 | void DeleteByGuid(Guid tenantGuid, Guid guid); 89 | 90 | /// 91 | /// Delete users associated with a tenant. 92 | /// 93 | /// Tenant GUID. 94 | void DeleteAllInTenant(Guid tenantGuid); 95 | 96 | /// 97 | /// Check if a user exists by GUID. 98 | /// 99 | /// Tenant GUID. 100 | /// GUID. 101 | /// True if exists. 102 | bool ExistsByGuid(Guid tenantGuid, Guid guid); 103 | 104 | /// 105 | /// Check if a user exists by email. 106 | /// 107 | /// Tenant GUID. 108 | /// Email. 109 | /// True if exists. 110 | bool ExistsByEmail(Guid tenantGuid, string email); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/LiteGraph/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | 5 | /// 6 | /// Constants. 7 | /// 8 | internal static class Constants 9 | { 10 | /// 11 | /// Log file directory. 12 | /// 13 | public static string LogDirectory = "./logs/"; 14 | 15 | /// 16 | /// Log filename. 17 | /// 18 | public static string LogFilename = "litegraph.log"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/LiteGraph/Credential.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Security.Cryptography; 6 | using System.Text.Json.Serialization; 7 | using PrettyId; 8 | 9 | /// 10 | /// Credentials. 11 | /// 12 | public class Credential 13 | { 14 | #region Public-Members 15 | 16 | /// 17 | /// GUID. 18 | /// 19 | public Guid GUID { get; set; } = Guid.NewGuid(); 20 | 21 | /// 22 | /// Tenant GUID. 23 | /// 24 | public Guid TenantGUID { get; set; } = Guid.NewGuid(); 25 | 26 | /// 27 | /// User GUID. 28 | /// 29 | public Guid UserGUID { get; set; } = Guid.NewGuid(); 30 | 31 | /// 32 | /// Name. 33 | /// 34 | public string Name { get; set; } = null; 35 | 36 | /// 37 | /// Access key. 38 | /// 39 | public string BearerToken { get; set; } = IdGenerator.Generate(64); 40 | 41 | /// 42 | /// Active. 43 | /// 44 | public bool Active { get; set; } = true; 45 | 46 | /// 47 | /// Creation timestamp, in UTC. 48 | /// 49 | public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; 50 | 51 | /// 52 | /// Timestamp from last update, in UTC. 53 | /// 54 | public DateTime LastUpdateUtc { get; set; } = DateTime.UtcNow; 55 | 56 | #endregion 57 | 58 | #region Private-Members 59 | 60 | #endregion 61 | 62 | #region Constructors-and-Factories 63 | 64 | /// 65 | /// Instantiate. 66 | /// 67 | public Credential() 68 | { 69 | 70 | } 71 | 72 | #endregion 73 | 74 | #region Public-Methods 75 | 76 | #endregion 77 | 78 | #region Private-Methods 79 | 80 | #endregion 81 | } 82 | } -------------------------------------------------------------------------------- /src/LiteGraph/Edge.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.Specialized; 6 | 7 | /// 8 | /// Edge in the graph. 9 | /// 10 | public class Edge 11 | { 12 | #region Public-Members 13 | 14 | /// 15 | /// Tenant GUID. 16 | /// 17 | public Guid TenantGUID { get; set; } = Guid.NewGuid(); 18 | 19 | /// 20 | /// Globally-unique identifier. 21 | /// 22 | public Guid GUID { get; set; } = Guid.NewGuid(); 23 | 24 | /// 25 | /// Globally-unique identifier for the graph. 26 | /// 27 | public Guid GraphGUID { get; set; } = Guid.NewGuid(); 28 | 29 | /// 30 | /// Name. 31 | /// 32 | public string Name { get; set; } = null; 33 | 34 | /// 35 | /// Globally-unique identifier of the from node. 36 | /// 37 | public Guid From { get; set; } = default(Guid); 38 | 39 | /// 40 | /// From node. This property is only populated when retrieving routes. 41 | /// 42 | public Node FromNode { get; set; } = null; 43 | 44 | /// 45 | /// Globally-unique identifier of the to node. 46 | /// 47 | public Guid To { get; set; } = default(Guid); 48 | 49 | /// 50 | /// To node. This property is only populated when retrieving routes. 51 | /// 52 | public Node ToNode { get; set; } = null; 53 | 54 | /// 55 | /// Cost. 56 | /// 57 | public int Cost 58 | { 59 | get 60 | { 61 | return _Cost; 62 | } 63 | set 64 | { 65 | if (value < 0) throw new ArgumentOutOfRangeException(nameof(Cost)); 66 | _Cost = value; 67 | } 68 | } 69 | 70 | /// 71 | /// Timestamp from creation, in UTC. 72 | /// 73 | public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; 74 | 75 | /// 76 | /// Timestamp from last update, in UTC. 77 | /// 78 | public DateTime LastUpdateUtc { get; set; } = DateTime.UtcNow; 79 | 80 | /// 81 | /// Labels. 82 | /// 83 | public List Labels { get; set; } = null; 84 | 85 | /// 86 | /// Tags. 87 | /// 88 | public NameValueCollection Tags { get; set; } = null; 89 | 90 | /// 91 | /// Object data. 92 | /// 93 | public object Data { get; set; } = null; 94 | 95 | /// 96 | /// Vectors. 97 | /// 98 | public List Vectors { get; set; } = null; 99 | 100 | #endregion 101 | 102 | #region Private-Members 103 | 104 | private int _Cost = 0; 105 | 106 | #endregion 107 | 108 | #region Constructors-and-Factories 109 | 110 | /// 111 | /// Instantiate. 112 | /// 113 | public Edge() 114 | { 115 | 116 | } 117 | 118 | #endregion 119 | 120 | #region Public-Methods 121 | 122 | #endregion 123 | 124 | #region Private-Methods 125 | 126 | #endregion 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/LiteGraph/EdgeBetween.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using ExpressionTree; 6 | 7 | /// 8 | /// Existence check for multiple identifiers request. 9 | /// 10 | public class EdgeBetween 11 | { 12 | #region Public-Members 13 | 14 | /// 15 | /// From GUID. 16 | /// 17 | public Guid From { get; set; } 18 | 19 | /// 20 | /// To GUID. 21 | /// 22 | public Guid To { get; set; } 23 | 24 | #endregion 25 | 26 | #region Private-Members 27 | 28 | #endregion 29 | 30 | #region Constructors-and-Factories 31 | 32 | /// 33 | /// Instantiate. 34 | /// 35 | public EdgeBetween() 36 | { 37 | 38 | } 39 | 40 | #endregion 41 | 42 | #region Public-Methods 43 | 44 | #endregion 45 | 46 | #region Private-Methods 47 | 48 | #endregion 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/LiteGraph/EnumerationOrderEnum.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | /// 4 | /// Enumeration order. 5 | /// 6 | public enum EnumerationOrderEnum 7 | { 8 | /// 9 | /// Created ascending. 10 | /// 11 | CreatedAscending, 12 | /// 13 | /// Created descending. 14 | /// 15 | CreatedDescending, 16 | /// 17 | /// Name ascending. 18 | /// 19 | NameAscending, 20 | /// 21 | /// Name descending. 22 | /// 23 | NameDescending, 24 | /// 25 | /// GUID ascending. 26 | /// 27 | GuidAscending, 28 | /// 29 | /// GUID descending. 30 | /// 31 | GuidDescending, 32 | /// 33 | /// Cost ascending. 34 | /// 35 | CostAscending, 36 | /// 37 | /// Cost descending. 38 | /// 39 | CostDescending, 40 | /// 41 | /// Most connected. 42 | /// 43 | MostConnected, 44 | /// 45 | /// Least connected. 46 | /// 47 | LeastConnected 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/LiteGraph/ExistenceRequest.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using ExpressionTree; 6 | 7 | /// 8 | /// Existence check for multiple identifiers request. 9 | /// 10 | public class ExistenceRequest 11 | { 12 | #region Public-Members 13 | 14 | /// 15 | /// List of node GUIDs. 16 | /// 17 | public List Nodes { get; set; } = null; 18 | 19 | /// 20 | /// List of edge GUIDs. 21 | /// 22 | public List Edges { get; set; } = null; 23 | 24 | /// 25 | /// List of edges between two nodes. 26 | /// 27 | public List EdgesBetween { get; set; } = null; 28 | 29 | #endregion 30 | 31 | #region Private-Members 32 | 33 | #endregion 34 | 35 | #region Constructors-and-Factories 36 | 37 | /// 38 | /// Route request. 39 | /// 40 | public ExistenceRequest() 41 | { 42 | 43 | } 44 | 45 | #endregion 46 | 47 | #region Public-Methods 48 | 49 | /// 50 | /// Verify that the object contains at least one existence request. 51 | /// 52 | /// True if present. 53 | public bool ContainsExistenceRequest() 54 | { 55 | if (Nodes != null && Nodes.Count > 0) return true; 56 | if (Edges != null && Edges.Count > 0) return true; 57 | if (EdgesBetween != null && EdgesBetween.Count > 0) return true; 58 | return false; 59 | } 60 | 61 | #endregion 62 | 63 | #region Private-Methods 64 | 65 | #endregion 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/LiteGraph/ExistenceResult.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using ExpressionTree; 6 | 7 | /// 8 | /// Existence check for multiple identifiers result. 9 | /// 10 | public class ExistenceResult 11 | { 12 | #region Public-Members 13 | 14 | /// 15 | /// List of existing node GUIDs. 16 | /// 17 | public List ExistingNodes { get; set; } = null; 18 | 19 | /// 20 | /// List of missing node GUIDs. 21 | /// 22 | public List MissingNodes { get; set; } = null; 23 | 24 | /// 25 | /// List of existing edge GUIDs. 26 | /// 27 | public List ExistingEdges { get; set; } = null; 28 | 29 | /// 30 | /// List of missing edge GUIDs. 31 | /// 32 | public List MissingEdges { get; set; } = null; 33 | 34 | /// 35 | /// List of existing edges between two nodes. 36 | /// 37 | public List ExistingEdgesBetween { get; set; } = null; 38 | 39 | /// 40 | /// List of missing edges between two nodes. 41 | /// 42 | public List MissingEdgesBetween { get; set; } = null; 43 | 44 | #endregion 45 | 46 | #region Private-Members 47 | 48 | #endregion 49 | 50 | #region Constructors-and-Factories 51 | 52 | /// 53 | /// Route request. 54 | /// 55 | public ExistenceResult() 56 | { 57 | 58 | } 59 | 60 | #endregion 61 | 62 | #region Public-Methods 63 | 64 | #endregion 65 | 66 | #region Private-Methods 67 | 68 | #endregion 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Attribute. 9 | /// 10 | [XmlRoot(ElementName = "attribute", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfAttribute 12 | { 13 | /// 14 | /// Attribute ID. 15 | /// 16 | [XmlAttribute(AttributeName = "id")] 17 | public string Id { get; set; } = null; 18 | 19 | /// 20 | /// Attribute title. 21 | /// 22 | [XmlAttribute(AttributeName = "title")] 23 | public string Title { get; set; } = null; 24 | 25 | /// 26 | /// Attribute type. 27 | /// 28 | [XmlAttribute(AttributeName = "type")] 29 | public string Type 30 | { 31 | get 32 | { 33 | return _Type; 34 | } 35 | set 36 | { 37 | if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Type)); 38 | List validValues = new List { "string", "integer", "float", "double", "boolean", "date" }; 39 | if (!validValues.Contains(value)) throw new ArgumentException("Invalid value for Type: " + value); 40 | _Type = value; 41 | } 42 | } 43 | 44 | private string _Type = "string"; 45 | 46 | /// 47 | /// Attribute default value. 48 | /// 49 | [XmlElement(ElementName = "default", Namespace = "http://www.gexf.net/1.3")] 50 | public string Default { get; set; } = null; 51 | 52 | /// 53 | /// Instantiate the object. 54 | /// 55 | /// Attribute ID. 56 | /// Attribute title. 57 | /// Attribute type. 58 | public GexfAttribute(string id, string title, string type = "string") 59 | { 60 | Id = id ?? throw new ArgumentNullException(nameof(id)); 61 | Title = title ?? throw new ArgumentNullException(nameof(title)); 62 | Type = type ?? throw new ArgumentNullException(nameof(type)); 63 | } 64 | 65 | /// 66 | /// Instantiate the object. 67 | /// 68 | public GexfAttribute() 69 | { 70 | 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfAttributeValue.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Attribute value. 9 | /// 10 | [XmlRoot(ElementName = "attvalue", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfAttributeValue 12 | { 13 | /// 14 | /// ID of the object to which the attribute is assigned. 15 | /// 16 | [XmlAttribute(AttributeName = "for")] 17 | public string For { get; set; } 18 | 19 | /// 20 | /// Value of the attribute. 21 | /// 22 | [XmlAttribute(AttributeName = "value")] 23 | public string Value { get; set; } 24 | 25 | /// 26 | /// Instantiate the object. 27 | /// 28 | /// ID of the object to which the attribute is assigned. 29 | /// Value of the attribute. 30 | public GexfAttributeValue(string forGuid, string value) 31 | { 32 | For = forGuid ?? throw new ArgumentNullException(nameof(forGuid)); 33 | if (value == null) value = ""; 34 | Value = value; 35 | } 36 | 37 | /// 38 | /// Instantiate the object. 39 | /// 40 | public GexfAttributeValue() 41 | { 42 | 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfAttributeValues.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Attribute values. 9 | /// 10 | [XmlRoot(ElementName = "attvalues", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfAttributeValues 12 | { 13 | /// 14 | /// Attribute values. 15 | /// 16 | [XmlElement(ElementName = "attvalue", Namespace = "http://www.gexf.net/1.3")] 17 | public List Values { get; set; } = new List(); 18 | 19 | /// 20 | /// Instantiate the object. 21 | /// 22 | public GexfAttributeValues() 23 | { 24 | 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfAttributes.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Attributes. 9 | /// 10 | [XmlRoot(ElementName = "attributes", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfAttributes 12 | { 13 | /// 14 | /// Attributes. 15 | /// 16 | [XmlElement(ElementName = "attribute", Namespace = "http://www.gexf.net/1.3")] 17 | public List AttributeList { get; set; } = new List(); 18 | 19 | /// 20 | /// Attribute class, i.e. 'node' or 'edge'. 21 | /// 22 | [XmlAttribute(AttributeName = "class")] 23 | public string Class 24 | { 25 | get 26 | { 27 | return _Class; 28 | } 29 | set 30 | { 31 | if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Class)); 32 | List validValues = new List { "node", "edge" }; 33 | if (!validValues.Contains(value)) throw new ArgumentException("Invalid value for Class: " + value); 34 | _Class = value; 35 | } 36 | } 37 | 38 | private string _Class = "node"; 39 | 40 | /// 41 | /// Instantiate the object. 42 | /// 43 | public GexfAttributes() 44 | { 45 | 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfDocument.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Graph Exchange XML Format document. 9 | /// 10 | [XmlRoot(ElementName = "gexf", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfDocument 12 | { 13 | /// 14 | /// Document metadata. 15 | /// 16 | [XmlElement(ElementName = "meta", Namespace = "http://www.gexf.net/1.3")] 17 | public GexfMetadata Meta { get; set; } = new GexfMetadata(); 18 | 19 | /// 20 | /// Graph. 21 | /// 22 | [XmlElement(ElementName = "graph", Namespace = "http://www.gexf.net/1.3")] 23 | public GexfGraph Graph { get; set; } = new GexfGraph(); 24 | 25 | /// 26 | /// XML namespace. 27 | /// 28 | [XmlAttribute(AttributeName = "xmlns")] 29 | public string Xmlns { get; set; } = "http://www.gexf.net/1.3"; 30 | 31 | /// 32 | /// Schema location. 33 | /// 34 | [XmlAttribute(AttributeName = "schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")] 35 | public string SchemaLocation { get; set; } = "http://www.gexf.net/1.3 http://www.gexf.net/1.3/gexf.xsd"; 36 | 37 | /// 38 | /// Version. 39 | /// 40 | [XmlAttribute(AttributeName = "version")] 41 | public string Version { get; set; } = "1.3"; 42 | 43 | /// 44 | /// Instantiate the object. 45 | /// 46 | public GexfDocument() 47 | { 48 | 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfEdge.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Edge. 9 | /// 10 | [XmlRoot(ElementName = "edge", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfEdge 12 | { 13 | /// 14 | /// Attribute values. 15 | /// 16 | [XmlElement(ElementName = "attvalues", Namespace = "http://www.gexf.net/1.3")] 17 | public GexfAttributeValues ValueList { get; set; } = new GexfAttributeValues(); 18 | 19 | /// 20 | /// ID. 21 | /// 22 | [XmlAttribute(AttributeName = "id")] 23 | public string Id { get; set; } 24 | 25 | /// 26 | /// Source. 27 | /// 28 | [XmlAttribute(AttributeName = "source")] 29 | public string Source { get; set; } 30 | 31 | /// 32 | /// Target. 33 | /// 34 | [XmlAttribute(AttributeName = "target")] 35 | public string Target { get; set; } 36 | 37 | /// 38 | /// Instantiate the object. 39 | /// 40 | /// ID. 41 | /// Source. 42 | /// Target. 43 | public GexfEdge(Guid id, Guid source, Guid target) 44 | { 45 | Id = id.ToString(); 46 | Source = source.ToString(); 47 | Target = target.ToString(); 48 | } 49 | 50 | /// 51 | /// Instantiate the object. 52 | /// 53 | public GexfEdge() 54 | { 55 | 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfEdges.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Edges. 9 | /// 10 | [XmlRoot(ElementName = "edges", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfEdges 12 | { 13 | /// 14 | /// List of edges. 15 | /// 16 | [XmlElement(ElementName = "edge", Namespace = "http://www.gexf.net/1.3")] 17 | public List Edges { get; set; } = new List(); 18 | 19 | /// 20 | /// Instantiate the object. 21 | /// 22 | public GexfEdges() 23 | { 24 | 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfGraph.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Graph. 9 | /// 10 | [XmlRoot(ElementName = "graph", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfGraph 12 | { 13 | /// 14 | /// Attributes. 15 | /// 16 | [XmlElement(ElementName = "attributes", Namespace = "http://www.gexf.net/1.3")] 17 | public GexfAttributes Attributes { get; set; } = new GexfAttributes(); 18 | 19 | /// 20 | /// Nodes. 21 | /// 22 | [XmlElement(ElementName = "nodes", Namespace = "http://www.gexf.net/1.3")] 23 | public GexfNodes NodeList { get; set; } = new GexfNodes(); 24 | 25 | /// 26 | /// Edges. 27 | /// 28 | [XmlElement(ElementName = "edges", Namespace = "http://www.gexf.net/1.3")] 29 | public GexfEdges EdgeList { get; set; } = new GexfEdges(); 30 | 31 | /// 32 | /// Default edge type, i.e. 'directed'. 33 | /// 34 | [XmlAttribute(AttributeName = "defaultedgetype")] 35 | public string DefaultEdgeType 36 | { 37 | get 38 | { 39 | return _DefaultEdgeType; 40 | } 41 | set 42 | { 43 | if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(DefaultEdgeType)); 44 | List validValues = new List { "directed", "undirected", "mutual" }; 45 | if (!validValues.Contains(value)) throw new ArgumentException("Invalid value for DefaultEdgeType: " + value); 46 | _DefaultEdgeType = value; 47 | } 48 | } 49 | 50 | private string _DefaultEdgeType = "directed"; 51 | 52 | /// 53 | /// Instantiate the object. 54 | /// 55 | public GexfGraph() 56 | { 57 | 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfMetadata.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Document metadata. 9 | /// 10 | [XmlRoot(ElementName = "meta", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfMetadata 12 | { 13 | /// 14 | /// Document creator. 15 | /// 16 | [XmlElement(ElementName = "creator", Namespace = "http://www.gexf.net/1.3")] 17 | public string Creator { get; set; } = "LiteGraph"; 18 | 19 | /// 20 | /// Document description. 21 | /// 22 | [XmlElement(ElementName = "description", Namespace = "http://www.gexf.net/1.3")] 23 | public string Description { get; set; } = "Graph from LiteGraph https://github.com/jchristn/litegraph"; 24 | 25 | /// 26 | /// Last modified date. 27 | /// 28 | [XmlAttribute(AttributeName = "lastmodifieddate")] 29 | public DateTime LastModifiedDate { get; set; } = DateTime.UtcNow; 30 | 31 | /// 32 | /// Instantiate the object. 33 | /// 34 | public GexfMetadata() 35 | { 36 | 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfNode.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Node. 9 | /// 10 | [XmlRoot(ElementName = "node", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfNode 12 | { 13 | /// 14 | /// Attribute values. 15 | /// 16 | [XmlElement(ElementName = "attvalues", Namespace = "http://www.gexf.net/1.3")] 17 | public GexfAttributeValues ValueList { get; set; } = new GexfAttributeValues(); 18 | 19 | /// 20 | /// ID. 21 | /// 22 | [XmlAttribute(AttributeName = "id")] 23 | public string Id { get; set; } 24 | 25 | /// 26 | /// Label. 27 | /// 28 | [XmlAttribute(AttributeName = "label")] 29 | public string Label { get; set; } 30 | 31 | /// 32 | /// Instantiate the object. 33 | /// 34 | /// ID. 35 | /// Label. 36 | public GexfNode(Guid id, string label) 37 | { 38 | Id = id.ToString(); 39 | Label = label ?? throw new ArgumentNullException(nameof(label)); 40 | } 41 | 42 | /// 43 | /// Instantiate the object. 44 | /// 45 | public GexfNode() 46 | { 47 | 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/LiteGraph/Gexf/GexfNodes.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Gexf 2 | { 3 | using System; 4 | using System.Xml.Serialization; 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// Nodes. 9 | /// 10 | [XmlRoot(ElementName = "nodes", Namespace = "http://www.gexf.net/1.3")] 11 | public class GexfNodes 12 | { 13 | /// 14 | /// List of nodes. 15 | /// 16 | [XmlElement(ElementName = "node", Namespace = "http://www.gexf.net/1.3")] 17 | public List Nodes { get; set; } = new List(); 18 | 19 | /// 20 | /// Instantiate the object. 21 | /// 22 | public GexfNodes() 23 | { 24 | 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/LiteGraph/Graph.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.Specialized; 6 | 7 | /// 8 | /// Graph. 9 | /// 10 | public class Graph 11 | { 12 | #region Public-Members 13 | 14 | /// 15 | /// Tenant GUID. 16 | /// 17 | public Guid TenantGUID { get; set; } = Guid.NewGuid(); 18 | 19 | /// 20 | /// Globally-unique identifier. 21 | /// 22 | public Guid GUID { get; set; } = Guid.NewGuid(); 23 | 24 | /// 25 | /// Name. 26 | /// 27 | public string Name { get; set; } = null; 28 | 29 | /// 30 | /// Timestamp from creation, in UTC. 31 | /// 32 | public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; 33 | 34 | /// 35 | /// Timestamp from last update, in UTC. 36 | /// 37 | public DateTime LastUpdateUtc { get; set; } = DateTime.UtcNow; 38 | 39 | /// 40 | /// Labels. 41 | /// 42 | public List Labels { get; set; } = null; 43 | 44 | /// 45 | /// Tags. 46 | /// 47 | public NameValueCollection Tags { get; set; } = null; 48 | 49 | /// 50 | /// Object data. 51 | /// 52 | public object Data { get; set; } = null; 53 | 54 | /// 55 | /// Vectors. 56 | /// 57 | public List Vectors { get; set; } = null; 58 | 59 | #endregion 60 | 61 | #region Private-Members 62 | 63 | #endregion 64 | 65 | #region Constructors-and-Factories 66 | 67 | /// 68 | /// Instantiate the object. 69 | /// 70 | public Graph() 71 | { 72 | 73 | } 74 | 75 | #endregion 76 | 77 | #region Public-Methods 78 | 79 | #endregion 80 | 81 | #region Private-Methods 82 | 83 | #endregion 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/GraphRepositoryBase.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.GraphRepositories.Interfaces; 12 | using LiteGraph.Serialization; 13 | using Microsoft.Data.Sqlite; 14 | 15 | /// 16 | /// Graph repository base class. 17 | /// The graph repository base class is only responsible for primitives. 18 | /// Validation and cross-cutting functions should be performed in LiteGraphClient rather than in the graph repository base. 19 | /// 20 | public abstract class GraphRepositoryBase 21 | { 22 | #region Public-Members 23 | 24 | /// 25 | /// Logging. 26 | /// 27 | public LoggingSettings Logging 28 | { 29 | get 30 | { 31 | return _Logging; 32 | } 33 | set 34 | { 35 | if (value == null) value = new LoggingSettings(); 36 | _Logging = value; 37 | } 38 | } 39 | 40 | /// 41 | /// Serializer. 42 | /// 43 | public Serializer Serializer 44 | { 45 | get 46 | { 47 | return _Serializer; 48 | } 49 | set 50 | { 51 | if (value == null) throw new ArgumentNullException(nameof(Serializer)); 52 | _Serializer = value; 53 | } 54 | } 55 | 56 | /// 57 | /// Admin methods. 58 | /// 59 | public abstract IAdminMethods Admin { get; } 60 | 61 | /// 62 | /// Tenant methods. 63 | /// 64 | public abstract ITenantMethods Tenant { get; } 65 | 66 | /// 67 | /// User methods. 68 | /// 69 | public abstract IUserMethods User { get; } 70 | 71 | /// 72 | /// Credential methods. 73 | /// 74 | public abstract ICredentialMethods Credential { get; } 75 | 76 | /// 77 | /// Label methods. 78 | /// 79 | public abstract ILabelMethods Label { get; } 80 | 81 | /// 82 | /// Tag methods. 83 | /// 84 | public abstract ITagMethods Tag { get; } 85 | 86 | /// 87 | /// Vector methods. 88 | /// 89 | public abstract IVectorMethods Vector { get; } 90 | 91 | /// 92 | /// Graph methods. 93 | /// 94 | public abstract IGraphMethods Graph { get; } 95 | 96 | /// 97 | /// Node methods. 98 | /// 99 | public abstract INodeMethods Node { get; } 100 | 101 | /// 102 | /// Edge methods. 103 | /// 104 | public abstract IEdgeMethods Edge { get; } 105 | 106 | /// 107 | /// Batch methods. 108 | /// 109 | public abstract IBatchMethods Batch { get; } 110 | 111 | #endregion 112 | 113 | #region Private-Members 114 | 115 | private LoggingSettings _Logging = new LoggingSettings(); 116 | private Serializer _Serializer = new Serializer(); 117 | 118 | #endregion 119 | 120 | #region Public-Methods 121 | 122 | /// 123 | /// Initialize the repository. 124 | /// 125 | public abstract void InitializeRepository(); 126 | 127 | /// 128 | /// Flush database contents to disk. Only required if using an in-memory instance of a LiteGraph database. 129 | /// 130 | public abstract void Flush(); 131 | 132 | #endregion 133 | 134 | #region Private-Methods 135 | 136 | #endregion 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Interfaces/IAdminMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for admin methods. 16 | /// Graph repository base methods are responsible only for primitives, not input validation or cross-cutting. 17 | /// 18 | public interface IAdminMethods 19 | { 20 | /// 21 | /// Batch existence request. 22 | /// 23 | /// Output filename. 24 | void Backup(string outputFilename); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Interfaces/IBatchMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for batch methods. 16 | /// Graph repository base methods are responsible only for primitives, not input validation or cross-cutting. 17 | /// 18 | public interface IBatchMethods 19 | { 20 | /// 21 | /// Batch existence request. 22 | /// 23 | /// Tenant GUID. 24 | /// Graph GUID. 25 | /// Existence request. 26 | /// Existence result. 27 | ExistenceResult Existence(Guid tenantGuid, Guid graphGuid, ExistenceRequest req); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Interfaces/ICredentialMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for credential methods. 16 | /// Graph repository base methods are responsible only for primitives, not input validation or cross-cutting. 17 | /// 18 | public interface ICredentialMethods 19 | { 20 | /// 21 | /// Create a credential. 22 | /// 23 | /// Credential. 24 | /// Credential. 25 | Credential Create(Credential credential); 26 | 27 | /// 28 | /// Read all credentials in tenant. 29 | /// 30 | /// Tenant GUID. 31 | /// Enumeration order. 32 | /// Number of records to skip. 33 | /// Credentials. 34 | IEnumerable ReadAllInTenant( 35 | Guid tenantGuid, 36 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 37 | int skip = 0); 38 | 39 | /// 40 | /// Read credentials. 41 | /// 42 | /// Tenant GUID. 43 | /// User GUID. 44 | /// Bearer token. 45 | /// Enumeration order. 46 | /// Number of records to skip. 47 | /// Credentials. 48 | IEnumerable ReadMany( 49 | Guid? tenantGuid, 50 | Guid? userGuid, 51 | string bearerToken, 52 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 53 | int skip = 0); 54 | 55 | /// 56 | /// Read a credential by GUID. 57 | /// 58 | /// Tenant GUID. 59 | /// GUID. 60 | /// Credential. 61 | Credential ReadByGuid(Guid tenantGuid, Guid guid); 62 | 63 | /// 64 | /// Read a credential by bearer token. 65 | /// 66 | /// Bearer token. 67 | /// Credential. 68 | Credential ReadByBearerToken(string bearerToken); 69 | 70 | /// 71 | /// Update a credential. 72 | /// 73 | /// Credential. 74 | /// Credential. 75 | Credential Update(Credential cred); 76 | 77 | /// 78 | /// Delete credentials associated with a tenant. 79 | /// 80 | /// Tenant GUID. 81 | void DeleteAllInTenant(Guid tenantGuid); 82 | 83 | /// 84 | /// Delete a credential. 85 | /// 86 | /// Tenant GUID. 87 | /// GUID. 88 | void DeleteByGuid(Guid tenantGuid, Guid guid); 89 | 90 | /// 91 | /// Delete credentials associated with a user. 92 | /// 93 | /// Tenant GUID. 94 | /// User GUID. 95 | void DeleteByUser(Guid tenantGuid, Guid userGuid); 96 | 97 | /// 98 | /// Check if a credential exists by GUID. 99 | /// 100 | /// Tenant GUID. 101 | /// GUID. 102 | /// True if exists. 103 | bool ExistsByGuid(Guid tenantGuid, Guid guid); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Interfaces/IGraphMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for graph methods. 16 | /// Graph repository base methods are responsible only for primitives, not input validation or cross-cutting. 17 | /// 18 | public interface IGraphMethods 19 | { 20 | /// 21 | /// Create a graph. 22 | /// 23 | /// Graph. 24 | /// Graph. 25 | Graph Create(Graph graph); 26 | 27 | /// 28 | /// Read all graphs in a given tenant. 29 | /// 30 | /// Tenant GUID. 31 | /// Enumeration order. 32 | /// The number of records to skip. 33 | /// Graphs. 34 | IEnumerable ReadAllInTenant( 35 | Guid tenantGuid, 36 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 37 | int skip = 0); 38 | 39 | /// 40 | /// Read graphs. 41 | /// 42 | /// Tenant GUID. 43 | /// Labels. 44 | /// Tags on which to match. 45 | /// 46 | /// Graph filter expression for Data JSON body. 47 | /// Expression left terms must follow the form of Sqlite JSON paths. 48 | /// For example, to retrieve the 'Name' property, use '$.Name', OperatorEnum.Equals, '[name here]'. 49 | /// Enumeration order. 50 | /// The number of records to skip. 51 | /// Graphs. 52 | IEnumerable ReadMany( 53 | Guid tenantGuid, 54 | List labels = null, 55 | NameValueCollection tags = null, 56 | Expr graphFilter = null, 57 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 58 | int skip = 0); 59 | 60 | /// 61 | /// Read first. 62 | /// 63 | /// Tenant GUID. 64 | /// Labels. 65 | /// Tags on which to match. 66 | /// 67 | /// Graph filter expression for Data JSON body. 68 | /// Expression left terms must follow the form of Sqlite JSON paths. 69 | /// For example, to retrieve the 'Name' property, use '$.Name', OperatorEnum.Equals, '[name here]'. 70 | /// Enumeration order. 71 | /// Graph. 72 | Graph ReadFirst( 73 | Guid tenantGuid, 74 | List labels = null, 75 | NameValueCollection tags = null, 76 | Expr graphFilter = null, 77 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending); 78 | 79 | /// 80 | /// Read a graph by GUID. 81 | /// 82 | /// Tenant GUID. 83 | /// GUID. 84 | /// Graph. 85 | Graph ReadByGuid(Guid tenantGuid, Guid guid); 86 | 87 | /// 88 | /// Update a graph. 89 | /// 90 | /// Graph. 91 | /// Graph. 92 | Graph Update(Graph graph); 93 | 94 | /// 95 | /// Delete a graph. 96 | /// 97 | /// Tenant GUID. 98 | /// GUID. 99 | void DeleteByGuid(Guid tenantGuid, Guid guid); 100 | 101 | /// 102 | /// Delete graphs associated with a tenant. Deletion is forceful. 103 | /// 104 | /// Tenant GUID. 105 | void DeleteAllInTenant(Guid tenantGuid); 106 | 107 | /// 108 | /// Check if a graph exists by GUID. 109 | /// 110 | /// Tenant GUID. 111 | /// GUID. 112 | /// True if exists. 113 | bool ExistsByGuid(Guid tenantGuid, Guid guid); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Interfaces/ITenantMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for tenant methods. 16 | /// Graph repository base methods are responsible only for primitives, not input validation or cross-cutting. 17 | /// 18 | public interface ITenantMethods 19 | { 20 | /// 21 | /// Create a tenant. 22 | /// 23 | /// Tenant. 24 | /// Tenant. 25 | TenantMetadata Create(TenantMetadata tenant); 26 | 27 | /// 28 | /// Read tenants. 29 | /// 30 | /// Enumeration order. 31 | /// The number of records to skip. 32 | /// Tenants. 33 | IEnumerable ReadMany( 34 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 35 | int skip = 0); 36 | 37 | /// 38 | /// Read a tenant by GUID. 39 | /// 40 | /// GUID. 41 | /// Tenant. 42 | TenantMetadata ReadByGuid(Guid guid); 43 | 44 | /// 45 | /// Update a tenant. 46 | /// 47 | /// Tenant. 48 | /// Tenant. 49 | TenantMetadata Update(TenantMetadata tenant); 50 | 51 | /// 52 | /// Delete a tenant. 53 | /// 54 | /// GUID. 55 | /// True to force deletion of users and credentials. 56 | void DeleteByGuid(Guid guid, bool force = false); 57 | 58 | /// 59 | /// Check if a tenant exists by GUID. 60 | /// 61 | /// GUID. 62 | /// True if exists. 63 | bool ExistsByGuid(Guid guid); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Interfaces/IUserMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Interfaces 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Data; 8 | using System.Linq; 9 | using ExpressionTree; 10 | using LiteGraph; 11 | using LiteGraph.Serialization; 12 | using Microsoft.Data.Sqlite; 13 | 14 | /// 15 | /// Interface for user methods. 16 | /// Graph repository base methods are responsible only for primitives, not input validation or cross-cutting. 17 | /// 18 | public interface IUserMethods 19 | { 20 | /// 21 | /// Create a user. 22 | /// 23 | /// User. 24 | /// User. 25 | UserMaster Create(UserMaster user); 26 | 27 | /// 28 | /// Read all users in a given tenant. 29 | /// 30 | /// Tenant GUID. 31 | /// Enumeration order. 32 | /// The number of records to skip. 33 | /// Users. 34 | IEnumerable ReadAllInTenant( 35 | Guid tenantGuid, 36 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 37 | int skip = 0); 38 | 39 | /// 40 | /// Read users. 41 | /// 42 | /// Tenant GUID. 43 | /// Email. 44 | /// Enumeration order. 45 | /// Number of records to skip. 46 | /// Users. 47 | IEnumerable ReadMany( 48 | Guid? tenantGuid, 49 | string email, 50 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 51 | int skip = 0); 52 | 53 | /// 54 | /// Read a user by GUID. 55 | /// 56 | /// Tenant GUID. 57 | /// GUID. 58 | /// User. 59 | UserMaster ReadByGuid(Guid tenantGuid, Guid guid); 60 | 61 | /// 62 | /// Read tenants associated with a given email address. 63 | /// 64 | /// Email address. 65 | /// List of tenants. 66 | List ReadTenantsByEmail(string email); 67 | 68 | /// 69 | /// Read a user by email. 70 | /// 71 | /// Tenant GUID. 72 | /// Email. 73 | /// User. 74 | UserMaster ReadByEmail(Guid tenantGuid, string email); 75 | 76 | /// 77 | /// Update a user. 78 | /// 79 | /// User. 80 | /// User. 81 | UserMaster Update(UserMaster user); 82 | 83 | /// 84 | /// Delete a user. 85 | /// 86 | /// Tenant GUID. 87 | /// GUID. 88 | void DeleteByGuid(Guid tenantGuid, Guid guid); 89 | 90 | /// 91 | /// Delete users associated with a tenant. 92 | /// 93 | /// Tenant GUID. 94 | void DeleteAllInTenant(Guid tenantGuid); 95 | 96 | /// 97 | /// Check if a user exists by GUID. 98 | /// 99 | /// Tenant GUID. 100 | /// GUID. 101 | /// True if exists. 102 | bool ExistsByGuid(Guid tenantGuid, Guid guid); 103 | 104 | /// 105 | /// Check if a user exists by email. 106 | /// 107 | /// Tenant GUID. 108 | /// Email. 109 | /// True if exists. 110 | bool ExistsByEmail(Guid tenantGuid, string email); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Sqlite/Implementations/AdminMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Sqlite.Implementations 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Runtime.Serialization.Json; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using LiteGraph.GraphRepositories.Interfaces; 11 | using LiteGraph.GraphRepositories.Sqlite; 12 | using LiteGraph.GraphRepositories.Sqlite.Queries; 13 | using LiteGraph.Serialization; 14 | 15 | using LoggingSettings = LoggingSettings; 16 | 17 | /// 18 | /// Admin methods. 19 | /// Graph repository base methods are responsible only for primitives, not input validation or cross-cutting. 20 | /// 21 | public class AdminMethods : IAdminMethods 22 | { 23 | #region Public-Members 24 | 25 | #endregion 26 | 27 | #region Private-Members 28 | 29 | private SqliteGraphRepository _Repo = null; 30 | 31 | #endregion 32 | 33 | #region Constructors-and-Factories 34 | 35 | /// 36 | /// Admin methods. 37 | /// 38 | /// Graph repository. 39 | public AdminMethods(SqliteGraphRepository repo) 40 | { 41 | _Repo = repo ?? throw new ArgumentNullException(nameof(repo)); 42 | } 43 | 44 | #endregion 45 | 46 | #region Public-Methods 47 | 48 | /// 49 | public void Backup(string outputFilename) 50 | { 51 | if (String.IsNullOrEmpty(outputFilename)) throw new ArgumentNullException(nameof(outputFilename)); 52 | string query = "VACUUM INTO '" + Sanitizer.Sanitize(outputFilename) + "';"; 53 | _Repo.ExecuteQuery(query); 54 | } 55 | 56 | #endregion 57 | 58 | #region Private-Methods 59 | 60 | #endregion 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Sqlite/Implementations/TenantMethods.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Sqlite.Implementations 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Runtime.Serialization.Json; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using LiteGraph.GraphRepositories.Interfaces; 11 | using LiteGraph.GraphRepositories.Sqlite; 12 | using LiteGraph.GraphRepositories.Sqlite.Queries; 13 | using LiteGraph.Serialization; 14 | 15 | using LoggingSettings = LoggingSettings; 16 | 17 | /// 18 | /// Tenant methods. 19 | /// Graph repository base methods are responsible only for primitives, not input validation or cross-cutting. 20 | /// 21 | public class TenantMethods : ITenantMethods 22 | { 23 | #region Public-Members 24 | 25 | #endregion 26 | 27 | #region Private-Members 28 | 29 | private SqliteGraphRepository _Repo = null; 30 | 31 | #endregion 32 | 33 | #region Constructors-and-Factories 34 | 35 | /// 36 | /// Tenant methods. 37 | /// 38 | /// Graph repository. 39 | public TenantMethods(SqliteGraphRepository repo) 40 | { 41 | _Repo = repo ?? throw new ArgumentNullException(nameof(repo)); 42 | } 43 | 44 | #endregion 45 | 46 | #region Public-Methods 47 | 48 | /// 49 | public TenantMetadata Create(TenantMetadata tenant) 50 | { 51 | if (tenant == null) throw new ArgumentNullException(nameof(tenant)); 52 | string createQuery = TenantQueries.Insert(tenant); 53 | DataTable createResult = _Repo.ExecuteQuery(createQuery, true); 54 | TenantMetadata created = Converters.TenantFromDataRow(createResult.Rows[0]); 55 | return created; 56 | } 57 | 58 | /// 59 | public void DeleteByGuid(Guid guid, bool force = false) 60 | { 61 | _Repo.ExecuteQuery(TenantQueries.Delete(guid), true); 62 | } 63 | 64 | /// 65 | public bool ExistsByGuid(Guid tenantGuid) 66 | { 67 | return (ReadByGuid(tenantGuid) != null); 68 | } 69 | 70 | /// 71 | public TenantMetadata ReadByGuid(Guid guid) 72 | { 73 | DataTable result = _Repo.ExecuteQuery(TenantQueries.Select(guid)); 74 | if (result != null && result.Rows.Count == 1) return Converters.TenantFromDataRow(result.Rows[0]); 75 | return null; 76 | } 77 | 78 | /// 79 | public IEnumerable ReadMany( 80 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending, 81 | int skip = 0) 82 | { 83 | if (skip < 0) throw new ArgumentOutOfRangeException(nameof(skip)); 84 | 85 | while (true) 86 | { 87 | DataTable result = _Repo.ExecuteQuery(TenantQueries.SelectMany(_Repo.SelectBatchSize, skip, order)); 88 | if (result == null || result.Rows.Count < 1) break; 89 | 90 | for (int i = 0; i < result.Rows.Count; i++) 91 | { 92 | yield return Converters.TenantFromDataRow(result.Rows[i]); 93 | skip++; 94 | } 95 | 96 | if (result.Rows.Count < _Repo.SelectBatchSize) break; 97 | } 98 | } 99 | 100 | /// 101 | public TenantMetadata Update(TenantMetadata tenant) 102 | { 103 | if (tenant == null) throw new ArgumentNullException(nameof(tenant)); 104 | return Converters.TenantFromDataRow(_Repo.ExecuteQuery(TenantQueries.Update(tenant), true).Rows[0]); 105 | } 106 | 107 | #endregion 108 | 109 | #region Private-Methods 110 | 111 | #endregion 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Sqlite/Queries/CredentialQueries.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Sqlite.Queries 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.Specialized; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using ExpressionTree; 10 | using LiteGraph.Serialization; 11 | 12 | internal static class CredentialQueries 13 | { 14 | internal static string TimestampFormat = "yyyy-MM-dd HH:mm:ss.ffffff"; 15 | 16 | internal static Serializer Serializer = new Serializer(); 17 | 18 | internal static string Insert(Credential cred) 19 | { 20 | string ret = 21 | "INSERT INTO 'creds' " 22 | + "VALUES (" 23 | + "'" + cred.GUID + "'," 24 | + "'" + cred.TenantGUID + "'," 25 | + "'" + cred.UserGUID + "'," 26 | + "'" + Sanitizer.Sanitize(cred.Name) + "'," 27 | + "'" + Sanitizer.Sanitize(cred.BearerToken) + "'," 28 | + (cred.Active ? "1" : "0") + "," 29 | + "'" + Sanitizer.Sanitize(cred.CreatedUtc.ToString(TimestampFormat)) + "'," 30 | + "'" + Sanitizer.Sanitize(cred.LastUpdateUtc.ToString(TimestampFormat)) + "'" 31 | + ") " 32 | + "RETURNING *;"; 33 | 34 | return ret; 35 | } 36 | 37 | internal static string SelectByToken(string bearerToken) 38 | { 39 | return "SELECT * FROM 'creds' WHERE bearertoken = '" + Sanitizer.Sanitize(bearerToken) + "';"; 40 | } 41 | 42 | internal static string SelectByGuid(Guid tenantGuid, Guid guid) 43 | { 44 | return "SELECT * FROM 'creds' WHERE tenantguid = '" + tenantGuid + "' AND guid = '" + guid + "';"; 45 | } 46 | 47 | internal static string SelectAllInTenant(Guid tenantGuid, int batchSize = 100, int skip = 0, EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending) 48 | { 49 | string ret = "SELECT * FROM 'creds' WHERE tenantguid = '" + tenantGuid + "' "; 50 | ret += 51 | "ORDER BY " + Converters.EnumerationOrderToClause(order) + " " 52 | + "LIMIT " + batchSize + " OFFSET " + skip + ";"; 53 | return ret; 54 | } 55 | 56 | internal static string Select( 57 | Guid? tenantGuid, 58 | Guid? userGuid, 59 | string bearerToken, 60 | int batchSize = 100, 61 | int skip = 0, 62 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending) 63 | { 64 | string ret = 65 | "SELECT * FROM 'creds' WHERE guid IS NOT NULL "; 66 | 67 | if (tenantGuid != null) 68 | ret += "AND tenantguid = '" + tenantGuid.Value.ToString() + "' "; 69 | 70 | if (userGuid != null) 71 | ret += "AND userGuid = '" + userGuid.Value.ToString() + "' "; 72 | 73 | if (!String.IsNullOrEmpty(bearerToken)) 74 | ret += "AND bearertoken = '" + Sanitizer.Sanitize(bearerToken) + "' "; 75 | 76 | ret += 77 | "ORDER BY " + Converters.EnumerationOrderToClause(order) + " " 78 | + "LIMIT " + batchSize + " OFFSET " + skip + ";"; 79 | 80 | return ret; 81 | } 82 | 83 | internal static string Update(Credential cred) 84 | { 85 | return 86 | "UPDATE 'creds' SET " 87 | + "lastupdateutc = '" + DateTime.UtcNow.ToString(TimestampFormat) + "'," 88 | + "name = '" + Sanitizer.Sanitize(cred.Name) + "'," 89 | + "active = " + (cred.Active ? "1" : "0") + " " 90 | + "WHERE guid = '" + cred.GUID + "' " 91 | + "RETURNING *;"; 92 | } 93 | 94 | internal static string Delete(Guid tenantGuid, Guid guid) 95 | { 96 | return "DELETE FROM 'creds' WHERE tenantguid = '" + tenantGuid + "' AND guid = '" + guid + "';"; 97 | } 98 | 99 | internal static string DeleteUser(Guid tenantGuid, Guid userGuid) 100 | { 101 | return "DELETE FROM 'creds' WHERE tenantguid = '" + tenantGuid + "' AND userguid = '" + userGuid + "';"; 102 | } 103 | 104 | internal static string DeleteAllInTenant(Guid tenantGuid) 105 | { 106 | return "DELETE FROM 'creds' WHERE tenantguid = '" + tenantGuid + "';"; 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Sqlite/Queries/TenantQueries.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Sqlite.Queries 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.Specialized; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using ExpressionTree; 10 | using LiteGraph.Serialization; 11 | 12 | internal static class TenantQueries 13 | { 14 | internal static string TimestampFormat = "yyyy-MM-dd HH:mm:ss.ffffff"; 15 | 16 | internal static Serializer Serializer = new Serializer(); 17 | 18 | internal static string Insert(TenantMetadata tenant) 19 | { 20 | string ret = 21 | "INSERT INTO 'tenants' " 22 | + "VALUES (" 23 | + "'" + tenant.GUID + "'," 24 | + "'" + Sanitizer.Sanitize(tenant.Name) + "'," 25 | + (tenant.Active ? "1" : "0") + "," 26 | + "'" + Sanitizer.Sanitize(tenant.CreatedUtc.ToString(TimestampFormat)) + "'," 27 | + "'" + Sanitizer.Sanitize(tenant.LastUpdateUtc.ToString(TimestampFormat)) + "'" 28 | + ") " 29 | + "RETURNING *;"; 30 | 31 | return ret; 32 | } 33 | 34 | internal static string Select(string name) 35 | { 36 | return "SELECT * FROM 'tenants' WHERE name = '" + Sanitizer.Sanitize(name) + "';"; 37 | } 38 | 39 | internal static string Select(Guid guid) 40 | { 41 | return "SELECT * FROM 'tenants' WHERE guid = '" + guid.ToString() + "';"; 42 | } 43 | 44 | internal static string SelectMany( 45 | int batchSize = 100, 46 | int skip = 0, 47 | EnumerationOrderEnum order = EnumerationOrderEnum.CreatedDescending) 48 | { 49 | string ret = 50 | "SELECT * FROM 'tenants' WHERE guid IS NOT NULL " 51 | + "ORDER BY " + Converters.EnumerationOrderToClause(order) + " " 52 | + "LIMIT " + batchSize + " OFFSET " + skip + ";"; 53 | 54 | return ret; 55 | } 56 | 57 | internal static string Update(TenantMetadata tenant) 58 | { 59 | return 60 | "UPDATE 'tenants' SET " 61 | + "lastupdateutc = '" + DateTime.UtcNow.ToString(TimestampFormat) + "'," 62 | + "name = '" + Sanitizer.Sanitize(tenant.Name) + "'," 63 | + "active = " + (tenant.Active ? "1" : "0") + " " 64 | + "WHERE guid = '" + tenant.GUID + "' " 65 | + "RETURNING *;"; 66 | } 67 | 68 | internal static string Delete(Guid tenantGuid) 69 | { 70 | string ret = string.Empty; 71 | ret += "DELETE FROM 'labels' WHERE tenantguid = '" + tenantGuid + "'; "; 72 | ret += "DELETE FROM 'tags' WHERE tenantguid = '" + tenantGuid + "'; "; 73 | ret += "DELETE FROM 'vectors' WHERE tenantguid = '" + tenantGuid + "'; "; 74 | ret += "DELETE FROM 'edges' WHERE tenantguid = '" + tenantGuid + "'; "; 75 | ret += "DELETE FROM 'nodes' WHERE tenantguid = '" + tenantGuid + "'; "; 76 | ret += "DELETE FROM 'graphs' WHERE tenantguid = '" + tenantGuid + "'; "; 77 | ret += "DELETE FROM 'creds' WHERE tenantguid = '" + tenantGuid + "'; "; 78 | ret += "DELETE FROM 'users' WHERE tenantguid = '" + tenantGuid + "'; "; 79 | ret += "DELETE FROM 'tenants' WHERE guid = '" + tenantGuid + "'; "; 80 | return ret; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/LiteGraph/GraphRepositories/Sqlite/Sanitizer.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.GraphRepositories.Sqlite 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Text.Json; 8 | using System.Threading.Tasks; 9 | 10 | 11 | internal static class Sanitizer 12 | { 13 | internal static string Sanitize(string val) 14 | { 15 | if (String.IsNullOrEmpty(val)) return val; 16 | 17 | string ret = ""; 18 | 19 | // 20 | // null, below ASCII range, above ASCII range 21 | // 22 | for (int i = 0; i < val.Length; i++) 23 | { 24 | if (((int)(val[i]) == 10) || // Preserve carriage return 25 | ((int)(val[i]) == 13)) // and line feed 26 | { 27 | ret += val[i]; 28 | } 29 | else if ((int)(val[i]) < 32) 30 | { 31 | continue; 32 | } 33 | else 34 | { 35 | ret += val[i]; 36 | } 37 | } 38 | 39 | // 40 | // double dash 41 | // 42 | int doubleDash = 0; 43 | while (true) 44 | { 45 | doubleDash = ret.IndexOf("--"); 46 | if (doubleDash < 0) 47 | { 48 | break; 49 | } 50 | else 51 | { 52 | ret = ret.Remove(doubleDash, 2); 53 | } 54 | } 55 | 56 | // 57 | // open comment 58 | // 59 | int openComment = 0; 60 | while (true) 61 | { 62 | openComment = ret.IndexOf("/*"); 63 | if (openComment < 0) break; 64 | else 65 | { 66 | ret = ret.Remove(openComment, 2); 67 | } 68 | } 69 | 70 | // 71 | // close comment 72 | // 73 | int closeComment = 0; 74 | while (true) 75 | { 76 | closeComment = ret.IndexOf("*/"); 77 | if (closeComment < 0) break; 78 | else 79 | { 80 | ret = ret.Remove(closeComment, 2); 81 | } 82 | } 83 | 84 | // 85 | // in-string replacement 86 | // 87 | ret = ret.Replace("'", "''"); 88 | return ret; 89 | } 90 | 91 | internal static string SanitizeJson(string json) 92 | { 93 | if (string.IsNullOrEmpty(json)) return json; 94 | 95 | try 96 | { 97 | JsonDocument.Parse(json); 98 | } 99 | catch (JsonException e) 100 | { 101 | throw new ArgumentException("Invalid JSON provided for data.", nameof(json), e); 102 | } 103 | 104 | return json.Replace("'", "''"); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/LiteGraph/Helpers/FileHelpers.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Helpers 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.Specialized; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | /// 12 | /// File helpers. 13 | /// 14 | public static class FileHelpers 15 | { 16 | /// 17 | /// Normalize a directory. 18 | /// 19 | /// Directory. 20 | /// Directory. 21 | public static string NormalizeDirectory(string directory) 22 | { 23 | if (String.IsNullOrEmpty(directory)) return directory; 24 | while (directory.Contains("\\")) directory = directory.Replace("\\", "/"); 25 | while (directory.Contains("..")) directory = directory.Replace("..", ""); 26 | while (directory.Contains("//")) directory = directory.Replace("//", "/"); 27 | if (!directory.EndsWith("/")) directory += "/"; 28 | if (directory.IndexOfAny(Path.GetInvalidPathChars()) >= 0) 29 | throw new ArgumentException("The specified directory contains invalid characters."); 30 | return directory; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/LiteGraph/Helpers/NvcHelpers.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Helpers 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.Specialized; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// Name-value collection helpers. 12 | /// 13 | public static class NvcHelpers 14 | { 15 | /// 16 | /// Combine two name-value collections. 17 | /// 18 | /// Name-value collection 1. 19 | /// Name-value collection 2. 20 | /// Name-value collection. 21 | public static NameValueCollection Combine(NameValueCollection nvc1, NameValueCollection nvc2) 22 | { 23 | if (nvc1 == null) return nvc2; 24 | if (nvc2 == null) return nvc1; 25 | NameValueCollection nvc = new NameValueCollection(); 26 | nvc.Add(nvc1); 27 | nvc.Add(nvc2); 28 | return nvc; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/LiteGraph/Helpers/StringHelper.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Helpers 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.Specialized; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// String collection helpers. 12 | /// 13 | public static class StringHelpers 14 | { 15 | /// 16 | /// Combine two string lists. 17 | /// 18 | /// String list 1. 19 | /// String list 2. 20 | /// String list. 21 | public static List Combine(List list1, List list2) 22 | { 23 | if (list1 == null) return list2; 24 | if (list2 == null) return list1; 25 | List ret = new List(); 26 | ret.AddRange(list1); 27 | ret.AddRange(list2); 28 | return ret; 29 | } 30 | 31 | /// 32 | /// Redact a string. 33 | /// 34 | /// String. 35 | /// Replacement character. 36 | /// Number of characters to retain. 37 | /// Redacted string. 38 | public static string RedactTail(string str, string replacementChar = "*", int charsToRetain = 4) 39 | { 40 | if (String.IsNullOrEmpty(str)) return str; 41 | if (String.IsNullOrEmpty(replacementChar)) throw new ArgumentNullException(nameof(replacementChar)); 42 | if (charsToRetain < 0) throw new ArgumentOutOfRangeException(nameof(charsToRetain)); 43 | 44 | if (str.Length < charsToRetain) 45 | { 46 | return new string(replacementChar[0], str.Length); 47 | } 48 | else 49 | { 50 | return str.Substring(0, charsToRetain) + new string(replacementChar[0], str.Length - charsToRetain); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/LiteGraph/Helpers/VectorHelper.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Helpers 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | /// 8 | /// Vector helper. 9 | /// 10 | public static class VectorHelper 11 | { 12 | /// 13 | /// Calculates the cosine similarity between two vectors 14 | /// 15 | /// Value between -1 and 1, where 1 means vectors are identical, 0 means orthogonal, -1 means opposite 16 | public static float CalculateCosineSimilarity(List vectors1, List vectors2) 17 | { 18 | if (vectors1 == null || vectors2 == null) 19 | throw new ArgumentNullException("Vectors cannot be null"); 20 | 21 | if (vectors1.Count != vectors2.Count) 22 | throw new ArgumentException("Vectors must be of equal length"); 23 | 24 | float dotProduct = CalculateInnerProduct(vectors1, vectors2); 25 | float magnitude1 = (float)Math.Sqrt(vectors1.Sum(x => x * x)); 26 | float magnitude2 = (float)Math.Sqrt(vectors2.Sum(x => x * x)); 27 | 28 | if (magnitude1 == 0 || magnitude2 == 0) 29 | throw new ArgumentException("Vector magnitudes cannot be zero"); 30 | 31 | return dotProduct / (magnitude1 * magnitude2); 32 | } 33 | 34 | /// 35 | /// Calculates the cosine distance between two vectors 36 | /// 37 | /// Value between 0 and 2, where 0 means vectors are identical, 2 means opposite 38 | public static float CalculateCosineDistance(List vectors1, List vectors2) 39 | { 40 | return 1 - CalculateCosineSimilarity(vectors1, vectors2); 41 | } 42 | 43 | /// 44 | /// Calculates the Euclidean similarity between two vectors 45 | /// 46 | /// Value between 0 and 1, where 1 means vectors are identical 47 | public static float CalculateEuclidianSimilarity(List vectors1, List vectors2) 48 | { 49 | float distance = CalculateEuclidianDistance(vectors1, vectors2); 50 | return 1 / (1 + distance); // Convert distance to similarity using inverse relationship 51 | } 52 | 53 | /// 54 | /// Calculates the Euclidean distance between two vectors 55 | /// 56 | /// Value >= 0, where 0 means vectors are identical 57 | public static float CalculateEuclidianDistance(List vectors1, List vectors2) 58 | { 59 | if (vectors1 == null || vectors2 == null) 60 | throw new ArgumentNullException("Vectors cannot be null"); 61 | 62 | if (vectors1.Count != vectors2.Count) 63 | throw new ArgumentException("Vectors must be of equal length"); 64 | 65 | float sumSquaredDifferences = 0; 66 | for (int i = 0; i < vectors1.Count; i++) 67 | { 68 | float diff = vectors1[i] - vectors2[i]; 69 | sumSquaredDifferences += diff * diff; 70 | } 71 | 72 | return (float)Math.Sqrt(sumSquaredDifferences); 73 | } 74 | 75 | /// 76 | /// Calculates the inner (dot) product of two vectors 77 | /// 78 | /// The sum of the element-wise products 79 | public static float CalculateInnerProduct(List vectors1, List vectors2) 80 | { 81 | if (vectors1 == null || vectors2 == null) 82 | throw new ArgumentNullException("Vectors cannot be null"); 83 | 84 | if (vectors1.Count != vectors2.Count) 85 | throw new ArgumentException("Vectors must be of equal length"); 86 | 87 | return vectors1.Zip(vectors2, (a, b) => a * b).Sum(); 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /src/LiteGraph/LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/LiteGraph/LabelMetadata.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.Specialized; 6 | using System.Linq; 7 | using System.Security.Cryptography; 8 | using System.Text.Json.Serialization; 9 | 10 | /// 11 | /// Label metadata. 12 | /// we 13 | public class LabelMetadata 14 | { 15 | #region Public-Members 16 | 17 | /// 18 | /// GUID. 19 | /// 20 | public Guid GUID { get; set; } = Guid.NewGuid(); 21 | 22 | /// 23 | /// Tenant GUID. 24 | /// 25 | public Guid TenantGUID { get; set; } = Guid.NewGuid(); 26 | 27 | /// 28 | /// Graph GUID. 29 | /// 30 | public Guid GraphGUID { get; set; } = default(Guid); 31 | 32 | /// 33 | /// Node GUID. 34 | /// 35 | public Guid? NodeGUID { get; set; } = null; 36 | 37 | /// 38 | /// Edge GUID. 39 | /// 40 | public Guid? EdgeGUID { get; set; } = null; 41 | 42 | /// 43 | /// Key. 44 | /// 45 | public string Label { get; set; } = string.Empty; 46 | 47 | /// 48 | /// Creation timestamp, in UTC. 49 | /// 50 | public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; 51 | 52 | /// 53 | /// Timestamp from last update, in UTC. 54 | /// 55 | public DateTime LastUpdateUtc { get; set; } = DateTime.UtcNow; 56 | 57 | #endregion 58 | 59 | #region Private-Members 60 | 61 | #endregion 62 | 63 | #region Constructors-and-Factories 64 | 65 | /// 66 | /// Instantiate. 67 | /// 68 | public LabelMetadata() 69 | { 70 | 71 | } 72 | 73 | /// 74 | /// Create a list of label metadata from a list of labels. 75 | /// 76 | /// Tenant GUID. 77 | /// Graph GUID. 78 | /// Node GUID. 79 | /// Edge GUID. 80 | /// Labels. 81 | /// List of label metadata. 82 | public static List FromListString(Guid tenantGuid, Guid graphGuid, Guid? nodeGuid, Guid? edgeGuid, List labels) 83 | { 84 | if (labels == null) return null; 85 | if (labels.Count < 1) return new List(); 86 | 87 | List ret = new List(); 88 | 89 | foreach (string label in labels) 90 | { 91 | ret.Add(new LabelMetadata 92 | { 93 | TenantGUID = tenantGuid, 94 | GraphGUID = graphGuid, 95 | NodeGUID = nodeGuid, 96 | EdgeGUID = edgeGuid, 97 | Label = label 98 | }); 99 | } 100 | 101 | return ret; 102 | } 103 | 104 | /// 105 | /// Create a list of strings for all labels in the list. 106 | /// 107 | /// Labels. 108 | /// Labels. 109 | public static List ToListString(List labels) 110 | { 111 | if (labels == null) return null; 112 | if (labels.Count < 1) return new List(); 113 | 114 | List ret = new List(); 115 | foreach (LabelMetadata label in labels) 116 | { 117 | ret.Add(label.Label); 118 | } 119 | 120 | return ret; 121 | } 122 | 123 | #endregion 124 | 125 | #region Public-Methods 126 | 127 | #endregion 128 | 129 | #region Private-Methods 130 | 131 | #endregion 132 | } 133 | } -------------------------------------------------------------------------------- /src/LiteGraph/LiteGraph.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | 4.0.21 6 | LiteGraph is a property graph database with support for graph relationships, tags, labels, metadata, data, and vectors. 7 | Refactor, batch APIs, and performance optimization. 8 | true 9 | Joel Christner 10 | Joel Christner 11 | (c)2025 Joel Christner 12 | (c)2025 Joel Christner 13 | LICENSE.md 14 | https://github.com/jchristn/LiteGraph 15 | favicon.png 16 | https://github.com/jchristn/LiteGraph 17 | github 18 | graph database search traverse rest 19 | assets\favicon.ico 20 | True 21 | LiteGraph.xml 22 | LiteGraph 23 | README.md 24 | True 25 | snupkg 26 | true 27 | LiteGraph.xml 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | True 44 | 45 | 46 | 47 | Always 48 | 49 | 50 | Always 51 | 52 | 53 | True 54 | \ 55 | 56 | 57 | True 58 | 59 | 60 | 61 | Always 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/LiteGraph/LoggingSettings.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | /// 7 | /// Logging settings. 8 | /// 9 | public class LoggingSettings 10 | { 11 | #region Public-Members 12 | 13 | /// 14 | /// Enable or disable logging. 15 | /// 16 | public bool Enable { get; set; } = true; 17 | 18 | /// 19 | /// List of syslog servers. 20 | /// 21 | public List Servers 22 | { 23 | get 24 | { 25 | return _Servers; 26 | } 27 | set 28 | { 29 | if (value == null) value = new List(); 30 | _Servers = value; 31 | } 32 | } 33 | 34 | /// 35 | /// Log directory. 36 | /// 37 | public string LogDirectory { get; set; } = Constants.LogDirectory; 38 | 39 | /// 40 | /// Log filename. 41 | /// 42 | public string LogFilename { get; set; } = Constants.LogFilename; 43 | 44 | /// 45 | /// Enable or disable console logging. 46 | /// 47 | public bool ConsoleLogging { get; set; } = true; 48 | 49 | /// 50 | /// Enable colors in logging. 51 | /// 52 | public bool EnableColors { get; set; } = true; 53 | 54 | /// 55 | /// Minimum severity. 56 | /// 57 | public int MinimumSeverity 58 | { 59 | get 60 | { 61 | return _MinimumSeverity; 62 | } 63 | set 64 | { 65 | if (value < 0 || value > 7) throw new ArgumentOutOfRangeException(nameof(MinimumSeverity)); 66 | _MinimumSeverity = value; 67 | } 68 | } 69 | 70 | /// 71 | /// Header to prepend to emitted messages. 72 | /// 73 | public string Header 74 | { 75 | get 76 | { 77 | return _Header; 78 | } 79 | set 80 | { 81 | if (!String.IsNullOrEmpty(value)) if (!value.EndsWith(" ")) value += " "; 82 | _Header = value; 83 | } 84 | } 85 | 86 | /// 87 | /// Method to invoke to send log messages. 88 | /// 89 | public Action Logger { get; set; } = null; 90 | 91 | /// 92 | /// Enable or disable logging of queries. 93 | /// 94 | public bool LogQueries { get; set; } = false; 95 | 96 | /// 97 | /// Enable or disable logging of results. 98 | /// 99 | public bool LogResults { get; set; } = false; 100 | 101 | #endregion 102 | 103 | #region Private-Members 104 | 105 | private string _Header = "[LiteGraph] "; 106 | private int _MinimumSeverity = 0; 107 | private List _Servers = new List() 108 | { 109 | new SyslogServer 110 | { 111 | Hostname = "127.0.0.1", 112 | Port = 514 113 | } 114 | }; 115 | 116 | #endregion 117 | 118 | #region Constructors-and-Factories 119 | 120 | /// 121 | /// Logging settings. 122 | /// 123 | public LoggingSettings() 124 | { 125 | 126 | } 127 | 128 | #endregion 129 | 130 | #region Internal-Methods 131 | 132 | /// 133 | /// Emit a log message. 134 | /// 135 | /// Severity. 136 | /// Message. 137 | public void Log(SeverityEnum sev, string msg) 138 | { 139 | if (Enable 140 | && (int)sev >= MinimumSeverity 141 | && !String.IsNullOrEmpty(msg)) 142 | { 143 | Logger?.Invoke(sev, Header + msg); 144 | } 145 | } 146 | 147 | #endregion 148 | 149 | #region Private-Methods 150 | 151 | #endregion 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/LiteGraph/Node.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.Specialized; 6 | 7 | /// 8 | /// Node in the graph. 9 | /// 10 | public class Node 11 | { 12 | #region Public-Members 13 | 14 | /// 15 | /// Tenant GUID. 16 | /// 17 | public Guid TenantGUID { get; set; } = Guid.NewGuid(); 18 | 19 | /// 20 | /// Globally-unique identifier. 21 | /// 22 | public Guid GUID { get; set; } = Guid.NewGuid(); 23 | 24 | /// 25 | /// Globally-unique identifier for the graph. 26 | /// 27 | public Guid GraphGUID { get; set; } = Guid.NewGuid(); 28 | 29 | /// 30 | /// Name. 31 | /// 32 | public string Name { get; set; } = null; 33 | 34 | /// 35 | /// Number of edges connected to this node. 36 | /// 37 | public int? EdgesIn 38 | { 39 | get 40 | { 41 | return _EdgesIn; 42 | } 43 | set 44 | { 45 | if (value != null && value.Value < 0) throw new ArgumentOutOfRangeException(nameof(EdgesIn)); 46 | _EdgesIn = value; 47 | } 48 | } 49 | 50 | /// 51 | /// Number of edges connected from this node. 52 | /// 53 | public int? EdgesOut 54 | { 55 | get 56 | { 57 | return _EdgesOut; 58 | } 59 | set 60 | { 61 | if (value != null && value.Value < 0) throw new ArgumentOutOfRangeException(nameof(EdgesOut)); 62 | _EdgesOut = value; 63 | } 64 | } 65 | 66 | /// 67 | /// Number of total edges to or from this node. 68 | /// 69 | public int? EdgesTotal 70 | { 71 | get 72 | { 73 | int? total = null; 74 | if (EdgesIn != null || EdgesOut != null) total = 0; 75 | if (EdgesIn != null) total += EdgesIn.Value; 76 | if (EdgesOut != null) total += EdgesOut.Value; 77 | return total; 78 | } 79 | } 80 | 81 | /// 82 | /// Timestamp from creation, in UTC. 83 | /// 84 | public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; 85 | 86 | /// 87 | /// Timestamp from last update, in UTC. 88 | /// 89 | public DateTime LastUpdateUtc { get; set; } = DateTime.UtcNow; 90 | 91 | /// 92 | /// Labels. 93 | /// 94 | public List Labels { get; set; } = null; 95 | 96 | /// 97 | /// Tags. 98 | /// 99 | public NameValueCollection Tags { get; set; } = null; 100 | 101 | /// 102 | /// Object data. 103 | /// 104 | public object Data { get; set; } = null; 105 | 106 | /// 107 | /// Vectors. 108 | /// 109 | public List Vectors { get; set; } = null; 110 | 111 | #endregion 112 | 113 | #region Private-Members 114 | 115 | private int? _EdgesIn = null; 116 | private int? _EdgesOut = null; 117 | 118 | #endregion 119 | 120 | #region Constructors-and-Factories 121 | 122 | /// 123 | /// Instantiate the object. 124 | /// 125 | public Node() 126 | { 127 | 128 | } 129 | 130 | #endregion 131 | 132 | #region Public-Methods 133 | 134 | #endregion 135 | 136 | #region Private-Methods 137 | 138 | #endregion 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/LiteGraph/RouteDetail.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | /// 8 | /// Total cost and ordered list of edges between two nodes. 9 | /// 10 | public class RouteDetail 11 | { 12 | #region Public-Members 13 | 14 | /// 15 | /// Total cost of the route. 16 | /// 17 | public int TotalCost 18 | { 19 | get 20 | { 21 | if (_Edges == null || _Edges.Count < 1) return 0; 22 | return _Edges.Sum(e => e.Cost); 23 | } 24 | } 25 | 26 | /// 27 | /// Edges. 28 | /// 29 | public List Edges 30 | { 31 | get 32 | { 33 | return _Edges; 34 | } 35 | set 36 | { 37 | if (value == null) value = new List(); 38 | _Edges = value; 39 | } 40 | } 41 | 42 | #endregion 43 | 44 | #region Private-Members 45 | 46 | private List _Edges = new List(); 47 | 48 | #endregion 49 | 50 | #region Constructors-and-Factories 51 | 52 | /// 53 | /// Instantiate the object. 54 | /// 55 | public RouteDetail() 56 | { 57 | 58 | } 59 | 60 | #endregion 61 | 62 | #region Public-Methods 63 | 64 | #endregion 65 | 66 | #region Private-Methods 67 | 68 | #endregion 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/LiteGraph/SearchRequest.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using ExpressionTree; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Linq; 8 | 9 | /// 10 | /// Search request. 11 | /// 12 | public class SearchRequest 13 | { 14 | #region Public-Members 15 | 16 | /// 17 | /// Tenant GUID. 18 | /// 19 | public Guid TenantGUID { get; set; } = default(Guid); 20 | 21 | /// 22 | /// Graph GUID. 23 | /// 24 | public Guid GraphGUID { get; set; } = default(Guid); 25 | 26 | /// 27 | /// Ordering. 28 | /// 29 | public EnumerationOrderEnum Ordering { get; set; } = EnumerationOrderEnum.CreatedDescending; 30 | 31 | /// 32 | /// Maximum number of results to retrieve. 33 | /// 34 | public int MaxResults 35 | { 36 | get 37 | { 38 | return _MaxResults; 39 | } 40 | set 41 | { 42 | if (value < 1) throw new ArgumentOutOfRangeException(nameof(MaxResults)); 43 | _MaxResults = value; 44 | } 45 | } 46 | 47 | /// 48 | /// The number of records to skip. 49 | /// 50 | public int Skip 51 | { 52 | get 53 | { 54 | return _Skip; 55 | } 56 | set 57 | { 58 | if (value < 0) throw new ArgumentOutOfRangeException(nameof(Skip)); 59 | _Skip = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Search labels. 65 | /// 66 | public List Labels 67 | { 68 | get 69 | { 70 | return _Labels; 71 | } 72 | set 73 | { 74 | if (value == null) value = new List(); 75 | _Labels = value; 76 | } 77 | } 78 | 79 | /// 80 | /// Search tags. 81 | /// 82 | public NameValueCollection Tags 83 | { 84 | get 85 | { 86 | return _Tags; 87 | } 88 | set 89 | { 90 | if (value == null) value = new NameValueCollection(StringComparer.InvariantCultureIgnoreCase); 91 | _Tags = value; 92 | } 93 | } 94 | 95 | /// 96 | /// Expression. 97 | /// 98 | public Expr Expr { get; set; } = null; 99 | 100 | #endregion 101 | 102 | #region Private-Members 103 | 104 | private int _MaxResults = 100; 105 | private int _Skip = 0; 106 | private List _Labels = new List(); 107 | private NameValueCollection _Tags = new NameValueCollection(StringComparer.InvariantCultureIgnoreCase); 108 | 109 | #endregion 110 | 111 | #region Constructors-and-Factories 112 | 113 | /// 114 | /// Instantiate the object. 115 | /// 116 | public SearchRequest() 117 | { 118 | 119 | } 120 | 121 | #endregion 122 | 123 | #region Public-Methods 124 | 125 | #endregion 126 | 127 | #region Private-Methods 128 | 129 | #endregion 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/LiteGraph/SearchResult.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | /// 8 | /// Search result. 9 | /// 10 | public class SearchResult 11 | { 12 | #region Public-Members 13 | 14 | /// 15 | /// Graphs. 16 | /// 17 | public List Graphs { get; set; } = null; 18 | 19 | /// 20 | /// Nodes. 21 | /// 22 | public List Nodes { get; set; } = null; 23 | 24 | /// 25 | /// Edges. 26 | /// 27 | public List Edges { get; set; } = null; 28 | 29 | #endregion 30 | 31 | #region Private-Members 32 | 33 | #endregion 34 | 35 | #region Constructors-and-Factories 36 | 37 | /// 38 | /// Instantiate the object. 39 | /// 40 | public SearchResult() 41 | { 42 | 43 | } 44 | 45 | #endregion 46 | 47 | #region Public-Methods 48 | 49 | #endregion 50 | 51 | #region Private-Methods 52 | 53 | #endregion 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/LiteGraph/SearchTypeEnum.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | /// 10 | /// Search type. 11 | /// 12 | public enum SearchTypeEnum 13 | { 14 | /// 15 | /// Depth first search. 16 | /// 17 | DepthFirstSearch 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/LiteGraph/Serialization/ISerializer.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph.Serialization 2 | { 3 | using System; 4 | 5 | /// 6 | /// Serializer interface. 7 | /// 8 | public interface ISerializer 9 | { 10 | /// 11 | /// Copy an object. 12 | /// 13 | /// Type. 14 | /// Object. 15 | /// Copied object. 16 | T CopyObject(T obj); 17 | 18 | /// 19 | /// Serialize an object to JSON. 20 | /// 21 | /// Object. 22 | /// Enable or disable pretty formatting. 23 | /// 24 | string SerializeJson(object obj, bool pretty = false); 25 | 26 | /// 27 | /// Deserialize an object to JSON. 28 | /// 29 | /// Type. 30 | /// JSON. 31 | /// Instance. 32 | T DeserializeJson(string json); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/LiteGraph/SeverityEnum.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | /// 4 | /// Message severity. 5 | /// 6 | public enum SeverityEnum 7 | { 8 | /// 9 | /// Debug messages. 10 | /// 11 | Debug = 0, 12 | /// 13 | /// Informational messages. 14 | /// 15 | Info = 1, 16 | /// 17 | /// Warning messages. 18 | /// 19 | Warn = 2, 20 | /// 21 | /// Error messages. 22 | /// 23 | Error = 3, 24 | /// 25 | /// Alert messages. 26 | /// 27 | Alert = 4, 28 | /// 29 | /// Critical messages. 30 | /// 31 | Critical = 5, 32 | /// 33 | /// Emergency messages. 34 | /// 35 | Emergency = 6 36 | } 37 | } -------------------------------------------------------------------------------- /src/LiteGraph/StorageSettings.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using LiteGraph.Helpers; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | 8 | /// 9 | /// Storage settings. 10 | /// 11 | public class StorageSettings 12 | { 13 | #region Public-Members 14 | 15 | /// 16 | /// Backups directory. 17 | /// 18 | public string BackupsDirectory 19 | { 20 | get 21 | { 22 | return _BackupsDirectory; 23 | } 24 | set 25 | { 26 | try 27 | { 28 | Console.WriteLine($"BackupsDirectory setter called with: '{value}'"); 29 | if (String.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(BackupsDirectory)); 30 | 31 | Console.WriteLine($"About to call NormalizeDirectory with: '{value}'"); 32 | _BackupsDirectory = FileHelpers.NormalizeDirectory(value); 33 | Console.WriteLine($"NormalizeDirectory returned: '{_BackupsDirectory}'"); 34 | 35 | if (!Directory.Exists(_BackupsDirectory)) 36 | { 37 | Console.WriteLine($"Creating directory: '{_BackupsDirectory}'"); 38 | Directory.CreateDirectory(_BackupsDirectory); 39 | } 40 | } 41 | catch (Exception ex) 42 | { 43 | Console.WriteLine($"Exception in BackupsDirectory setter: {ex.GetType().Name}: {ex.Message}"); 44 | Console.WriteLine($"Value was: '{value}'"); 45 | throw; 46 | } 47 | } 48 | } 49 | 50 | #endregion 51 | 52 | #region Private-Members 53 | 54 | private string _BackupsDirectory = "./backups/"; 55 | 56 | #endregion 57 | 58 | #region Constructors-and-Factories 59 | 60 | /// 61 | /// Instantiate. 62 | /// 63 | public StorageSettings() 64 | { 65 | 66 | } 67 | 68 | #endregion 69 | 70 | #region Public-Methods 71 | 72 | #endregion 73 | 74 | #region Private-Methods 75 | 76 | #endregion 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/LiteGraph/SyslogServer.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | 5 | /// 6 | /// Syslog server settings. 7 | /// 8 | public class SyslogServer 9 | { 10 | #region Public-Members 11 | 12 | /// 13 | /// Hostname. 14 | /// 15 | public string Hostname 16 | { 17 | get 18 | { 19 | return _Hostname; 20 | } 21 | set 22 | { 23 | if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Hostname)); 24 | _Hostname = value; 25 | } 26 | } 27 | 28 | /// 29 | /// Port. 30 | /// 31 | public int Port 32 | { 33 | get 34 | { 35 | return _Port; 36 | } 37 | set 38 | { 39 | if (value < 0 || value > 65535) throw new ArgumentOutOfRangeException(nameof(Port)); 40 | _Port = value; 41 | } 42 | } 43 | 44 | #endregion 45 | 46 | #region Private-Members 47 | 48 | private string _Hostname = "127.0.0.1"; 49 | private int _Port = 514; 50 | 51 | #endregion 52 | 53 | #region Constructors-and-Factories 54 | 55 | /// 56 | /// Instantiate. 57 | /// 58 | public SyslogServer() 59 | { 60 | 61 | } 62 | 63 | /// 64 | /// Instantiate. 65 | /// 66 | /// Hostname. 67 | /// Port. 68 | public SyslogServer(string hostname, int port) 69 | { 70 | if (string.IsNullOrEmpty(hostname)) throw new ArgumentNullException(nameof(hostname)); 71 | 72 | _Hostname = hostname; 73 | _Port = port; 74 | } 75 | 76 | #endregion 77 | 78 | #region Public-Members 79 | 80 | #endregion 81 | 82 | #region Private-Members 83 | 84 | #endregion 85 | } 86 | } -------------------------------------------------------------------------------- /src/LiteGraph/TenantMetadata.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Security.Cryptography; 7 | using System.Text; 8 | using System.Text.Json.Serialization; 9 | using System.Threading.Tasks; 10 | 11 | /// 12 | /// Tenant metadata. 13 | /// 14 | public class TenantMetadata 15 | { 16 | #region Public-Members 17 | 18 | /// 19 | /// GUID. 20 | /// 21 | public Guid GUID { get; set; } = Guid.NewGuid(); 22 | 23 | /// 24 | /// Name. 25 | /// 26 | public string Name { get; set; } = null; 27 | 28 | /// 29 | /// Active. 30 | /// 31 | public bool Active { get; set; } = true; 32 | 33 | /// 34 | /// Created timestamp, in UTC timestamp. 35 | /// 36 | public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; 37 | 38 | /// 39 | /// Timestamp from last update, in UTC. 40 | /// 41 | public DateTime LastUpdateUtc { get; set; } = DateTime.UtcNow; 42 | 43 | #endregion 44 | 45 | #region Private-Members 46 | 47 | #endregion 48 | 49 | #region Constructors-and-Factories 50 | 51 | /// 52 | /// Instantiate. 53 | /// 54 | public TenantMetadata() 55 | { 56 | 57 | } 58 | 59 | #endregion 60 | 61 | #region Public-Methods 62 | 63 | #endregion 64 | 65 | #region Private-Methods 66 | 67 | #endregion 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/LiteGraph/UserMaster.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using LiteGraph.Serialization; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text.Json.Serialization; 7 | 8 | /// 9 | /// User. 10 | /// 11 | public class UserMaster 12 | { 13 | #region Public-Members 14 | 15 | /// 16 | /// GUID. 17 | /// 18 | public Guid GUID { get; set; } = Guid.NewGuid(); 19 | 20 | /// 21 | /// Tenant GUID. 22 | /// 23 | public Guid TenantGUID { get; set; } = Guid.NewGuid(); 24 | 25 | /// 26 | /// First name. 27 | /// 28 | public string FirstName { get; set; } = string.Empty; 29 | 30 | /// 31 | /// Last name. 32 | /// 33 | public string LastName { get; set; } = string.Empty; 34 | 35 | /// 36 | /// Email. 37 | /// 38 | public string Email { get; set; } = string.Empty; 39 | 40 | /// 41 | /// Password. 42 | /// 43 | public string Password { get; set; } = string.Empty; 44 | 45 | /// 46 | /// Active. 47 | /// 48 | public bool Active { get; set; } = true; 49 | 50 | /// 51 | /// Creation time, in UTC. 52 | /// 53 | public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; 54 | 55 | /// 56 | /// Timestamp from last update, in UTC. 57 | /// 58 | public DateTime LastUpdateUtc { get; set; } = DateTime.UtcNow; 59 | 60 | #endregion 61 | 62 | #region Private-Members 63 | 64 | #endregion 65 | 66 | #region Constructors-and-Factories 67 | 68 | /// 69 | /// Instantiate. 70 | /// 71 | public UserMaster() 72 | { 73 | 74 | } 75 | 76 | /// 77 | /// Redact. 78 | /// 79 | /// Serializer. 80 | /// User. 81 | /// User. 82 | public static UserMaster Redact(ISerializer serializer, UserMaster user) 83 | { 84 | if (user == null) return null; 85 | UserMaster redacted = serializer.CopyObject(user); 86 | 87 | if (!String.IsNullOrEmpty(user.Password)) 88 | { 89 | int numAsterisks = user.Password.Length - 4; 90 | if (user.Password.Length < 5) user.Password = "****"; 91 | else 92 | { 93 | string password = ""; 94 | for (int i = 0; i < numAsterisks; i++) password += "*"; 95 | password += user.Password.Substring((user.Password.Length - 4), 4); 96 | redacted.Password = password; 97 | } 98 | } 99 | 100 | return redacted; 101 | } 102 | 103 | #endregion 104 | 105 | #region Public-Methods 106 | 107 | #endregion 108 | 109 | #region Private-Methods 110 | 111 | #endregion 112 | } 113 | } -------------------------------------------------------------------------------- /src/LiteGraph/VectorMetadata.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.Specialized; 6 | using System.Linq; 7 | using System.Security.Cryptography; 8 | using System.Text.Json.Serialization; 9 | 10 | /// 11 | /// Vector metadata. 12 | /// 13 | public class VectorMetadata 14 | { 15 | #region Public-Members 16 | 17 | /// 18 | /// GUID. 19 | /// 20 | public Guid GUID { get; set; } = Guid.NewGuid(); 21 | 22 | /// 23 | /// Tenant GUID. 24 | /// 25 | public Guid TenantGUID { get; set; } = Guid.NewGuid(); 26 | 27 | /// 28 | /// Graph GUID. 29 | /// 30 | public Guid GraphGUID { get; set; } = default(Guid); 31 | 32 | /// 33 | /// Node GUID. 34 | /// 35 | public Guid? NodeGUID { get; set; } = null; 36 | 37 | /// 38 | /// Edge GUID. 39 | /// 40 | public Guid? EdgeGUID { get; set; } = null; 41 | 42 | /// 43 | /// Model. 44 | /// 45 | public string Model { get; set; } = null; 46 | 47 | /// 48 | /// Dimensionality. 49 | /// 50 | public int Dimensionality 51 | { 52 | get 53 | { 54 | return _Dimensionality; 55 | } 56 | set 57 | { 58 | if (value < 0) throw new ArgumentOutOfRangeException(nameof(Dimensionality)); 59 | _Dimensionality = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Content. 65 | /// 66 | public string Content { get; set; } = string.Empty; 67 | 68 | /// 69 | /// Vectors. 70 | /// 71 | public List Vectors { get; set; } = null; 72 | 73 | /// 74 | /// Creation timestamp, in UTC. 75 | /// 76 | public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; 77 | 78 | /// 79 | /// Timestamp from last update, in UTC. 80 | /// 81 | public DateTime LastUpdateUtc { get; set; } = DateTime.UtcNow; 82 | 83 | #endregion 84 | 85 | #region Private-Members 86 | 87 | private int _Dimensionality = 0; 88 | 89 | #endregion 90 | 91 | #region Constructors-and-Factories 92 | 93 | /// 94 | /// Instantiate. 95 | /// 96 | public VectorMetadata() 97 | { 98 | 99 | } 100 | 101 | /// 102 | /// Create a list of vector metadata from a list of floats. 103 | /// 104 | /// Tenant GUID. 105 | /// Graph GUID. 106 | /// Node GUID. 107 | /// Edge GUID. 108 | /// Embeddings. 109 | /// List of vector metadata. 110 | public static List FromFloatsList(Guid tenantGuid, Guid graphGuid, Guid? nodeGuid, Guid? edgeGuid, List> embeddings) 111 | { 112 | if (embeddings == null) return null; 113 | if (embeddings.Count < 1) return new List(); 114 | 115 | List ret = new List(); 116 | 117 | foreach (List floats in embeddings) 118 | { 119 | ret.Add(new VectorMetadata 120 | { 121 | TenantGUID = tenantGuid, 122 | GraphGUID = graphGuid, 123 | NodeGUID = nodeGuid, 124 | EdgeGUID = edgeGuid, 125 | Vectors = floats 126 | }); 127 | } 128 | 129 | return ret; 130 | } 131 | 132 | /// 133 | /// Create a list float lists for all vector metadata entries. 134 | /// 135 | /// Vectors. 136 | /// Labels. 137 | public static List> ToListString(List vectors) 138 | { 139 | if (vectors == null) return null; 140 | if (vectors.Count < 1) return new List>(); 141 | 142 | List> ret = new List>(); 143 | foreach (VectorMetadata vector in vectors) 144 | { 145 | ret.Add(vector.Vectors); 146 | } 147 | 148 | return ret; 149 | } 150 | 151 | #endregion 152 | 153 | #region Public-Methods 154 | 155 | #endregion 156 | 157 | #region Private-Methods 158 | 159 | #endregion 160 | }} -------------------------------------------------------------------------------- /src/LiteGraph/VectorSearchDomainEnum.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | /// 4 | /// Vector search domain. 5 | /// 6 | public enum VectorSearchDomainEnum 7 | { 8 | /// 9 | /// Graph. 10 | /// 11 | Graph, 12 | /// 13 | /// Node. 14 | /// 15 | Node, 16 | /// 17 | /// Edge. 18 | /// 19 | Edge 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/LiteGraph/VectorSearchRequest.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using ExpressionTree; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Collections.Specialized; 7 | using System.Linq; 8 | 9 | /// 10 | /// Vector search request. 11 | /// 12 | public class VectorSearchRequest 13 | { 14 | #region Public-Members 15 | 16 | /// 17 | /// Tenant GUID. 18 | /// 19 | public Guid TenantGUID { get; set; } = default(Guid); 20 | 21 | /// 22 | /// Graph GUID. 23 | /// 24 | public Guid? GraphGUID { get; set; } = null; 25 | 26 | /// 27 | /// Vector search domain. 28 | /// 29 | public VectorSearchDomainEnum Domain { get; set; } = VectorSearchDomainEnum.Node; 30 | 31 | /// 32 | /// Vector search type. 33 | /// 34 | public VectorSearchTypeEnum SearchType { get; set; } = VectorSearchTypeEnum.CosineSimilarity; 35 | 36 | /// 37 | /// Search labels. 38 | /// 39 | public List Labels 40 | { 41 | get 42 | { 43 | return _Labels; 44 | } 45 | set 46 | { 47 | if (value == null) value = new List(); 48 | _Labels = value; 49 | } 50 | } 51 | 52 | /// 53 | /// Search tags. 54 | /// 55 | public NameValueCollection Tags 56 | { 57 | get 58 | { 59 | return _Tags; 60 | } 61 | set 62 | { 63 | if (value == null) value = new NameValueCollection(StringComparer.InvariantCultureIgnoreCase); 64 | _Tags = value; 65 | } 66 | } 67 | 68 | /// 69 | /// Expression. 70 | /// 71 | public Expr Expr { get; set; } = null; 72 | 73 | /// 74 | /// Embeddings. 75 | /// 76 | public List Embeddings { get; set; } = null; 77 | 78 | #endregion 79 | 80 | #region Private-Members 81 | 82 | private List _Labels = new List(); 83 | private NameValueCollection _Tags = new NameValueCollection(StringComparer.InvariantCultureIgnoreCase); 84 | private List _Embeddings = new List(); 85 | 86 | #endregion 87 | 88 | #region Constructors-and-Factories 89 | 90 | /// 91 | /// Instantiate the object. 92 | /// 93 | public VectorSearchRequest() 94 | { 95 | 96 | } 97 | 98 | #endregion 99 | 100 | #region Public-Methods 101 | 102 | #endregion 103 | 104 | #region Private-Methods 105 | 106 | #endregion 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/LiteGraph/VectorSearchResult.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | /// 8 | /// Vector search result. 9 | /// 10 | public class VectorSearchResult 11 | { 12 | #region Public-Members 13 | 14 | /// 15 | /// Score. 16 | /// 17 | public float? Score { get; set; } = null; 18 | 19 | /// 20 | /// Distance. 21 | /// 22 | public float? Distance { get; set; } = null; 23 | 24 | /// 25 | /// Inner product. 26 | /// 27 | public float? InnerProduct { get; set; } = null; 28 | 29 | /// 30 | /// Graph. 31 | /// 32 | public Graph Graph { get; set; } = null; 33 | 34 | /// 35 | /// Node. 36 | /// 37 | public Node Node { get; set; } = null; 38 | 39 | /// 40 | /// Edge. 41 | /// 42 | public Edge Edge { get; set; } = null; 43 | 44 | #endregion 45 | 46 | #region Private-Members 47 | 48 | #endregion 49 | 50 | #region Constructors-and-Factories 51 | 52 | /// 53 | /// Instantiate the object. 54 | /// 55 | public VectorSearchResult() 56 | { 57 | 58 | } 59 | 60 | #endregion 61 | 62 | #region Public-Methods 63 | 64 | #endregion 65 | 66 | #region Private-Methods 67 | 68 | #endregion 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/LiteGraph/VectorSearchTypeEnum.cs: -------------------------------------------------------------------------------- 1 | namespace LiteGraph 2 | { 3 | /// 4 | /// Vector search type. 5 | /// 6 | public enum VectorSearchTypeEnum 7 | { 8 | /// 9 | /// Cosine distance, the inverse of cosine similarity. 10 | /// 11 | CosineDistance, 12 | /// 13 | /// Cosine similarity, the inverse of cosine distance. 14 | /// 15 | CosineSimilarity, 16 | /// 17 | /// Euclidian distance, also known as L2 distance, the inverse of Euclidian similarity or L2 similarity. 18 | /// 19 | EuclidianDistance, 20 | /// 21 | /// Euclidian simmilarity, also known as L2 similarity, the inverse of Euclidian distance or L2 distance. 22 | /// 23 | EuclidianSimilarity, 24 | /// 25 | /// Dot product similarity. Equivalent to cosine similarity when vectors are normalized, that is, magnitudes are all 1. 26 | /// 27 | DotProduct 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/LiteGraph/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/src/LiteGraph/assets/favicon.ico -------------------------------------------------------------------------------- /src/LiteGraph/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/litegraphdb/litegraph/3add6e1b65c8bdb9374397b18ca20f1a0b8e5570/src/LiteGraph/assets/favicon.png -------------------------------------------------------------------------------- /src/Test.RamDatabase/Test.RamDatabase.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Test.RamDatabase/TestClasses.cs: -------------------------------------------------------------------------------- 1 | namespace Test.RamDatabase 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. 10 | 11 | public class GraphMetadata 12 | { 13 | public string Description { get; set; } = null; 14 | } 15 | 16 | public class Person 17 | { 18 | public string Name { get; set; } = null; 19 | public bool IsHandsome { get; set; } = true; 20 | public int Age { get; set; } = 0; 21 | public Hobby Hobby { get; set; } = null; 22 | public override string ToString() 23 | { 24 | return "Name: " + Name + " handsome: " + IsHandsome + " age: " + Age; 25 | } 26 | } 27 | 28 | public class Hobby 29 | { 30 | public string Name { get; set; } = null; 31 | public int HoursPerWeek { get; set; } = 0; 32 | public override string ToString() 33 | { 34 | return "Name: " + Name + " hours/week: " + HoursPerWeek; 35 | } 36 | } 37 | 38 | public class ISP 39 | { 40 | public string Name { get; set; } = null; 41 | public int Mbps { get; set; } = 100; 42 | } 43 | 44 | public class Internet 45 | { 46 | public string Name { get; } = "Internet"; 47 | } 48 | 49 | public class HostingProvider 50 | { 51 | public string Name { get; set; } = null; 52 | } 53 | 54 | public class Application 55 | { 56 | public string Name { get; set; } = null; 57 | } 58 | 59 | #pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. 60 | } 61 | -------------------------------------------------------------------------------- /src/Test/Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Always 19 | 20 | 21 | Always 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Test/TestClasses.cs: -------------------------------------------------------------------------------- 1 | namespace Test 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | public class GraphMetadata 10 | { 11 | public string Description { get; set; } = null; 12 | } 13 | 14 | public class Person 15 | { 16 | public string Name { get; set; } = null; 17 | public bool IsHandsome { get; set; } = true; 18 | public int Age { get; set; } = 0; 19 | public Hobby Hobby { get; set; } = null; 20 | public override string ToString() 21 | { 22 | return "Name: " + Name + " handsome: " + IsHandsome + " age: " + Age; 23 | } 24 | } 25 | 26 | public class Hobby 27 | { 28 | public string Name { get; set; } = null; 29 | public int HoursPerWeek { get; set; } = 0; 30 | public override string ToString() 31 | { 32 | return "Name: " + Name + " hours/week: " + HoursPerWeek; 33 | } 34 | } 35 | 36 | public class ISP 37 | { 38 | public string Name { get; set; } = null; 39 | public int Mbps { get; set; } = 100; 40 | } 41 | 42 | public class Internet 43 | { 44 | public string Name { get; } = "Internet"; 45 | } 46 | 47 | public class HostingProvider 48 | { 49 | public string Name { get; set; } = null; 50 | } 51 | 52 | public class Application 53 | { 54 | public string Name { get; set; } = null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Test/clean.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | del /q litegraph.db 3 | @echo on 4 | -------------------------------------------------------------------------------- /src/Test/clean.sh: -------------------------------------------------------------------------------- 1 | rm -f litegraph.db 2 | --------------------------------------------------------------------------------