Skip to content

gordon-matt/Queryz

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Donate

Logo

Intro

Queryz is a report building tool that allows you to quickly connect to databases and run queries against them, while giving you the option to download the results as an xlsx file or a delimited file, such as a CSV.

Getting started

  1. Add a reference to the Queryz NuGet package (coming soon - for now, just reference the project in this repo).

  2. Ensure your DbContext inherits from QueryzDbContext<ApplicationUser, ApplicationRole>:

public class ApplicationDbContext : QueryzDbContext<ApplicationUser, ApplicationRole>
{
    public ApplicationDbContext(DbContextOptions<QueryzDbContext<ApplicationUser, ApplicationRole>> options)
        : base(options)
    {
    }
}
  1. Create an IDbContextFactory
public class ApplicationDbContextFactory : IDbContextFactory
{
    // see Query.Demo project for example implementation
}
  1. Setup your Program.cs:
builder.Services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
{
    options.SignIn.RequireConfirmedAccount = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders()
.AddDefaultUI();

builder.Services.AddDistributedMemoryCache(); // Required for session state
builder.Services.AddSession();

builder.Services
    .AddControllersWithViews()
    .AddNewtonsoftJson() // Currently only working with this. The model binding wouldn't work otherwise. It's on the TODO list to fix.
    .AddOData((options, serviceProvider) =>
    {
        options.Select().Expand().Filter().OrderBy().SetMaxTop(null).Count();
        var registrars = serviceProvider.GetRequiredService<IEnumerable<IODataRegistrar>>();
        foreach (var registrar in registrars)
        {
            registrar.Register(options);
        }
    })
    .AddQueryz<ApplicationUser, ApplicationRole>(builder.Configuration, connectionString)
    .AddRazorRuntimeCompilation();

// Override the default IDbContextFactory registered when calling AddQueryz()
builder.Services.AddSingleton<IDbContextFactory, ApplicationDbContextFactory>();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}")
    .WithStaticAssets(); // Important

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new CompositeFileProvider(
        new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath, "wwwroot")),
        new EmbeddedFileProvider(
            typeof(IQueryzAssemblyMarker).Assembly,
            baseNamespace: "Queryz.wwwroot"))
});

app.UseQueryz();

// If you are commercial, then set your own commercial license here.. or else change the name passed into SetNonCommercialPersonal().
ExcelPackage.License.SetNonCommercialPersonal("Queryz");

app.Run();

Queryz expects there to be 3 different roles available:

public static class QueryzConstants
{
    public static class Roles
    {
        public const string Administrators = "Administrators";
        public const string ReportBuilderEditors = "Report Builder Editors";
        public const string ReportBuilderUsers = "Report Builder Users";
    }
}

Customization in appsettings.json:

"Queryz": {
  "Layout": "~/Views/Shared/_QueryzLayout.cshtml", // Set your own layout or use null for the default layout from the library.
  "GridPageSize": 10,
  "AppName": "DemoApp", // Only used if Layout is set to null
  "FooterText": "&copy; 2025 - DemoApp" // Only used if Layout is set to null
}

See the Query.Demo project in this repo for a full working example, including how to seed your database with the aforementioned roles.

Usage

The main screen with many Reports under each Report Group. You can make as many groups as you like - one for each of your clients and/or one for each internal department and so forth.

Main Screen

Setting up a data source:

Data Source

If you have enum values in your report and want them to be displayed as text, you can setup an enumeration:

Enum Setup

.. which will then allow you to select that enumeration when choosing columns:

Enum column selection

.. and the end result will be as follows:

Enum result

There are also transform functions available for making JSON columns easier to read or for converting the timezone of a date/time field:

Other Functions

The convert timezone function will work based on the timezone you've setup for your report group (if any):

Report Group Setup

You can create your own transforms by implementing ITransformFunction and registering it with dependency injection:

public class ConvertTimeZoneFunction : ITransformFunction
{
    public string Name => "Convert Time Zone";

    public dynamic Transform(dynamic value, Report report)
    {
        if (value is not DateTime) return value;

        if (value == null) return value;

        if (report == null || string.IsNullOrEmpty(report.Group.TimeZoneId)) return value;

        var timeZone = TZConvert.GetTimeZoneInfo(report.Group.TimeZoneId);

        return TimeZoneInfo.ConvertTimeFromUtc(value, timeZone);
    }
}

services.AddSingleton<ITransformFunction, ConvertTimeZoneFunction>();

You can setup default query filters, including hidden filters:

QueryBuilder - Setup

Notice the open/closed eye icons. If you setup a filter here as being hidden, it will still be applied when the report is run, but not show for the user when they select other filters. This is useful when there is some data they should not see (other tenants, other users, confidential records, etc). The above example is in design mode and the screenshot below is in "run report" mode:

QueryBuilder - Run

Donate

If you find this project helpful, consider buying me a cup of coffee.

PayPal

Crypto Wallet Address
Bitcoin 1EeDfbcqoEaz6bbcWsymwPbYv4uyEaZ3Lp
Ethereum 0x277552efd6ea9ca9052a249e781abf1719ea9414
Litecoin LRUP8hukWGXRrcPK6Tm7iUp9vPvnNNt3uz

gordon-matt

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published