mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
update, remove the has_attachment field from the envelopes table.
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use arrow::array::{BooleanArray, Int32Array, Int64Array, ListBuilder, StringBuilder, UInt64Array};
|
use arrow::array::{Int32Array, Int64Array, ListBuilder, StringBuilder, UInt64Array};
|
||||||
use arrow::datatypes::{DataType, Field, Schema};
|
use arrow::datatypes::{DataType, Field, Schema};
|
||||||
use arrow::record_batch::RecordBatch;
|
use arrow::record_batch::RecordBatch;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -57,7 +57,6 @@ pub fn build_record_batch(items: &[Envelope]) -> RecordBatch {
|
|||||||
Field::new("size_bytes", DataType::UInt64, true),
|
Field::new("size_bytes", DataType::UInt64, true),
|
||||||
Field::new("thread_id", DataType::Utf8, true),
|
Field::new("thread_id", DataType::Utf8, true),
|
||||||
Field::new("message_id", DataType::Utf8, true),
|
Field::new("message_id", DataType::Utf8, true),
|
||||||
Field::new("has_attachment", DataType::Boolean, false),
|
|
||||||
Field::new("attachment_count", DataType::Int32, false),
|
Field::new("attachment_count", DataType::Int32, false),
|
||||||
Field::new("regular_attachment_count", DataType::Int32, false),
|
Field::new("regular_attachment_count", DataType::Int32, false),
|
||||||
Field::new(
|
Field::new(
|
||||||
@@ -87,7 +86,6 @@ pub fn build_record_batch(items: &[Envelope]) -> RecordBatch {
|
|||||||
let mut size_b = UInt64Array::builder(capacity);
|
let mut size_b = UInt64Array::builder(capacity);
|
||||||
let mut thread_id_b = StringBuilder::with_capacity(capacity, capacity * 20);
|
let mut thread_id_b = StringBuilder::with_capacity(capacity, capacity * 20);
|
||||||
let mut msg_id_b = StringBuilder::with_capacity(capacity, capacity * 30);
|
let mut msg_id_b = StringBuilder::with_capacity(capacity, capacity * 30);
|
||||||
let mut has_att_b = BooleanArray::builder(capacity);
|
|
||||||
let mut att_count_b = Int32Array::builder(capacity);
|
let mut att_count_b = Int32Array::builder(capacity);
|
||||||
let mut regular_att_count_b = Int32Array::builder(capacity);
|
let mut regular_att_count_b = Int32Array::builder(capacity);
|
||||||
let mut tags_b = ListBuilder::new(StringBuilder::new());
|
let mut tags_b = ListBuilder::new(StringBuilder::new());
|
||||||
@@ -119,7 +117,6 @@ pub fn build_record_batch(items: &[Envelope]) -> RecordBatch {
|
|||||||
size_b.append_value(e.size as u64);
|
size_b.append_value(e.size as u64);
|
||||||
thread_id_b.append_value(&e.thread_id);
|
thread_id_b.append_value(&e.thread_id);
|
||||||
msg_id_b.append_value(&e.message_id);
|
msg_id_b.append_value(&e.message_id);
|
||||||
has_att_b.append_value(e.regular_attachment_count > 0);
|
|
||||||
att_count_b.append_value(e.attachment_count as i32);
|
att_count_b.append_value(e.attachment_count as i32);
|
||||||
regular_att_count_b.append_value(e.regular_attachment_count as i32);
|
regular_att_count_b.append_value(e.regular_attachment_count as i32);
|
||||||
tags_b.append(true);
|
tags_b.append(true);
|
||||||
@@ -145,7 +142,6 @@ pub fn build_record_batch(items: &[Envelope]) -> RecordBatch {
|
|||||||
Arc::new(size_b.finish()),
|
Arc::new(size_b.finish()),
|
||||||
Arc::new(thread_id_b.finish()),
|
Arc::new(thread_id_b.finish()),
|
||||||
Arc::new(msg_id_b.finish()),
|
Arc::new(msg_id_b.finish()),
|
||||||
Arc::new(has_att_b.finish()),
|
|
||||||
Arc::new(att_count_b.finish()),
|
Arc::new(att_count_b.finish()),
|
||||||
Arc::new(regular_att_count_b.finish()),
|
Arc::new(regular_att_count_b.finish()),
|
||||||
Arc::new(tags_b.finish()),
|
Arc::new(tags_b.finish()),
|
||||||
|
|||||||
@@ -1212,7 +1212,7 @@ impl DuckDBManager {
|
|||||||
{
|
{
|
||||||
let sql = format!(
|
let sql = format!(
|
||||||
r#"
|
r#"
|
||||||
SELECT has_attachment, COUNT(*) AS cnt
|
SELECT (regular_attachment_count > 0) AS has_attachment, COUNT(*) AS cnt
|
||||||
FROM envelopes
|
FROM envelopes
|
||||||
{account_filter}
|
{account_filter}
|
||||||
GROUP BY has_attachment
|
GROUP BY has_attachment
|
||||||
@@ -1559,8 +1559,11 @@ impl DuckDBManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(has) = filter.has_attachment {
|
if let Some(has) = filter.has_attachment {
|
||||||
base_sql.push_str(" AND e.has_attachment = ? ");
|
if has {
|
||||||
args.push(has.into());
|
base_sql.push_str(" AND e.regular_attachment_count > 0 ");
|
||||||
|
} else {
|
||||||
|
base_sql.push_str(" AND e.regular_attachment_count = 0 ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(tags) = filter.tags {
|
if let Some(tags) = filter.tags {
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ CREATE TABLE IF NOT EXISTS envelopes (
|
|||||||
message_id TEXT,
|
message_id TEXT,
|
||||||
|
|
||||||
-- attachment summary
|
-- attachment summary
|
||||||
has_attachment BOOLEAN NOT NULL,
|
|
||||||
attachment_count INTEGER NOT NULL CHECK (attachment_count >= 0),
|
attachment_count INTEGER NOT NULL CHECK (attachment_count >= 0),
|
||||||
regular_attachment_count INTEGER NOT NULL CHECK (regular_attachment_count >= 0),
|
regular_attachment_count INTEGER NOT NULL CHECK (regular_attachment_count >= 0),
|
||||||
tags VARCHAR[],
|
tags VARCHAR[],
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ pub async fn reattach_eml_content(
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if !envelope.has_attachments() {
|
if !envelope.has_any_attachments() {
|
||||||
return Ok((envelope, restored_eml));
|
return Ok((envelope, restored_eml));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ pub struct Envelope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Envelope {
|
impl Envelope {
|
||||||
pub fn has_attachments(&self) -> bool {
|
pub fn has_any_attachments(&self) -> bool {
|
||||||
self.attachment_count > 0
|
self.attachment_count > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { HTMLAttributes, useState } from 'react'
|
|||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
import { useForm } from 'react-hook-form'
|
import { useForm } from 'react-hook-form'
|
||||||
import { zodResolver } from '@hookform/resolvers/zod'
|
import { zodResolver } from '@hookform/resolvers/zod'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn, toSearchParams } from '@/lib/utils'
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormControl,
|
FormControl,
|
||||||
@@ -65,7 +65,7 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const { search } = useLocation();
|
const { search } = useLocation();
|
||||||
const redirect = new URLSearchParams(search).get('redirect') || '/';
|
const redirect = toSearchParams(search).get('redirect') || '/';
|
||||||
|
|
||||||
const formSchema = getFormSchema(t)
|
const formSchema = getFormSchema(t)
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
const form = useForm<z.infer<typeof formSchema>>({
|
||||||
|
|||||||
@@ -23,11 +23,12 @@ import { useLocation } from "@tanstack/react-router";
|
|||||||
import { AlertCircle, CheckCircle2, Info } from "lucide-react";
|
import { AlertCircle, CheckCircle2, Info } from "lucide-react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { toSearchParams } from "@/lib/utils";
|
||||||
|
|
||||||
export default function OAuth2Result() {
|
export default function OAuth2Result() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { search } = useLocation();
|
const { search } = useLocation();
|
||||||
const params = new URLSearchParams(search);
|
const params = toSearchParams(search);
|
||||||
const error = params.get("error");
|
const error = params.get("error");
|
||||||
const message = params.get("message");
|
const message = params.get("message");
|
||||||
const success = params.get("success");
|
const success = params.get("success");
|
||||||
|
|||||||
@@ -25,13 +25,10 @@ import {
|
|||||||
ShieldCheck,
|
ShieldCheck,
|
||||||
Server,
|
Server,
|
||||||
Database,
|
Database,
|
||||||
Globe,
|
|
||||||
Lock,
|
|
||||||
Activity,
|
Activity,
|
||||||
InfoIcon,
|
InfoIcon,
|
||||||
Mail,
|
Mail,
|
||||||
Zap,
|
Zap
|
||||||
Cpu
|
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import { get_system_configurations } from "@/api/system/api"
|
import { get_system_configurations } from "@/api/system/api"
|
||||||
import { useQuery } from "@tanstack/react-query"
|
import { useQuery } from "@tanstack/react-query"
|
||||||
|
|||||||
@@ -188,3 +188,14 @@ export function showNumbers(current: number, total: number) {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function toSearchParams(obj: Record<string, any>): URLSearchParams {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
Object.entries(obj).forEach(([key, value]) => {
|
||||||
|
if (value !== undefined && value !== null) {
|
||||||
|
params.append(key, String(value));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return params;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user